!src/leveldb*/Makefile
/doc/doxygen/
+
+libbitcoinconsensus.pc
global:
- MAKEJOBS=-j3
- RUN_TESTS=false
+ - BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID
- CCACHE_SIZE=100M
- CCACHE_TEMPDIR=/tmp/.ccache-temp
- CCACHE_COMPRESS=1
fast_finish: true
include:
- compiler: ": ARM"
- env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
+ env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
- compiler: ": bitcoind"
- env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat CPPFLAGS=-DDEBUG_LOCKORDER"
+ env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER"
- compiler: ": No wallet"
- env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
+ env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
- compiler: ": 32-bit + dash"
- env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" USE_SHELL="/bin/dash"
+ env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash"
- compiler: ": Cross-Mac"
- env: HOST=x86_64-apple-darwin11 PACKAGES="gcc-multilib g++-multilib cmake libcap-dev libz-dev libbz2-dev" OSX_SDK=10.7 GOAL="deploy"
+ env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy"
- compiler: ": Win64"
- env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2"
+ env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2"
- compiler: ": Win32"
- env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2"
+ env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2"
install:
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi
-Copyright (c) 2009-2014 Bitcoin Developers
+Copyright (c) 2009-2015 Bitcoin Developers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
GZIP_ENV="-9n"
+if BUILD_BITCOIN_LIBS
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libbitcoinconsensus.pc
+endif
+
BITCOIND_BIN=$(top_builddir)/src/bitcoind$(EXEEXT)
BITCOIN_QT_BIN=$(top_builddir)/src/qt/bitcoin-qt$(EXEEXT)
BITCOIN_CLI_BIN=$(top_builddir)/src/bitcoin-cli$(EXEEXT)
OSX_APP=Bitcoin-Qt.app
OSX_DMG=Bitcoin-Qt.dmg
+OSX_BACKGROUND_IMAGE=background.tiff
OSX_DEPLOY_SCRIPT=$(top_srcdir)/contrib/macdeploy/macdeployqtplus
OSX_FANCY_PLIST=$(top_srcdir)/contrib/macdeploy/fancy.plist
OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/bitcoin.icns
$(top_srcdir)/doc/README_windows.txt
OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) \
- $(top_srcdir)/contrib/macdeploy/background.png \
- $(top_srcdir)/contrib/macdeploy/DS_Store
+ $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_IMAGE) \
+ $(top_srcdir)/contrib/macdeploy/DS_Store \
+ $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \
+ $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh
COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \
leveldb_baseline.info test_bitcoin_filtered.info total_coverage.info \
$(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING)
$(OSX_DEPLOY_SCRIPT) $(OSX_APP) -add-qt-tr $(OSX_QT_TRANSLATIONS) -translations-dir=$(QT_TRANSLATION_DIR) -dmg -fancy $(OSX_FANCY_PLIST) -verbose 2
+deploydir: $(OSX_DMG)
else
-$(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING)
- INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -add-qt-tr $(OSX_QT_TRANSLATIONS) -translations-dir=$(QT_TRANSLATION_DIR) -verbose 2
- $(MKDIR_P) dist/.background
- $(INSTALL) contrib/macdeploy/background.png dist/.background
- $(INSTALL) contrib/macdeploy/DS_Store dist/.DS_Store
- cd dist; $(LN_S) /Applications Applications
- $(GENISOIMAGE) -no-cache-inodes -l -probe -V "Bitcoin-Qt" -no-pad -r -apple -o $@ dist
+APP_DIST_DIR=$(top_builddir)/dist
+APP_DIST_EXTRAS=$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE) $(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications
+
+$(APP_DIST_DIR)/Applications:
+ @rm -f $@
+ @cd $(@D); $(LN_S) /Applications $(@F)
+
+$(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt
+
+$(OSX_DMG): $(APP_DIST_EXTRAS)
+ $(GENISOIMAGE) -no-cache-inodes -D -l -probe -V "Bitcoin-Qt" -no-pad -r -apple -o $@ dist
+
+$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): contrib/macdeploy/$(OSX_BACKGROUND_IMAGE)
+ $(MKDIR_P) $(@D)
+ $(INSTALL) $< $@
+$(APP_DIST_DIR)/.DS_Store: contrib/macdeploy/DS_Store
+ $(INSTALL) $< $@
+
+$(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING)
+ INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -translations-dir=$(QT_TRANSLATION_DIR) -add-qt-tr $(OSX_QT_TRANSLATIONS) -verbose 2
+
+deploydir: $(APP_DIST_EXTRAS)
endif
if TARGET_DARWIN
https://www.bitcoin.org
-Copyright (c) 2009-2014 Bitcoin Core Developers
-
What is Bitcoin?
----------------
The patch will be accepted if there is broad consensus that it is a good thing.
Developers should expect to rework and resubmit patches if the code doesn't
-match the project's coding conventions (see [doc/coding.md](doc/coding.md)) or are
+match the project's coding conventions (see [doc/developer-notes.md](doc/developer-notes.md)) or are
controversial.
The `master` branch is regularly built and tested, but is not guaranteed to be
pull from Transifex would automatically overwrite them again.
Translators should also subscribe to the [mailing list](https://groups.google.com/forum/#!forum/bitcoin-translators).
-
-Development tips and tricks
----------------------------
-
-**compiling for debugging**
-
-Run configure with the --enable-debug option, then make. Or run configure with
-CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need.
-
-**debug.log**
-
-If the code is behaving strangely, take a look in the debug.log file in the data directory;
-error and debugging messages are written there.
-
-The -debug=... command-line option controls debugging; running with just -debug will turn
-on all categories (and give you a very large debug.log file).
-
-The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt
-to see it.
-
-**testnet and regtest modes**
-
-Run with the -testnet option to run with "play bitcoins" on the test network, if you
-are testing multi-machine code that needs to operate across the internet.
-
-If you are testing something that can run on one machine, run with the -regtest option.
-In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests
-that run in -regtest mode.
-
-**DEBUG_LOCKORDER**
-
-Bitcoin Core is a multithreaded application, and deadlocks or other multithreading bugs
-can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure
-CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of which locks
-are held, and adds warnings to the debug.log file if inconsistencies are detected.
done
if test "x$bdbpath" = "xX"; then
AC_MSG_RESULT([no])
- AC_MSG_ERROR(libdb_cxx headers missing)
+ AC_MSG_ERROR([libdb_cxx headers missing, Bitcoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)])
elif test "x$bdb48path" = "xX"; then
BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdbpath}],db_cxx)
AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 4.8])],[
dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 0)
-define(_CLIENT_VERSION_MINOR, 9)
+define(_CLIENT_VERSION_MINOR, 10)
define(_CLIENT_VERSION_REVISION, 99)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_IS_RELEASE, false)
-define(_COPYRIGHT_YEAR, 2014)
+define(_COPYRIGHT_YEAR, 2015)
AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[
[email protected]],[bitcoin])
AC_CONFIG_SRCDIR([src/main.cpp])
AC_CONFIG_HEADERS([src/config/bitcoin-config.h])
AC_PATH_PROG(XGETTEXT,xgettext)
AC_PATH_PROG(HEXDUMP,hexdump)
-# This m4 will only be used if a system copy cannot be found. This is helpful
-# on systems where autotools are installed but the pkg-config macros are not in
-# a default location. It is currently used for building on OSX where autotools
-# are preinstalled but pkg-config comes from macports or homebrew. It should
-# probably be removed when building on <= 10.6 is no longer supported.
-m4_include([pkg.m4])
-
dnl pkg-config check.
PKG_PROG_PKG_CONFIG
AC_ARG_ENABLE([reduce-exports],
[AS_HELP_STRING([--enable-reduce-exports],
- [attempt to reduce exported symbols in the resulting executables (default is yes)])],
+ [attempt to reduce exported symbols in the resulting executables (default is no)])],
[use_reduce_exports=$enableval],
- [use_reduce_exports=auto])
+ [use_reduce_exports=no])
AC_ARG_ENABLE([ccache],
[AS_HELP_STRING([--enable-ccache],
AC_ARG_ENABLE([glibc-back-compat],
[AS_HELP_STRING([--enable-glibc-back-compat],
- [enable backwards compatibility with glibc and libstdc++])],
+ [enable backwards compatibility with glibc])],
[use_glibc_compat=$enableval],
[use_glibc_compat=no])
fi
CPPFLAGS="$CPPFLAGS -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS"
+AC_ARG_WITH([utils],
+ [AS_HELP_STRING([--with-utils],
+ [build bitcoin-cli bitcoin-tx (default=yes)])],
+ [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)])],
+ [build_bitcoind=$withval],
+ [build_bitcoind=yes])
+
AC_LANG_PUSH([C++])
use_pkgconfig=yes
AC_CHECK_PROG([PORT],port, port)
if test x$PORT = xport; then
dnl add default macports paths
- CPPFLAGS="$CPPFLAGS -isystem /opt/local/include -I/opt/local/include/db48"
- LIBS="$LIBS -L/opt/local/lib -L/opt/local/lib/db48"
+ CPPFLAGS="$CPPFLAGS -isystem /opt/local/include"
+ LIBS="$LIBS -L/opt/local/lib"
+ if test -d /opt/local/include/db48; then
+ CPPFLAGS="$CPPFLAGS -I/opt/local/include/db48"
+ LIBS="$LIBS -L/opt/local/lib/db48"
+ fi
fi
AC_CHECK_PROG([BREW],brew, brew)
AC_PATH_TOOL([INSTALLNAMETOOL], [install_name_tool], install_name_tool)
AC_PATH_TOOL([OTOOL], [otool], otool)
AC_PATH_PROGS([GENISOIMAGE], [genisoimage mkisofs],genisoimage)
+
+ dnl libtool will try to strip the static lib, which is a problem for
+ dnl cross-builds because strip attempts to call a hard-coded ld,
+ dnl which may not exist in the path. Stripping the .a is not
+ dnl necessary, so just disable it.
+ old_striplib=
;;
esac
fi
[AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")])
fi
-dnl Require little endian
-AC_C_BIGENDIAN([AC_MSG_ERROR("Big Endian not supported")])
+dnl Check for endianness
+AC_C_BIGENDIAN
dnl Check for pthread compile/link requirements
AX_PTHREAD
AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"])
fi
-AC_CHECK_HEADERS([endian.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
+AC_CHECK_HEADERS([endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])])
AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])])
-AC_CHECK_DECLS([le32toh, le64toh, htole32, htole64, be32toh, be64toh, htobe32, htobe64],,,
+AC_CHECK_DECLS([strnlen])
+
+AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,,
[#if HAVE_ENDIAN_H
#include <endian.h>
#endif])
+AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,,
+ [#if HAVE_BYTESWAP_H
+ #include <byteswap.h>
+ #endif])
+
dnl Check for MSG_NOSIGNAL
AC_MSG_CHECKING(for MSG_NOSIGNAL)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]],
[
AC_MSG_RESULT(no)
if test x$use_reduce_exports = xyes; then
- AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduced-exports.])
+ AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduce-exports.])
fi
- AC_MSG_WARN([Cannot find a working visibility attribute. Disabling reduced exports.])
- use_reduce_exports=no
]
)
-if test x$use_reduce_exports != xno; then
+if test x$use_reduce_exports = xyes; then
AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"],
- [
- if test x$use_reduce_exports = xyes; then
- AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduced-exports.])
- fi
- AC_MSG_WARN([Cannot set default symbol visibility. Disabling reduced exports.])
- use_reduce_exports=no
- ])
+ [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])])
fi
LEVELDB_CPPFLAGS=
)
fi
+BITCOIN_QT_INIT
+
+dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus
+BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4])
+
+if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then
+ use_boost=no
+else
+ use_boost=yes
+fi
+
+if test x$use_boost = xyes; then
+
dnl Check for boost libs
AX_BOOST_BASE
AX_BOOST_SYSTEM
AX_BOOST_CHRONO
-if test x$use_reduce_exports != xno; then
+if test x$use_reduce_exports = xyes; then
AC_MSG_CHECKING([for working boost reduced exports])
TEMP_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS"
#endif
]])],[
AC_MSG_RESULT(yes)
- ],[:
- if test x$use_reduce_exports = xauto; then
- use_reduce_exports=no
- else
- if test x$use_reduce_exports = xyes; then
- AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduced-exports.])
- fi
- fi
- AC_MSG_RESULT(no)
- AC_MSG_WARN([boost versions < 1.49 are known to have symbol visibility issues. Disabling reduced exports.])
+ ],[
+ AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduce-exports.])
])
CPPFLAGS="$TEMP_CPPFLAGS"
fi
+fi
-if test x$use_reduce_exports != xno; then
+if test x$use_reduce_exports = xyes; then
CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS"
AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"])
fi
fi
+ if test x$use_boost = xyes; then
+
AX_BOOST_UNIT_TEST_FRAMEWORK
dnl Determine if -DBOOST_TEST_DYN_LINK is needed
[AC_MSG_RESULT(no)])
LIBS="$TEMP_LIBS"
CPPFLAGS="$TEMP_CPPFLAGS"
+
+ fi
fi
+if test x$use_boost = xyes; then
+
BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB"
dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however
AC_MSG_ERROR(No working boost sleep implementation found.)
fi
-AC_ARG_WITH([utils],
- [AS_HELP_STRING([--with-utils],
- [build bitcoin-cli bitcoin-tx (default=yes)])],
- [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)])],
- [build_bitcoind=$withval],
- [build_bitcoind=yes])
-
-BITCOIN_QT_INIT
+fi
if test x$use_pkgconfig = xyes; then
fi
fi
+CFLAGS_TEMP="$CFLAGS"
+LIBS_TEMP="$LIBS"
+CFLAGS="$CFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS"
+LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS"
+AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),)
+CFLAGS="$CFLAGS_TEMP"
+LIBS="$LIBS_TEMP"
+
BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path)
AC_MSG_CHECKING([whether to build bitcoind])
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])
+ AC_CONFIG_FILES([libbitcoinconsensus.pc:libbitcoinconsensus.pc.in])
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])
-
AC_LANG_POP
if test "x$use_ccache" != "xno"; then
fi
AC_MSG_CHECKING([whether to reduce exports])
-if test x$use_reduce_exports != xno; then
+if test x$use_reduce_exports = xyes; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
-if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then
+if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_tests = xnonononono; 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([USE_COMPARISON_TOOL],[test x$use_comparison_tool != xno])
AM_CONDITIONAL([USE_COMPARISON_TOOL_REORG_TESTS],[test x$use_comparison_tool_reorg_test != xno])
AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes])
-AM_CONDITIONAL([USE_LIBSECP256K1],[test x$use_libsecp256k1 = xyes])
AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version])
AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version])
# bash programmable completion for bitcoind(1) and bitcoin-cli(1)
-# 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.
have bitcoind && {
debian/manpages/bitcoind.1
debian/manpages/bitcoin.conf.5
+debian/manpages/bitcoin-cli.1
+bitcoin (0.10.0-precise1) precise; urgency=medium
+
+ * New upstream releases.
+
+
+bitcoin (0.9.4-precise1) precise; urgency=high
+
+ * New upstream releases.
+
+ -- Matt Corallo (laptop - only while traveling) <
[email protected]> Mon, 12 Jan 2015 23:30:00 -1000
+
bitcoin (0.9.3-precise1) precise; urgency=medium
* New upstream releases.
libdb4.8++-dev,
libssl-dev,
pkg-config,
- libminiupnpc8-dev,
+ libminiupnpc8-dev | libminiupnpc-dev (>> 1.6),
libboost-filesystem-dev (>> 1.35) | libboost-filesystem1.35-dev,
libboost-program-options-dev (>> 1.35) | libboost-program-options1.35-dev,
libboost-thread-dev (>> 1.35) | libboost-thread1.35-dev,
--- /dev/null
+.TH BITCOIN-CLI "1" "February 2015" "bitcoin-cli 0.10"
+.SH NAME
+bitcoin-cli \- a remote procedure call client for Bitcoin Core.
+.SH SYNOPSIS
+bitcoin-cli [options] <command> [params] \- Send command to Bitcoin Core.
+.TP
+bitcoin-cli [options] help \- Asks Bitcoin Core for a list of supported commands.
+.SH DESCRIPTION
+This manual page documents the bitcoin-cli program. bitcoin-cli is an RPC client used to send commands to Bitcoin Core.
+
+.SH OPTIONS
+.TP
+\fB\-?\fR
+Show the help message.
+.TP
+\fB\-conf=\fR<file>
+Specify configuration file (default: bitcoin.conf).
+.TP
+\fB\-datadir=\fR<dir>
+Specify data directory.
+.TP
+\fB\-testnet\fR
+Connect to a Bitcoin Core instance running in testnet mode.
+.TP
+\fB\-regtest\fR
+Connect to a Bitcoin Core instance running in regtest mode (see documentation for -regtest on bitcoind).
+.TP
+\fB\-rpcuser=\fR<user>
+Username for JSON\-RPC connections.
+.TP
+\fB\-rpcpassword=\fR<pw>
+Password for JSON\-RPC connections.
+.TP
+\fB\-rpcport=\fR<port>
+Listen for JSON\-RPC connections on <port> (default: 8332 or testnet: 18332).
+.TP
+\fB\-rpcconnect=\fR<ip>
+Send commands to node running on <ip> (default: 127.0.0.1).
+.TP
+\fB\-rpcssl\fR=\fI1\fR
+Use OpenSSL (https) for JSON\-RPC connections (see the Bitcoin Wiki for SSL setup instructions).
+
+.SH "SEE ALSO"
+\fBbitcoind\fP, \fBbitcoin.conf\fP
+.SH AUTHOR
+This manual page was written by Ciemon Dunville <
[email protected]>. Permission is granted to copy, distribute and/or modify this document under the terms of the MIT License.
+
+The complete text of the MIT License can be found on the web at \fIhttp://opensource.org/licenses/MIT\fP.
Safely copies *wallet.dat* to 'destination', which can be a directory or a path with filename.
.TP
\fBgetaccount 'bitcoinaddress'\fR
-Returns the account associated with the given address.
+DEPRECATED. Returns the account associated with the given address.
.TP
\fBsetaccount 'bitcoinaddress' ['account']\fR
-Sets the ['account'] associated with the given address. ['account'] may be omitted to remove an address from ['account'].
+DEPRECATED. Sets the ['account'] associated with the given address. ['account'] may be omitted to remove an address from ['account'].
.TP
\fBgetaccountaddress 'account'\fR
-Returns a new bitcoin address for 'account'.
+DEPRECATED. Returns a new bitcoin address for 'account'.
.TP
\fBgetaddressesbyaccount 'account'\fR
-Returns the list of addresses associated with the given 'account'.
+DEPRECATED. Returns the list of addresses associated with the given 'account'.
.TP
\fBgetbalance 'account'\fR
-Returns the server's available balance, or the balance for 'account'.
+Returns the server's available balance, or the balance for 'account' (accounts are deprecated).
.TP
\fBgetblockcount\fR
Returns the number of blocks in the longest block chain.
Returns an object containing server information.
.TP
\fBgetnewaddress 'account'\fR
-Returns a new bitcoin address for receiving payments. If 'account' is specified (recommended), it is added to the address book so payments received with the address will be credited to 'account'.
+Returns a new bitcoin address for receiving payments. If 'account' is specified (deprecated), it is added to the address book so payments received with the address will be credited to 'account'.
.TP
\fBgetreceivedbyaccount 'account' ['minconf=1']\fR
-Returns the total amount received by addresses associated with 'account' in transactions with at least ['minconf'] confirmations.
+DEPRECATED. Returns the total amount received by addresses associated with 'account' in transactions with at least ['minconf'] confirmations.
.TP
\fBgetreceivedbyaddress 'bitcoinaddress' ['minconf=1']\fR
Returns the total amount received by 'bitcoinaddress' in transactions with at least ['minconf'] confirmations.
List commands, or get help for a command.
.TP
\fBlistaccounts ['minconf=1']\fR
-List accounts and their current balances.
+DEPRECATED. List accounts and their current balances.
*note: requires bitcoin 0.3.20 or later.
.TP
\fBlistreceivedbyaccount ['minconf=1'] ['includeempty=false']\fR
['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing:
- "account" : the account of the receiving address.
+ "account" : DEPRECATED. the account of the receiving address.
"amount" : total amount received by the address.
"confirmations" : number of confirmations of the most recent transaction included.
.TP
['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing:
"address" : receiving address.
- "account" : the account of the receiving address.
+ "account" : DEPRECATED. the account of the receiving address.
"amount" : total amount received by the address.
"confirmations" : number of confirmations of the most recent transaction included.
.TP
*note: requires bitcoin 0.3.20 or later.
.TP
\fBmove <'fromaccount'> <'toaccount'> <'amount'> ['minconf=1'] ['comment']\fR
-Moves funds between accounts.
+DEPRECATED. Moves funds between accounts.
.TP
\fBsendfrom* <'account'> <'bitcoinaddress'> <'amount'> ['minconf=1'] ['comment'] ['comment-to']\fR
-Sends amount from account's balance to 'bitcoinaddress'. This method will fail if there is less than amount bitcoins with ['minconf'] confirmations in the account's balance (unless account is the empty-string-named default account; it behaves like the *sendtoaddress* method). Returns transaction ID on success.
+DEPRECATED. Sends amount from account's balance to 'bitcoinaddress'. This method will fail if there is less than amount bitcoins with ['minconf'] confirmations in the account's balance (unless account is the empty-string-named default account; it behaves like the *sendtoaddress* method). Returns transaction ID on success.
.TP
\fBsendtoaddress 'bitcoinaddress' 'amount' ['comment'] ['comment-to']\fR
Sends amount from the server's available balance to 'bitcoinaddress'. amount is a real and is rounded to the nearest 0.01. Returns transaction id on success.
.cpp and .h files if these have a git commit from the current year.
For example a file changed in 2014 (with 2014 being the current year):
-```// Copyright (c) 2009-2013 The Bitcoin developers```
+```// Copyright (c) 2009-2013 The Bitcoin Core developers```
would be changed to:
-```// Copyright (c) 2009-2014 The Bitcoin developers```
+```// Copyright (c) 2009-2014 The Bitcoin Core developers```
symbol-check.py
==================
For example: if it finds something like this and we're in 2014
-// Copyright (c) 2009-2013 The Bitcoin developers
+// Copyright (c) 2009-2013 The Bitcoin Core developers
it will change it to
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
It will do this for all the files in the folder and its children.
echo "Dropping you on a shell so you can try building/testing the merged source." >&2
echo "Run 'git diff HEAD~' to show the changes being merged." >&2
echo "Type 'exit' when done." >&2
+ if [[ -f /etc/debian_version ]]; then # Show pull number in prompt on Debian default prompt
+ export debian_chroot="$PULL"
+ fi
bash -i
read -p "Press 'm' to accept the merge. " -n 1 -r >&2
echo
echo
if [[ "d$REPLY" =~ ^d[Ss]$ ]]; then
if [[ "$(git config --get user.signingkey)" == "" ]]; then
- echo "WARNING: No GPG signing key set, not signing. Set one using:" >&2
+ echo "ERROR: No GPG signing key set, not signing. Set one using:" >&2
echo "git config --global user.signingkey <key>" >&2
- git commit -q --signoff --amend --no-edit
+ cleanup
+ exit 1
else
git commit -q --gpg-sign --amend --no-edit
fi
+else
+ echo "Not signing off on merge, exiting."
+ cleanup
+ exit 1
fi
# Clean up temporary branches, and put the result in $BRANCH.
--- /dev/null
+#!/usr/bin/env python
+
+import os
+import sys
+import subprocess
+import hashlib
+from PIL import Image
+
+def file_hash(filename):
+ '''Return hash of raw file contents'''
+ with open(filename, 'rb') as f:
+ return hashlib.sha256(f.read()).hexdigest()
+
+def content_hash(filename):
+ '''Return hash of RGBA contents of image'''
+ i = Image.open(filename)
+ i = i.convert('RGBA')
+ data = i.tostring()
+ return hashlib.sha256(data).hexdigest()
+
+#optimize png, remove various color profiles, remove ancillary chunks (alla) and text chunks (text)
+#pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text
+
+pngcrush = 'pngcrush'
+git = 'git'
+folders = ["src/qt/res/movies", "src/qt/res/icons", "src/qt/res/images"]
+basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel']).rstrip('\n')
+totalSaveBytes = 0
+
+outputArray = []
+for folder in folders:
+ absFolder=os.path.join(basePath, folder)
+ for file in os.listdir(absFolder):
+ extension = os.path.splitext(file)[1]
+ if extension.lower() == '.png':
+ print("optimizing "+file+"..."),
+ file_path = os.path.join(absFolder, file)
+ fileMetaMap = {'file' : file, 'osize': os.path.getsize(file_path), 'sha256Old' : file_hash(file_path)};
+ fileMetaMap['contentHashPre'] = content_hash(file_path)
+
+ pngCrushOutput = ""
+ try:
+ pngCrushOutput = subprocess.check_output(
+ [pngcrush, "-brute", "-ow", "-rem", "gAMA", "-rem", "cHRM", "-rem", "iCCP", "-rem", "sRGB", "-rem", "alla", "-rem", "text", file_path],
+ stderr=subprocess.STDOUT).rstrip('\n')
+ except:
+ print "pngcrush is not installed, aborting..."
+ sys.exit(0)
+
+ #verify
+ if "Not a PNG file" in subprocess.check_output([pngcrush, "-n", "-v", file_path], stderr=subprocess.STDOUT):
+ print "PNG file "+file+" is corrupted after crushing, check out pngcursh version"
+ sys.exit(1)
+
+ fileMetaMap['sha256New'] = file_hash(file_path)
+ fileMetaMap['contentHashPost'] = content_hash(file_path)
+
+ if fileMetaMap['contentHashPre'] != fileMetaMap['contentHashPost']:
+ print "Image contents of PNG file "+file+" before and after crushing don't match"
+ sys.exit(1)
+
+ fileMetaMap['psize'] = os.path.getsize(file_path)
+ outputArray.append(fileMetaMap)
+ print("done\n"),
+
+print "summary:\n+++++++++++++++++"
+for fileDict in outputArray:
+ oldHash = fileDict['sha256Old']
+ newHash = fileDict['sha256New']
+ totalSaveBytes += fileDict['osize'] - fileDict['psize']
+ print fileDict['file']+"\n size diff from: "+str(fileDict['osize'])+" to: "+str(fileDict['psize'])+"\n old sha256: "+oldHash+"\n new sha256: "+newHash+"\n"
+
+print "completed. Total reduction: "+str(totalSaveBytes)+" bytes"
#!/usr/bin/python
# Copyright (c) 2014 Wladimir J. van der Laan
-# 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.
'''
A script to check that the (Linux) executables produced by gitian only contain
#!/usr/bin/python
# Copyright (c) 2014 Wladimir J. van der Laan
-# 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.
'''
Run this script from the root of the repository to update all translations from
- "faketime"
- "bsdmainutils"
- "binutils-gold"
+- "libstdc++6-4.6-pic"
reference_datetime: "2013-06-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu"
- CONFIGFLAGS="--enable-upnp-default --enable-glibc-back-compat"
+ CONFIGFLAGS="--enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++"
FAKETIME_HOST_PROGS=""
FAKETIME_PROGS="date ar ranlib nm strip"
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
done
+ # Ubuntu precise hack: Not an issue in later versions.
+ # Precise's libstdc++.a is non-pic. There's an optional libstdc++6-4.6-pic
+ # package which provides libstdc++_pic.a, but the linker can't find it.
+ # Symlink it to a path that will be included in our link-line so that the
+ # linker picks it up before the default libstdc++.a.
+ # This is only necessary for 64bit.
+ ln -s /usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++_pic.a ${BASEPREFIX}/x86_64-unknown-linux-gnu/lib/libstdc++.a
+
# Create the release tarball using (arbitrarily) the first host
./autogen.sh
./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
make dist
- DISTNAME=`echo bitcoin-*.tar.gz`
-
+ SOURCEDIST=`echo bitcoin-*.tar.gz`
+ DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'`
# Correct tar file order
mkdir -p temp
pushd temp
- tar xf ../$DISTNAME
- find bitcoin-* | sort | tar --no-recursion -c -T - | gzip -9n > ../$DISTNAME
+ tar xf ../$SOURCEDIST
+ find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST
popd
ORIGPATH="$PATH"
export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH}
mkdir -p distsrc-${i}
cd distsrc-${i}
- tar --strip-components=1 -xf ../$DISTNAME
+ INSTALLPATH=`pwd`/installed/${DISTNAME}
+ mkdir -p ${INSTALLPATH}
+ tar --strip-components=1 -xf ../$SOURCEDIST
- ./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}
+ ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
make ${MAKEOPTS}
make install-strip
- cd ..
+ cd installed
+ find . -name "lib*.la" -delete
+ find . -name "lib*.a" -delete
+ rm -rf ${DISTNAME}/lib/pkgconfig
+ find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
+ cd ../../
done
mkdir -p $OUTDIR/src
- mv $DISTNAME $OUTDIR/src
- mv ${OUTDIR}/x86_64-* ${OUTDIR}/64
- mv ${OUTDIR}/i686-* ${OUTDIR}/32
+ mv $SOURCEDIST $OUTDIR/src
+ mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-linux64.tar.gz
+ mv ${OUTDIR}/${DISTNAME}-i686-*.tar.gz ${OUTDIR}/${DISTNAME}-linux32.tar.gz
- # Delete unwanted stuff
- find ${OUTDIR} -name "lib*.la" -delete
--- /dev/null
+---
+name: "bitcoin-dmg-signer"
+suites:
+- "precise"
+architectures:
+- "amd64"
+packages:
+- "libc6:i386"
+- "faketime"
+reference_datetime: "2013-06-01 00:00:00"
+remotes: []
+files:
+- "bitcoin-osx-unsigned.tar.gz"
+- "signature.tar.gz"
+script: |
+ WRAP_DIR=$HOME/wrapped
+ mkdir -p ${WRAP_DIR}
+ export PATH=`pwd`:$PATH
+ FAKETIME_PROGS="dmg genisoimage"
+
+ # 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
+
+ UNSIGNED=bitcoin-osx-unsigned.tar.gz
+ SIGNED=bitcoin-osx-signed.dmg
+
+ tar -xf ${UNSIGNED}
+ ./detached-sig-apply.sh ${UNSIGNED} signature.tar.gz
+ ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "Bitcoin-Qt" -no-pad -r -apple -o uncompressed.dmg signed-app
+ ${WRAP_DIR}/dmg dmg uncompressed.dmg ${OUTDIR}/${SIGNED}
architectures:
- "amd64"
packages:
-- "g++-multilib"
+- "g++"
- "git-core"
- "pkg-config"
- "autoconf2.13"
- "url": "https://github.com/bitcoin/bitcoin.git"
"dir": "bitcoin"
files:
-- "MacOSX10.7.sdk.tar.gz"
+- "MacOSX10.9.sdk.tar.gz"
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="x86_64-apple-darwin11"
- CONFIGFLAGS="--enable-upnp-default GENISOIMAGE=$WRAP_DIR/genisoimage"
+ CONFIGFLAGS="--enable-upnp-default --enable-reduce-exports GENISOIMAGE=$WRAP_DIR/genisoimage"
FAKETIME_HOST_PROGS=""
FAKETIME_PROGS="ar ranlib date dmg genisoimage"
BASEPREFIX=`pwd`/depends
mkdir -p ${BASEPREFIX}/SDKs
- tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.7.sdk.tar.gz
+ tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.9.sdk.tar.gz
# Build dependencies for each host
for i in $HOSTS; do
./autogen.sh
./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
make dist
- DISTNAME=`echo bitcoin-*.tar.gz`
+ SOURCEDIST=`echo bitcoin-*.tar.gz`
+ DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'`
# Correct tar file order
mkdir -p temp
pushd temp
- tar xf ../$DISTNAME
- find bitcoin-* | sort | tar --no-recursion -c -T - | gzip -9n > ../$DISTNAME
+ tar xf ../$SOURCEDIST
+ find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST
popd
ORIGPATH="$PATH"
export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH}
mkdir -p distsrc-${i}
cd distsrc-${i}
- tar --strip-components=1 -xf ../$DISTNAME
+ INSTALLPATH=`pwd`/installed/${DISTNAME}
+ mkdir -p ${INSTALLPATH}
+ tar --strip-components=1 -xf ../$SOURCEDIST
- ./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}
+ ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
make ${MAKEOPTS}
make install-strip
+
+ make deploydir
+ mkdir -p unsigned-app-${i}
+ cp contrib/macdeploy/detached-sig-apply.sh unsigned-app-${i}
+ cp contrib/macdeploy/detached-sig-create.sh unsigned-app-${i}
+ cp ${BASEPREFIX}/${i}/native/bin/dmg ${BASEPREFIX}/${i}/native/bin/genisoimage unsigned-app-${i}
+ cp ${BASEPREFIX}/${i}/native/bin/${i}-codesign_allocate unsigned-app-${i}/codesign_allocate
+ cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff
+ mv dist unsigned-app-${i}
+ pushd unsigned-app-${i}
+ find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz
+ popd
+
make deploy
- ${WRAP_DIR}/dmg dmg Bitcoin-Qt.dmg ${OUTDIR}/Bitcoin-Qt.dmg
- cd ..
+ ${WRAP_DIR}/dmg dmg Bitcoin-Qt.dmg ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg
+
+ cd installed
+ find . -name "lib*.la" -delete
+ find . -name "lib*.a" -delete
+ rm -rf ${DISTNAME}/lib/pkgconfig
+ find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
+ cd ../../
done
mkdir -p $OUTDIR/src
- mv $DISTNAME $OUTDIR/src
-
- # Delete unwanted stuff
- find ${OUTDIR} -name "lib*.la" -delete
+ mv $SOURCEDIST $OUTDIR/src
+ mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-osx64.tar.gz
- "mingw-w64"
- "g++-mingw-w64"
- "nsis"
+- "zip"
reference_datetime: "2013-06-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="x86_64-w64-mingw32 i686-w64-mingw32"
- CONFIGFLAGS="--enable-upnp-default"
+ CONFIGFLAGS="--enable-upnp-default --enable-reduce-exports"
FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip"
- FAKETIME_PROGS="date makensis"
+ FAKETIME_PROGS="date makensis zip"
export QT_RCC_TEST=1
export GZIP="-9n"
./autogen.sh
./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
make dist
- DISTNAME=`echo bitcoin-*.tar.gz`
+ SOURCEDIST=`echo bitcoin-*.tar.gz`
+ DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'`
# Correct tar file order
mkdir -p temp
pushd temp
- tar xf ../$DISTNAME
- find bitcoin-* | sort | tar --no-recursion -c -T - | gzip -9n > ../$DISTNAME
+ tar xf ../$SOURCEDIST
+ find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST
popd
ORIGPATH="$PATH"
export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH}
mkdir -p distsrc-${i}
cd distsrc-${i}
- tar --strip-components=1 -xf ../$DISTNAME
+ INSTALLPATH=`pwd`/installed/${DISTNAME}
+ mkdir -p ${INSTALLPATH}
+ tar --strip-components=1 -xf ../$SOURCEDIST
- ./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}
+ ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
make ${MAKEOPTS}
make deploy
make install-strip
cp -f bitcoin-*setup*.exe $OUTDIR/
- cd ..
+ cd installed
+ mv ${DISTNAME}/bin/*.dll ${DISTNAME}/lib/
+ find . -name "lib*.la" -delete
+ find . -name "lib*.a" -delete
+ rm -rf ${DISTNAME}/lib/pkgconfig
+ find ${DISTNAME} -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip
+ cd ../..
done
mkdir -p $OUTDIR/src
- mv $DISTNAME $OUTDIR/src
- mv ${OUTDIR}/x86_64-* ${OUTDIR}/64
- mv ${OUTDIR}/i686-* ${OUTDIR}/32
-
- # Delete unwanted stuff
- find ${OUTDIR} -name "lib*.la" -delete
+ mv $SOURCEDIST $OUTDIR/src
+ mv ${OUTDIR}/${DISTNAME}-x86_64-*.zip ${OUTDIR}/${DISTNAME}-win64.zip
+ mv ${OUTDIR}/${DISTNAME}-i686-*.zip ${OUTDIR}/${DISTNAME}-win32.zip
--- /dev/null
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG/MacGPG2 v2.0.26
+
+mQINBFFlV7oBEAC3dRAS7gSWQ1fV4JySD0HMBOtY+Y2oCX8vEuTI4atGcxbwXr4/
+OElRYhDK6Zirk8rMoKPxmr8OVek5LNnY3gcDffco6NXmZ+wTstQm6oqUxFfgzznG
+X/ExEVuCqiaPAwdWSKn9tC1GuOqRFcD+p2zmxw5mNH5XdsqaPSEGsKESY1IK+dMv
+K+YUrfrtexZyb66wCtupYziEeag6iEK/i2x2wewOji6IvtI+wB5FO+YMXw+LKucw
+PoHUOxjoz6YX3s04UxFaZo4R8x6J9XnJBSB2E5kfsSAzz3xR+zuapXY6H6mo/grq
+nr3c6ACcbAHnMWwQLYvWzde6iwswhyl0whebsajJH7Rd3G4c1U3L/oj4RwUFmZYU
+5Prs+Q5PepKAJfBeWCXZtUY2BNFCFj7b2H2NXYFR92Oc2GtoHAYACNeP070I9d3m
+IeuYhOrOckkunwaijUczq4rb3n3Vaq6YrdwZIzs8fALwc9Th98jj2dCUq0fljpSh
+UQFnPG83UsNkeWzUSgw+lBeEQqgOqUQQ293MbgRg0mJ8q677Iv+WaFqPKZzXxkwT
+QCCXhjcBmUKgXIHLFcbfmkR8pCcCToWXBD8CU441cBsootDD7SanPHbpcwZjt74x
+uLrVoCIyaju0T1jSrsPnm2A/8VkWLSCh1WRAlbjvMr7DwizGnRtzTiB6HQARAQAB
+tC9NaWNoYWVsIEZvcmQgKGJpdGNvaW4tb3RjKSA8ZmFucXVha2VAZ21haWwuY29t
+PokCNwQTAQoAIQUCUWVXugIbLwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRCU
+TTX5rD23agJgEAC0ouDjufjCMHL4DkaVkOnFbHzP+nR2Mq7pcjdiPNIt9tj8B6cI
+PRh/E+tt2iEJJ4lzlfj0uEqjqexmSBaMgY+pFb6ESg42EPQjRQ95oBoyZfp+uL/0
+KC3+Hh+EgmZGIFPZy2HneVfusiBUz2/YTOoqFkzmHalJe9Yvl2+dO0SUC7i6TUdJ
++ugSr/91hkjQC52LXgHzurH4zOz7ZjzRtZgUIG3oOx8mtEDf46eJ0IUsr+tWJqOp
+ce5xFh6nkKfS92B7YjGJ4YrkBHC7F9vmbrtIeuWiaxGzVqhHFmLvQe+4xyOpRgHM
+kcyD5uJNmSMO9gT3udut4hd0yUKg5rdqaUzqsvv19eNL/pZ7aBK2aDAK/yAi1T7X
+/nrhBJAU49zg1JRS6atRnhKSyd7wRSwVPJAXfVuelHsUgenSdLmSBxRha+9mL6Lb
+bLK/Dij/0r2fyhBJx4pV6V1n4BpHjv5ivkpgCvOupx8wx3PIxZq/rx+hK+ZBe2EQ
+7vq8rmLfBkSavHWyNxXEKWQed+mFS3d+Qsoy90bi7gQygIYNZOIBYwsy+qjCZ3om
+LwkzRjypH23ps7WmiaoenOaCjRYooNL4qtQwNVaDGYwvbMnXJ8Vb4/2j/Riz7+Ui
+BBVww+Wd72Fml/OFPDFep6HG/PuwFB9m5hmfSzrA01TIdjcWljtTDneufbkCDQRR
+ZVe6ARAAvi1IAxn9xKQCCqhsoKOiXNbpnmf6lYnoEwGtgI+0a0YQwtzm39P5T8P0
+esZ65/Re6jCCHLc23/urFPfW9VfrKPmNJncyzlx7OopJ7G1MWdRLEUzwqSaglC6x
+Zb4r1xR6eq2lBX6CAa5Q+AuAqkoGCEiYBpTyKij4sXE0c+Y9nIDIZhru7EnZvpL3
+SQvxzFryQLbWCGri0x9GKXZ2ZcDM7jRi/P+iX6yX6sVvOvyKz6NW2BI5OmpI1JbJ
+3fIXt/R6Wl2xpAFL/pxtYTYbfL6277HWtLDTqIkkRFKh64JdkH8n4G4m6VNUtGEu
+qP3SxtyShauxY44WzR0YX4rag6tU2Hks6h1JmyF8aQTBAkdP7UrQ0oxZ8f+iG9n6
+3GtTxgw2NyrqVMx3kBLm8DipyslbA2wCeZLrW6Co0j3pebJsDrMP/3zcmbJqRSLq
+qnkcxA4gn5j/N0oe8t26Y2WjovndhoR0QQxw8D/BKoMXbl0lvvRAtcnWtyG0COut
+AGB2PUbGdAX2Ky+uYKrG4uhu1edfV8JZVvB7NIQGzM2P8F9PrDRz7EtG6z7ky/pq
+HQwRbqwLWGs4QpQmHZchFmXH7pHmLC8i29W+xYhdeUstvx7oESbunICGrPjJOShJ
+G4191Zg0m/M6jeWV/v+piUXe3YVrgs42UWFusm5ZIduPUfgqUtkAEQEAAYkEPgQY
+AQoACQUCUWVXugIbLgIpCRCUTTX5rD23asFdIAQZAQoABgUCUWVXugAKCRAu659c
+wJUmwaduEACCiiRpBeKF5fSaM0cTb97hAHVQJL9Wk3xvA49YuROsSwtCzq9v+js5
+f/fE+QV/dIQUNwifEPQk8MqUVKpe1lIXwRp23GinzDAnOhfWnECqrMdR0dP99D49
+Zb7Dd4LDvP9c0mYtnX/78qQilxWmXhzDXcunnPsfCqsrduk9hMwkjmIrWFeSWSAg
+BEJDuZ4WLuqjni1udth0iZtZYrDaDgX/RWcTFW8QCc5hLsCRcInAxb75AWfWq6i/
+s3Ibg5tGm4+UfqGbFPuNyy6ow3ggqkovBp6ABMxe8dAYVXSmM2tKWZXBb3L6eho8
+QKKzyoezqpbQ2YUaYZ8XAdLuumXCtAHKP3/DI1JBefE0mxi1CXjdLK9sE5OO5KNt
+FXR8Dnot5C4BHrcaF6Iq2sqbhPxnhcDrEwv2mUgruD7n04LKIztAG0A35rcu6A2i
+IUq/PsXjS/5rX/p4CeYvnTTspXkhXgkvfhWz1cISXyfcNTWBKwOsLW4lY8bi05cv
+4Axl88tTg2dNYXIxSK7Jtu1YCEsZ8uaT3AAiTp1sKAOcRX8hIOTmPPxMxbIm8yg1
+jl71ovsV5rAyuVTUouFnljXyuLWXLotUOkmC6DjJUuRaxzt23/eByJ45x94T/A2U
+iT1oU+voigQGARrDkApXlgSI4oekg3Zgq57y6toV9F7o9A1PMtBq3AvDD/0as1K0
+wCRZIXinSwW2F6tFnVV+z+vvE0i54yHaskkuJYZRSQ/yJR1VgmW/BtAr7ooXF7l+
+9g7XOH7D8T28h+m4ABLN5ZDOxfTMZuV5Y4MnELh4dlBIfKGG2kjmW8+y/PUqMMGE
+BYRmGOD1qtWvFYoZ2ss5yrlvfenRRhQbIYSRz/YiT8OTogaNcYNpArUwT4z+05af
+kdxx0AaqauHqKRo/XTO5GIZQ6NbtPH6G++2Ie+oP8AyBWEpL3rvjZpzn7jxTBXMc
+MOMmhnb0Go4hD+BSphgDTZOgMLOLcorjb1Ct2VnajxPZD0aTB13SCgZjJhs9j3on
+EoI3gTHkRgiBjMBNtw7iaAumIRgrDwGzyuIL6bbyfDnbE02zxCqkYP6P0u48FGLs
+E4U60GrYSlFxa1MexF+HIPgqWsTOv4D2zXEJYvm1XEu1VOGQUkw7J5RFTDxHgkbh
+qvmkZ492iW2IC4L9hSdSqiZ5LhD2JwpgrMt8vrCzVitkjYQnXJ6WbWYfCybPsmLb
+mfQ03i9E+a50UC2SGDf8e3oxImAbbXLP/LyI7oczCxyb0EzcQlIIOtBgl3gI6KAh
+PTRQGeHCzIOSgUf7B0ihY7qiDeR1OshvTY0wdykdS0c+hzwuS5TZvfY4YM7Tssvt
+XwbdK0Zpx/oDtRHpuDMGKJBV2LWAZYkEbFsmtg==
+=3o2I
+-----END PGP PUBLIC KEY BLOCK-----
Upstart: bitcoind.conf
OpenRC: bitcoind.openrc
bitcoind.openrcconf
+CentOS: bitcoind.init
have been made available to assist packagers in creating node packages here.
--- /dev/null
+#!/bin/bash
+#
+# bitcoind The bitcoin core server.
+#
+#
+# chkconfig: 345 80 20
+# description: bitcoind
+# processname: bitcoind
+#
+
+# Source function library.
+. /etc/init.d/functions
+
+# you can override defaults in /etc/sysconfig/bitcoind, see below
+if [ -f /etc/sysconfig/bitcoind ]; then
+ . /etc/sysconfig/bitcoind
+fi
+
+RETVAL=0
+
+prog=bitcoind
+# you can override the lockfile via BITCOIND_LOCKFILE in /etc/sysconfig/bitcoind
+lockfile=${BITCOIND_LOCKFILE-/var/lock/subsys/bitcoind}
+
+# bitcoind defaults to /usr/bin/bitcoind, override with BITCOIND_BIN
+bitcoind=${BITCOIND_BIN-/usr/bin/bitcoind}
+
+# bitcoind opts default to -disablewallet, override with BITCOIND_OPTS
+bitcoind_opts=${BITCOIND_OPTS--disablewallet}
+
+start() {
+ echo -n $"Starting $prog: "
+ daemon $DAEMONOPTS $bitcoind $bitcoind_opts
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && touch $lockfile
+ return $RETVAL
+}
+
+stop() {
+ echo -n $"Stopping $prog: "
+ killproc $prog
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && rm -f $lockfile
+ return $RETVAL
+}
+
+case "$1" in
+ start)
+ start
+ ;;
+ stop)
+ stop
+ ;;
+ status)
+ status $prog
+ ;;
+ restart)
+ stop
+ start
+ ;;
+ *)
+ echo "Usage: service $prog {start|stop|status|restart}"
+ exit 1
+ ;;
+esac
BITCOIND_PIDDIR=${BITCOIND_PIDDIR:-/var/run/bitcoind}
BITCOIND_PIDFILE=${BITCOIND_PIDFILE:-${BITCOIND_PIDDIR}/bitcoind.pid}
BITCOIND_DATADIR=${BITCOIND_DATADIR:-${BITCOIND_DEFAULT_DATADIR}}
-BITCOIND_USER=${BITCOIND_USER:-bitcoin}
+BITCOIND_USER=${BITCOIND_USER:-${BITCOIN_USER:-bitcoin}}
BITCOIND_GROUP=${BITCOIND_GROUP:-bitcoin}
BITCOIND_BIN=${BITCOIND_BIN:-/usr/bin/bitcoind}
+BITCOIND_NICE=${BITCOIND_NICE:-${NICELEVEL:-0}}
+BITCOIND_OPTS="${BITCOIND_OPTS:-${BITCOIN_OPTS}}"
name="Bitcoin Core Daemon"
description="Bitcoin crypto-currency p2p network daemon"
required_files="${BITCOIND_CONFIGFILE}"
start_stop_daemon_args="-u ${BITCOIND_USER} \
- -N ${BITCOIND_NICE:-0} -w 2000"
+ -N ${BITCOIND_NICE} -w 2000"
pidfile="${BITCOIND_PIDFILE}"
retry=60
#
# linearize-data.py: Construct a linear, no-fork version of the chain.
#
-# Copyright (c) 2013-2014 The Bitcoin developers
-# Distributed under the MIT/X11 software license, see the accompanying
+# 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.
#
outFname = self.settings['output_file']
else:
outFname = "%s/blk%05d.dat" % (self.settings['output'], outFn)
- print("Output file" + outFname)
+ print("Output file " + outFname)
self.outF = open(outFname, "wb")
self.outF.write(inhdr)
while self.blkCountOut < len(self.blkindex):
if not self.inF:
fname = self.inFileName(self.inFn)
- print("Input file" + fname)
+ print("Input file " + fname)
try:
self.inF = open(fname, "rb")
except IOError:
inMagic = inhdr[:4]
if (inMagic != self.settings['netmagic']):
- print("Invalid magic:" + inMagic)
+ print("Invalid magic: " + inMagic)
return
inLenLE = inhdr[4:]
su = struct.unpack("<I", inLenLE)
blkmap = mkblockmap(blkindex)
if not "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" in blkmap:
- print("not found")
+ print("Genesis block not found in hashlist")
else:
BlockDataCopier(settings, blkindex, blkmap).run()
#
# linearize-hashes.py: List blocks in a linear, no-fork version of the chain.
#
-# Copyright (c) 2013-2014 The Bitcoin developers
-# Distributed under the MIT/X11 software license, see the accompanying
+# 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.
#
--- /dev/null
+#!/bin/sh
+set -e
+
+UNSIGNED=$1
+SIGNATURE=$2
+ARCH=x86_64
+ROOTDIR=dist
+BUNDLE=${ROOTDIR}/Bitcoin-Qt.app
+TEMPDIR=signed.temp
+OUTDIR=signed-app
+
+if [ -z "$UNSIGNED" ]; then
+ echo "usage: $0 <unsigned app> <signature>"
+ exit 1
+fi
+
+if [ -z "$SIGNATURE" ]; then
+ echo "usage: $0 <unsigned app> <signature>"
+ exit 1
+fi
+
+rm -rf ${TEMPDIR} && mkdir -p ${TEMPDIR}
+tar -C ${TEMPDIR} -xf ${UNSIGNED}
+tar -C ${TEMPDIR} -xf ${SIGNATURE}
+
+if [ -z "${PAGESTUFF}" ]; then
+ PAGESTUFF=${TEMPDIR}/pagestuff
+fi
+
+if [ -z "${CODESIGN_ALLOCATE}" ]; then
+ CODESIGN_ALLOCATE=${TEMPDIR}/codesign_allocate
+fi
+
+for i in `find ${TEMPDIR} -name "*.sign"`; do
+ SIZE=`stat -c %s ${i}`
+ TARGET_FILE=`echo ${i} | sed 's/\.sign$//'`
+
+ echo "Allocating space for the signature of size ${SIZE} in ${TARGET_FILE}"
+ ${CODESIGN_ALLOCATE} -i ${TARGET_FILE} -a ${ARCH} ${SIZE} -o ${i}.tmp
+
+ OFFSET=`${PAGESTUFF} ${i}.tmp -p | tail -2 | grep offset | sed 's/[^0-9]*//g'`
+ if [ -z ${QUIET} ]; then
+ echo "Attaching signature at offset ${OFFSET}"
+ fi
+
+ dd if=$i of=${i}.tmp bs=1 seek=${OFFSET} count=${SIZE} 2>/dev/null
+ mv ${i}.tmp ${TARGET_FILE}
+ rm ${i}
+ echo "Success."
+done
+mv ${TEMPDIR}/${ROOTDIR} ${OUTDIR}
+rm -rf ${TEMPDIR}
+echo "Signed: ${OUTDIR}"
--- /dev/null
+#!/bin/sh
+set -e
+
+ROOTDIR=dist
+BUNDLE=${ROOTDIR}/Bitcoin-Qt.app
+CODESIGN=codesign
+TEMPDIR=sign.temp
+TEMPLIST=${TEMPDIR}/signatures.txt
+OUT=signature.tar.gz
+
+if [ ! -n "$1" ]; then
+ echo "usage: $0 <codesign args>"
+ echo "example: $0 -s MyIdentity"
+ exit 1
+fi
+
+rm -rf ${TEMPDIR} ${TEMPLIST}
+mkdir -p ${TEMPDIR}
+
+${CODESIGN} -f --file-list ${TEMPLIST} "$@" "${BUNDLE}"
+
+for i in `grep -v CodeResources ${TEMPLIST}`; do
+ TARGETFILE="${BUNDLE}/`echo ${i} | sed "s|.*${BUNDLE}/||"`"
+ SIZE=`pagestuff $i -p | tail -2 | grep size | sed 's/[^0-9]*//g'`
+ OFFSET=`pagestuff $i -p | tail -2 | grep offset | sed 's/[^0-9]*//g'`
+ SIGNFILE="${TEMPDIR}/${TARGETFILE}.sign"
+ DIRNAME="`dirname ${SIGNFILE}`"
+ mkdir -p "${DIRNAME}"
+ echo "Adding detached signature for: ${TARGETFILE}. Size: ${SIZE}. Offset: ${OFFSET}"
+ dd if=$i of=${SIGNFILE} bs=1 skip=${OFFSET} count=${SIZE} 2>/dev/null
+done
+
+for i in `grep CodeResources ${TEMPLIST}`; do
+ TARGETFILE="${BUNDLE}/`echo ${i} | sed "s|.*${BUNDLE}/||"`"
+ RESOURCE="${TEMPDIR}/${TARGETFILE}"
+ DIRNAME="`dirname "${RESOURCE}"`"
+ mkdir -p "${DIRNAME}"
+ echo "Adding resource for: "${TARGETFILE}""
+ cp "${i}" "${RESOURCE}"
+done
+
+rm ${TEMPLIST}
+
+tar -C ${TEMPDIR} -czf ${OUT} .
+rm -rf ${TEMPDIR}
+echo "Created ${OUT}"
<integer>620</integer>
</array>
<key>background_picture</key>
- <string>background.png</string>
+ <string>background.tiff</string>
<key>icon_size</key>
<integer>96</integer>
<key>applications_symlink</key>
for path, dirs, files in os.walk("dist"):
for file in files:
size += os.path.getsize(os.path.join(path, file))
- size += int(size * 0.1)
+ size += int(size * 0.15)
if verbose >= 3:
print "Creating temp image for modification..."
print "+ Applying fancy settings +"
if fancy.has_key("background_picture"):
- bg_path = os.path.join(disk_root, os.path.basename(fancy["background_picture"]))
+ bg_path = os.path.join(disk_root, ".background", os.path.basename(fancy["background_picture"]))
+ os.mkdir(os.path.dirname(bg_path))
if verbose >= 3:
print fancy["background_picture"], "->", bg_path
shutil.copy2(fancy["background_picture"], bg_path)
if bg_path is not None:
# Set background file, then call SetFile to make it invisible.
# (note: making it invisible first makes set background picture fail)
- bgscript = Template("""set background picture of theViewOptions to file "$bgpic"
- do shell script "SetFile -a V /Volumes/$disk/$bgpic" """)
+ bgscript = Template("""set background picture of theViewOptions to file ".background:$bgpic"
+ do shell script "SetFile -a V /Volumes/$disk/.background/$bgpic" """)
params["background_commands"] = bgscript.substitute({"bgpic" : os.path.basename(bg_path), "disk" : params["disk"]})
s = appscript.substitute(params)
### Seeds ###
-Utility to generate the pnSeed[] array that is compiled into the client
-(see [src/net.cpp](/src/net.cpp)).
+Utility to generate the seeds.txt list that is compiled into the client
+(see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and [share/seeds](/share/seeds)).
-The 600 seeds compiled into the 0.8 release were created from sipa's DNS seed data, like this:
+The 512 seeds compiled into the 0.10 release were created from sipa's DNS seed data, like this:
- curl -s http://bitcoin.sipa.be/seeds.txt | head -1000 | makeseeds.py
-
-The input to makeseeds.py is assumed to be approximately sorted from most-reliable to least-reliable,
-with IP:port first on each line (lines that don't match IPv4:port are ignored).
+ curl -s http://bitcoin.sipa.be/seeds.txt | makeseeds.py
#!/usr/bin/env python
#
-# Generate pnSeed[] from Pieter's DNS seeder
+# Generate seeds.txt from Pieter's DNS seeder
#
-NSEEDS=600
+NSEEDS=512
+
+MAX_SEEDS_PER_ASN=2
+
+MIN_BLOCKS = 337600
+
+# These are hosts that have been observed to be behaving strangely (e.g.
+# aggressively connecting to every node).
+SUSPICIOUS_HOSTS = set([
+ "130.211.129.106", "178.63.107.226",
+ "83.81.130.26", "88.198.17.7", "148.251.238.178", "176.9.46.6",
+ "54.173.72.127", "54.174.10.182", "54.183.64.54", "54.194.231.211",
+ "54.66.214.167", "54.66.220.137", "54.67.33.14", "54.77.251.214",
+ "54.94.195.96", "54.94.200.247"
+])
import re
import sys
-from subprocess import check_output
+import dns.resolver
+
+PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):8333$")
+PATTERN_AGENT = re.compile(r"^(\/Satoshi:0.8.6\/|\/Satoshi:0.9.(2|3)\/|\/Satoshi:0.10.\d{1,2}\/)$")
+
+def parseline(line):
+ sline = line.split()
+ if len(sline) < 11:
+ return None
+ # Match only IPv4
+ m = PATTERN_IPV4.match(sline[0])
+ if m is None:
+ return None
+ # Do IPv4 sanity check
+ ip = 0
+ for i in range(0,4):
+ if int(m.group(i+2)) < 0 or int(m.group(i+2)) > 255:
+ return None
+ ip = ip + (int(m.group(i+2)) << (8*(3-i)))
+ if ip == 0:
+ return None
+ # Skip bad results.
+ if sline[1] == 0:
+ return None
+ # Extract uptime %.
+ uptime30 = float(sline[7][:-1])
+ # Extract Unix timestamp of last success.
+ lastsuccess = int(sline[2])
+ # Extract protocol version.
+ version = int(sline[10])
+ # Extract user agent.
+ agent = sline[11][1:-1]
+ # Extract service flags.
+ service = int(sline[9], 16)
+ # Extract blocks.
+ blocks = int(sline[8])
+ # Construct result.
+ return {
+ 'ip': m.group(1),
+ 'ipnum': ip,
+ 'uptime': uptime30,
+ 'lastsuccess': lastsuccess,
+ 'version': version,
+ 'agent': agent,
+ 'service': service,
+ 'blocks': blocks,
+ }
+
+# Based on Greg Maxwell's seed_filter.py
+def filterbyasn(ips, max_per_asn, max_total):
+ result = []
+ asn_count = {}
+ for ip in ips:
+ if len(result) == max_total:
+ break
+ try:
+ asn = int([x.to_text() for x in dns.resolver.query('.'.join(reversed(ip['ip'].split('.'))) + '.origin.asn.cymru.com', 'TXT').response.answer][0].split('\"')[1].split(' ')[0])
+ if asn not in asn_count:
+ asn_count[asn] = 0
+ if asn_count[asn] == max_per_asn:
+ continue
+ asn_count[asn] += 1
+ result.append(ip)
+ except:
+ sys.stderr.write('ERR: Could not resolve ASN for "' + ip['ip'] + '"\n')
+ return result
def main():
lines = sys.stdin.readlines()
+ ips = [parseline(line) for line in lines]
+
+ # Skip entries with valid IPv4 address.
+ ips = [ip for ip in ips if ip is not None]
+ # Skip entries from suspicious hosts.
+ ips = [ip for ip in ips if ip['ip'] not in SUSPICIOUS_HOSTS]
+ # Enforce minimal number of blocks.
+ ips = [ip for ip in ips if ip['blocks'] >= MIN_BLOCKS]
+ # Require service bit 1.
+ ips = [ip for ip in ips if (ip['service'] & 1) == 1]
+ # Require at least 50% 30-day uptime.
+ ips = [ip for ip in ips if ip['uptime'] > 50]
+ # Require a known and recent user agent.
+ ips = [ip for ip in ips if PATTERN_AGENT.match(ip['agent'])]
+ # Sort by availability (and use last success as tie breaker)
+ ips.sort(key=lambda x: (x['uptime'], x['lastsuccess'], x['ip']), reverse=True)
+ # Look up ASNs and limit results, both per ASN and globally.
+ ips = filterbyasn(ips, MAX_SEEDS_PER_ASN, NSEEDS)
+ # Sort the results by IP address (for deterministic output).
+ ips.sort(key=lambda x: (x['ipnum']))
- ips = []
- pattern = re.compile(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):8333")
- for line in lines:
- m = pattern.match(line)
- if m is None:
- continue
- ip = 0
- for i in range(0,4):
- ip = ip + (int(m.group(i+1)) << (8*(i)))
- if ip == 0:
- continue
- ips.append(ip)
-
- for row in range(0, min(NSEEDS,len(ips)), 8):
- print " " + ", ".join([ "0x%08x"%i for i in ips[row:row+8] ]) + ","
+ for ip in ips:
+ print ip['ip']
if __name__ == '__main__':
main()
NO_QT ?=
NO_WALLET ?=
NO_UPNP ?=
-USE_LINUX_STATIC_QT5 ?=
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
BUILD = $(shell ./config.guess)
base_build_dir=$(BASEDIR)/work/build
base_staging_dir=$(BASEDIR)/work/staging
+base_download_dir=$(BASEDIR)/work/download
canonical_host:=$(shell ./config.sub $(HOST))
build:=$(shell ./config.sub $(BUILD))
$(AT)touch $@
install: $(host_prefix)/share/config.site
-download: $(all_sources)
-.PHONY: install cached
+download-one: $(all_sources)
+download-osx:
+ @$(MAKE) -s HOST=x86_64-apple-darwin11 download-one
+download-linux:
+ @$(MAKE) -s HOST=x86_64-unknown-linux-gnu download-one
+download-win:
+ @$(MAKE) -s HOST=x86_64-w64-mingw32 download-one
+download: download-osx download-linux download-win
+.PHONY: install cached download-one download-osx download-linux download-win download
In theory, binaries for any target OS/architecture can be created, from a
builder running any OS/architecture. In practice, build-side tools must be
-specified when the defaults don't fit, and packages must be ammended to work
+specified when the defaults don't fit, and packages must be amended to work
on new hosts. For now, a build architecture of x86_64 is assumed, either on
Linux or OSX.
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.
Additional targets:
-download: run 'make download' to fetch sources without building them
+download: run 'make download' to fetch all sources without building them
+download-osx: run 'make download-osx' to fetch all sources needed for osx builds
+download-win: run 'make download-win' to fetch all sources needed for win builds
+download-linux: run 'make download-linux' to fetch all sources needed for linux builds
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2014-03-23'
+timestamp='2015-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
-# Originally written by Per Bothner.
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
me=`echo "$0" | sed -e 's,.*/,,'`
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
else
IBM_ARCH=powerpc
fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2014 Free Software Foundation, Inc.
+# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2014-05-01'
+timestamp='2015-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# of the GNU General Public License, version 3 ("GPLv3").
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2014 Free Software Foundation, Inc.
+Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
| c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
- | fido | fr30 | frv \
+ | fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
+ | riscv32 | riscv64 \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
c6x)
basic_machine=tic6x-unknown
;;
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown
os=-none
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
+ | visium-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
basic_machine=m68k-isi
os=-sysv
;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
basic_machine=powerpc-unknown
os=-morphos
;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
msdos)
basic_machine=i386-pc
os=-msdos
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
endef
define fetch_file
-(test -f $(SOURCES_PATH)/$(4) || \
- ( mkdir -p $$($(1)_extract_dir) && \
- ( $(build_DOWNLOAD) "$$($(1)_extract_dir)/$(4).temp" "$(2)/$(3)" || \
- $(build_DOWNLOAD) "$$($(1)_extract_dir)/$(4).temp" "$(FALLBACK_DOWNLOAD_PATH)/$(3)" ) && \
- echo "$(5) $$($(1)_extract_dir)/$(4).temp" > $$($(1)_extract_dir)/.$(4).hash && \
- $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$(4).hash && \
- mv $$($(1)_extract_dir)/$(4).temp $(SOURCES_PATH)/$(4) ))
+(test -f $$($(1)_source_dir)/$(4) || \
+ ( mkdir -p $$($(1)_download_dir) && echo Fetching $(1)... && \
+ ( $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(2)/$(3)" || \
+ $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(FALLBACK_DOWNLOAD_PATH)/$(3)" ) && \
+ echo "$(5) $$($(1)_download_dir)/$(4).temp" > $$($(1)_download_dir)/.$(4).hash && \
+ $(build_SHA256SUM) -c $$($(1)_download_dir)/.$(4).hash && \
+ mv $$($(1)_download_dir)/$(4).temp $$($(1)_source_dir)/$(4) && \
+ rm -rf $$($(1)_download_dir) ))
endef
define int_get_build_recipe_hash
-$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches))))
-$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | $(build_SHA256SUM)))
+$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches)) | cut -d" " -f1))
+$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | $(build_SHA256SUM) | cut -d" " -f1))
endef
define int_get_build_id
#compute package-specific paths
$(1)_build_subdir?=.
$(1)_download_file?=$($(1)_file_name)
-$(1)_source:=$(SOURCES_PATH)/$($(1)_file_name)
+$(1)_source_dir:=$(SOURCES_PATH)
+$(1)_source:=$$($(1)_source_dir)/$($(1)_file_name)
$(1)_staging_dir=$(base_staging_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)
$(1)_staging_prefix_dir:=$$($(1)_staging_dir)$($($(1)_type)_prefix)
$(1)_extract_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)
+$(1)_download_dir:=$(base_download_dir)/$(1)-$($(1)_version)
$(1)_build_dir:=$$($(1)_extract_dir)/$$($(1)_build_subdir)
$(1)_patch_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)/.patches-$($(1)_build_id)
$(1)_prefixbin:=$($($(1)_type)_prefix)/bin/
$(1)_cached:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz
#stamps
-$(1)_fetched=$$($(1)_extract_dir)/.stamp_fetched
+$(1)_fetched=$$($(1)_source_dir)/download-stamps/.stamp_fetched-$(1)-$($(1)_file_name)
$(1)_extracted=$$($(1)_extract_dir)/.stamp_extracted
$(1)_preprocessed=$$($(1)_extract_dir)/.stamp_preprocessed
$(1)_cleaned=$$($(1)_extract_dir)/.stamp_cleaned
define int_add_cmds
$($(1)_fetched):
- $(AT)echo Fetching $(1)...
$(AT)mkdir -p $$(@D) $(SOURCES_PATH)
$(AT)cd $$(@D); $(call $(1)_fetch_cmds,$(1))
$(AT)touch $$@
# These functions create the build targets for each package. They must be
# broken down into small steps so that each part is done for all packages
# before moving on to the next step. Otherwise, a package's info
-# (build-id for example) would only be avilable to another package if it
+# (build-id for example) would only be available to another package if it
# happened to be computed already.
#set the type for host/build packages.
-OSX_MIN_VERSION=10.6
-OSX_SDK_VERSION=10.7
+OSX_MIN_VERSION=10.7
+OSX_SDK_VERSION=10.9
OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk
-darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK)
-darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK)
+LD64_VERSION=241.9
+darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
+darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION)
darwin_CFLAGS=-pipe
darwin_CXXFLAGS=$(darwin_CFLAGS)
+++ /dev/null
-package=gmp
-$(package)_version=6.0.0a
-$(package)_download_path=https://gmplib.org/download/gmp
-$(package)_file_name=$(package)-$($(package)_version).tar.bz2
-$(package)_sha256_hash=7f8e9a804b9c6d07164cf754207be838ece1219425d64e28cfa3e70d5c759aaf
-$(package)_patches=arm_gmp_build_fix.patch darwin_gmp_build_fix.patch
-
-define $(package)_preprocess_cmds
- patch -p1 < $($(package)_patch_dir)/arm_gmp_build_fix.patch && \
- patch -p1 < $($(package)_patch_dir)/darwin_gmp_build_fix.patch
-endef
-
-define $(package)_set_vars
- $(package)_config_opts=--disable-shared CC_FOR_BUILD=$(build_CC)
- $(package)_config_opts_x86_64_darwin=--with-pic
- $(package)_config_opts_x86_64_linux=--with-pic
- $(package)_config_opts_arm_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
sed "s/pthread-stubs//" -i configure
endef
+# Don't install xcb headers to the default path in order to work around a qt
+# build issue: https://bugreports.qt.io/browse/QTBUG-34748
+# When using qt's internal libxcb, it may end up finding the real headers in
+# depends staging. Use a non-default path to avoid that.
+
define $(package)_config_cmds
- $($(package)_autoconf)
+ $($(package)_autoconf) --includedir=$(host_prefix)/include/xcb-shared
endef
define $(package)_build_cmds
package=native_cctools
-$(package)_version=809
-$(package)_download_path=http://www.opensource.apple.com/tarballs/cctools
-$(package)_file_name=cctools-$($(package)_version).tar.gz
-$(package)_sha256_hash=03ba62749b843b131c7304a044a98c6ffacd65b1399b921d69add0375f79d8ad
-$(package)_build_subdir=cctools2odcctools/odcctools-$($(package)_version)
-$(package)_dependencies=native_libuuid native_openssl
-$(package)_ld64_download_file=ld64-127.2.tar.gz
-$(package)_ld64_download_path=http://www.opensource.apple.com/tarballs/ld64
-$(package)_ld64_file_name=$($(package)_ld64_download_file)
-$(package)_ld64_sha256_hash=97b75547b2bd761306ab3e15ae297f01e7ab9760b922bc657f4ef72e4e052142
-$(package)_dyld_download_file=dyld-195.5.tar.gz
-$(package)_dyld_download_path=http://www.opensource.apple.com/tarballs/dyld
-$(package)_dyld_file_name=$($(package)_dyld_download_file)
-$(package)_dyld_sha256_hash=2cf0484c87cf79b606b351a7055a247dae84093ae92c747a74e0cde2c8c8f83c
-$(package)_toolchain4_download_file=10cc648683617cca8bcbeae507888099b41b530c.tar.gz
-$(package)_toolchain4_download_path=https://github.com/mingwandroid/toolchain4/archive
-$(package)_toolchain4_file_name=toolchain4-1.tar.gz
-$(package)_toolchain4_sha256_hash=18406961fd4a1ec5c7ea35c91d6a80a2f8bb797a2bd243a610bd75e13eff9aca
-$(package)_clang_download_file=clang+llvm-3.2-x86-linux-ubuntu-12.04.tar.gz
-$(package)_clang_download_path=http://llvm.org/releases/3.2
-$(package)_clang_file_name=clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz
-$(package)_clang_sha256_hash=b9d57a88f9514fa1f327a1a703756d0c1c960f4c58494a5bd80313245d13ffff
-
+$(package)_version=ee31ae567931c426136c94aad457c7b51d844beb
+$(package)_download_path=https://github.com/theuni/cctools-port/archive
+$(package)_file_name=$($(package)_version).tar.gz
+$(package)_sha256_hash=ef107e6ab1b3994cb22e14f4f5c59ea0c0b5a988e6b21d42ed9616b018bbcbf9
+$(package)_build_subdir=cctools
+$(package)_clang_version=3.3
+$(package)_clang_download_path=http://llvm.org/releases/$($(package)_clang_version)
+$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz
+$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-amd64-Ubuntu-12.04.2.tar.gz
+$(package)_clang_sha256_hash=60d8f69f032d62ef61bf527857ebb933741ec3352d4d328c5516aa520662dab7
define $(package)_fetch_cmds
$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \
-$(call fetch_file,$(package),$($(package)_ld64_download_path),$($(package)_ld64_download_file),$($(package)_ld64_file_name),$($(package)_ld64_sha256_hash)) && \
-$(call fetch_file,$(package),$($(package)_dyld_download_path),$($(package)_dyld_download_file),$($(package)_dyld_file_name),$($(package)_dyld_sha256_hash)) && \
-$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash)) && \
-$(call fetch_file,$(package),$($(package)_toolchain4_download_path),$($(package)_toolchain4_download_file),$($(package)_toolchain4_file_name),$($(package)_toolchain4_sha256_hash))
+$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash))
endef
-define $(package)_set_vars
-$(package)_config_opts=--target=$(host) --with-sysroot=$(OSX_SDK)
-$(package)_cflags+=-m32
-$(package)_cxxflags+=-m32
-$(package)_cppflags+=-D__DARWIN_UNIX03 -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
-$(package)_ldflags+=-m32 -Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib
-$(package)_ldflags+=-L$$(native_cctools_extract_dir)/clang+llvm-3.2-x86-linux-ubuntu-12.04/lib
-endef
define $(package)_extract_cmds
- tar --strip-components=1 -xf $(SOURCES_PATH)/$($(package)_toolchain4_file_name) && \
- ln -sf $($(package)_source) cctools2odcctools/$($(package)_file_name) && \
- ln -sf $(SOURCES_PATH)/$($(package)_ld64_file_name) cctools2odcctools/$($(package)_ld64_file_name) && \
- ln -sf $(SOURCES_PATH)/$($(package)_dyld_file_name) cctools2odcctools/$($(package)_dyld_file_name) && \
- tar xf $(SOURCES_PATH)/$($(package)_clang_file_name) && \
- mkdir -p $(SDK_PATH) sdks &&\
- cd sdks; ln -sf $(OSX_SDK) MacOSX$(OSX_SDK_VERSION).sdk
+ mkdir -p toolchain/bin toolchain/lib/clang/3.5/include && \
+ tar --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \
+ echo "#!/bin/sh" > toolchain/bin/$(host)-dsymutil && \
+ echo "exit 0" >> toolchain/bin/$(host)-dsymutil && \
+ chmod +x toolchain/bin/$(host)-dsymutil && \
+ tar --strip-components=1 -xf $($(package)_source)
+endef
+
+define $(package)_set_vars
+$(package)_config_opts=--target=$(host) --disable-libuuid
+$(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib
+$(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang
+$(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++
endef
define $(package)_preprocess_cmds
- sed -i "s|GCC_DIR|LLVM_CLANG_DIR|g" cctools2odcctools/extract.sh && \
- sed -i "s|llvmgcc42-2336.1|clang+llvm-3.2-x86-linux-ubuntu-12.04|g" cctools2odcctools/extract.sh && \
- sed -i "s|/llvmCore/include/llvm-c|/include/llvm-c \$$$${LLVM_CLANG_DIR}/include/llvm |" cctools2odcctools/extract.sh && \
- sed -i "s|fAC_INIT|AC_INIT|" cctools2odcctools/files/configure.ac && \
- sed -i 's/\# Dynamically linked LTO/\t ;\&\n\t linux*)\n# Dynamically linked LTO/' cctools2odcctools/files/configure.ac && \
- cd cctools2odcctools; ./extract.sh --osxver $(OSX_SDK_VERSION) && \
- sed -i "s|define\tPC|define\tPC_|" odcctools-809/include/architecture/sparc/reg.h
+ cd $($(package)_build_subdir); ./autogen.sh
endef
define $(package)_config_cmds
define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install && \
- cd ../../clang+llvm-3.2-x86-linux-ubuntu-12.04 && \
- mkdir -p $($(package)_staging_prefix_dir)/lib/clang/3.2/include && \
- mkdir -p $($(package)_staging_prefix_dir)/bin && \
+ cd $($(package)_extract_dir)/toolchain && \
+ mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include && \
+ mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \
cp -P bin/clang bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\
cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \
- cp lib/clang/3.2/include/* $($(package)_staging_prefix_dir)/lib/clang/3.2/include/ && \
- echo "#!/bin/sh" > $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \
- echo "exit 0" >> $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \
- chmod +x $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil
+ cp -rf lib/clang/$($(package)_clang_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include/ && \
+ cp bin/$(host)-dsymutil $($(package)_staging_prefix_dir)/bin && \
+ if `test -d include/c++/`; then cp -rf include/c++/ $($(package)_staging_prefix_dir)/include/; fi && \
+ if `test -d lib/c++/`; then cp -rf lib/c++/ $($(package)_staging_prefix_dir)/lib/; fi
endef
package=native_cdrkit
$(package)_version=1.1.11
-$(package)_download_path=http://distro.ibiblio.org/fatdog/source/c
+$(package)_download_path=http://distro.ibiblio.org/fatdog/source/600/c
$(package)_file_name=cdrkit-$($(package)_version).tar.bz2
$(package)_sha256_hash=b50d64c214a65b1a79afe3a964c691931a4233e2ba605d793eb85d0ac3652564
$(package)_patches=cdrkit-deterministic.patch
define $(package)_stage_cmds
mkdir -p $($(package)_staging_prefix_dir)/share/$($(package)_install_dirname) && \
- mv $(SOURCES_PATH)/$($(package)_file_name) $($(package)_staging_prefix_dir)/share/$($(package)_install_dirname)/$($(package)_install_filename)
+ cp $($(package)_source) $($(package)_staging_prefix_dir)/share/$($(package)_install_dirname)/$($(package)_install_filename)
endef
+++ /dev/null
-package:=native_libuuid
-$(package)_version=1.41.14
-$(package)_download_path=http://downloads.sourceforge.net/e2fsprogs
-$(package)_file_name=e2fsprogs-libs-$($(package)_version).tar.gz
-$(package)_sha256_hash=dbc7a138a3218d9b80a0626b5b692d76934d6746d8cbb762751be33785d8d9f5
-
-define $(package)_set_vars
-$(package)_config_opts=--disable-elf-shlibs --disable-uuidd
-$(package)_cflags+=-m32
-$(package)_ldflags+=-m32
-$(package)_cxxflags+=-m32
-endef
-
-define $(package)_config_cmds
- $($(package)_autoconf)
-endef
-
-define $(package)_build_cmds
- $(MAKE) -C lib/uuid
-endef
-
-define $(package)_stage_cmds
- $(MAKE) DESTDIR=$($(package)_staging_dir) -C lib/uuid install
-endef
+++ /dev/null
-package=native_openssl
-$(package)_version=1.0.1h
-$(package)_download_path=https://www.openssl.org/source
-$(package)_file_name=openssl-$($(package)_version).tar.gz
-$(package)_sha256_hash=9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093
-define $(package)_set_vars
-$(package)_build_config_opts= --prefix=$(build_prefix) no-zlib no-shared no-krb5C linux-generic32 -m32
-endef
-
-define $(package)_config_cmds
- ./Configure $($(package)_build_config_opts) &&\
- sed -i "s|engines apps test|engines|" Makefile
-endef
-
-define $(package)_build_cmds
- $(MAKE) -j1
-endef
-
-define $(package)_stage_cmds
- $(MAKE) INSTALL_PREFIX=$($(package)_staging_dir) -j1 install_sw
-endef
package=openssl
-$(package)_version=1.0.1j
+$(package)_version=1.0.1k
$(package)_download_path=https://www.openssl.org/source
$(package)_file_name=$(package)-$($(package)_version).tar.gz
-$(package)_sha256_hash=1b60ca8789ba6f03e8ef20da2293b8dc131c39d83814e775069f02d26354edf3
+$(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fcebe7a41c
define $(package)_set_vars
$(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
$(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_aarch64_linux=linux-generic64
+$(package)_config_opts_mipsel_linux=linux-generic32
+$(package)_config_opts_mips_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
endef
define $(package)_preprocess_cmds
- sed -i.old "/define DATE/d" crypto/Makefile && \
+ sed -i.old "/define DATE/d" util/mkbuildinf.pl && \
sed -i.old "s|engines apps test|engines|" Makefile.org
endef
-packages:=boost openssl gmp
+packages:=boost openssl
native_packages := native_ccache native_comparisontool
qt_native_packages = native_protobuf
qt_packages = qrencode protobuf
-qt46_linux_packages = qt46 expat dbus libxcb xcb_proto libXau xproto freetype libX11 xextproto libXext xtrans libICE libSM
-qt5_linux_packages= qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans
-
+qt_linux_packages= qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans
qt_darwin_packages=qt
qt_mingw32_packages=qt
-qt_linux_$(USE_LINUX_STATIC_QT5):=$(qt5_linux_packages)
-qt_linux_:=$(qt46_linux_packages)
-qt_linux_packages:=$(qt_linux_$(USE_LINUX_STATIC_QT5))
wallet_packages=bdb
upnp_packages=miniupnpc
ifneq ($(build_os),darwin)
-darwin_native_packages=native_libuuid native_openssl native_cctools native_cdrkit native_libdmg-hfsplus
+darwin_native_packages=native_cctools native_cdrkit native_libdmg-hfsplus
endif
$(package)_linux_dependencies=freetype fontconfig dbus libxcb libX11 xproto libXext
$(package)_build_subdir=qtbase
$(package)_qt_libs=corelib network widgets gui plugins testlib
-$(package)_patches=mac-qmake.conf fix-xcb-include-order.patch qt5-tablet-osx.patch
+$(package)_patches=mac-qmake.conf fix-xcb-include-order.patch qt5-tablet-osx.patch qt5-yosemite.patch
define $(package)_set_vars
$(package)_config_opts_release = -release
ifneq ($(build_os),darwin)
$(package)_config_opts_darwin = -xplatform macx-clang-linux -device-option MAC_SDK_PATH=$(OSX_SDK) -device-option CROSS_COMPILE="$(host)-"
-$(package)_config_opts_darwin += -device-option MAC_MIN_VERSION=$(OSX_MIN_VERSION) -device-option MAC_TARGET=$(host)
+$(package)_config_opts_darwin += -device-option MAC_MIN_VERSION=$(OSX_MIN_VERSION) -device-option MAC_TARGET=$(host) -device-option MAC_LD64_VERSION=$(LD64_VERSION)
endif
$(package)_config_opts_linux = -qt-xkbcommon -qt-xcb -no-eglfs -no-linuxfb -system-freetype -no-sm -fontconfig -no-xinput2 -no-libudev -no-egl -no-opengl
sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \
sed -i.old "s/src_plugins.depends = src_sql src_xml src_network/src_plugins.depends = src_xml src_network/" qtbase/src/src.pro && \
sed -i.old "/XIproto.h/d" qtbase/src/plugins/platforms/xcb/qxcbxsettings.cpp && \
+ sed -i.old 's/if \[ "$$$$XPLATFORM_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/if \[ "$$$$BUILD_ON_MAC" = "yes" \]; then xspecvals=$$$$(macSDKify/' qtbase/configure && \
mkdir -p qtbase/mkspecs/macx-clang-linux &&\
cp -f qtbase/mkspecs/macx-clang/Info.plist.lib qtbase/mkspecs/macx-clang-linux/ &&\
cp -f qtbase/mkspecs/macx-clang/Info.plist.app qtbase/mkspecs/macx-clang-linux/ &&\
cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \
patch -p1 < $($(package)_patch_dir)/fix-xcb-include-order.patch && \
patch -p1 < $($(package)_patch_dir)/qt5-tablet-osx.patch && \
+ patch -d qtbase -p1 < $($(package)_patch_dir)/qt5-yosemite.patch && \
echo "QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
echo "QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
echo "QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
+++ /dev/null
-
-# HG changeset patch
-# Date 1396602422 -7200
-# Node ID 676e2d0f0e4dd301a7066079d2c9326c25c34a40
-# Parent 0194a75b56b21a9196626430af86c5bd9110c42d
-Conditionalise ARM asm on !__thumb__.
-
-diff -r 0194a75b56b2 -r 676e2d0f0e4d mpn/generic/div_qr_1n_pi1.c
---- a/mpn/generic/div_qr_1n_pi1.c Thu Apr 03 23:58:51 2014 +0200
-+++ b/mpn/generic/div_qr_1n_pi1.c Fri Apr 04 11:07:02 2014 +0200
-@@ -130,7 +130,7 @@
- "%2" ((UDItype)(a0)), "r" ((UDItype)(b0)) __CLOBBER_CC)
- #endif
-
--#if defined (__arm__) && W_TYPE_SIZE == 32
-+#if defined (__arm__) && !defined (__thumb__) && W_TYPE_SIZE == 32
- #define add_mssaaaa(m, sh, sl, ah, al, bh, bl) \
- __asm__ ( "adds %2, %5, %6\n\t" \
- "adcs %1, %3, %4\n\t" \
-
+++ /dev/null
-
-# HG changeset patch
-# Date 1396470504 -7200
-# Node ID 1fab0adc5ff7d9ecddcbda96f407da58347bb49c
-# Parent db645603dcdb41afcf78b19b551ecd5a01c3841c
-Workaround for Darwin assembler quirk.
-
-diff -r db645603dcdb -r 1fab0adc5ff7 mpn/x86_64/k8/redc_1.asm
---- a/mpn/x86_64/k8/redc_1.asm Mon Mar 31 23:04:32 2014 +0200
-+++ b/mpn/x86_64/k8/redc_1.asm Wed Apr 02 22:28:24 2014 +0200
-@@ -114,7 +114,7 @@
-
- JUMPTABSECT
- ALIGN(8)
--L(tab): JMPENT( L(0m4), L(tab))
-+L(tab): JMPENT( L(0), L(tab))
- JMPENT( L(1), L(tab))
- JMPENT( L(2), L(tab))
- JMPENT( L(3), L(tab))
-@@ -397,6 +397,7 @@
-
-
- ALIGN(16)
-+L(0):
- L(0m4):
- L(lo0): mov (mp,nneg,8), %rax
- mov nneg, i
-
---- old/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2014-07-30 18:17:27.384458441 -0400
-+++ new/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2014-07-30 18:18:28.620459303 -0400
-@@ -101,10 +101,6 @@
- }
- }
-
--DEFINES += $$QMAKE_DEFINES_XCB
--LIBS += $$QMAKE_LIBS_XCB
+--- old/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-03-17 02:06:42.705930685 +0000
++++ new/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-03-17 02:08:41.281926351 +0000
+@@ -103,7 +103,6 @@
+
+ DEFINES += $$QMAKE_DEFINES_XCB
+ LIBS += $$QMAKE_LIBS_XCB
-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
--
+
CONFIG += qpa/genericunixfontdatabase
-
- contains(QT_CONFIG, dbus) {
-@@ -141,3 +137,7 @@
- INCLUDEPATH += ../../../3rdparty/xkbcommon/xkbcommon/
- }
- }
-+
-+DEFINES += $$QMAKE_DEFINES_XCB
-+LIBS += $$QMAKE_LIBS_XCB
-+INCLUDEPATH += $$QMAKE_CFLAGS_XCB
+
+@@ -118,7 +117,8 @@
+ contains(QT_CONFIG, xcb-qt) {
+ DEFINES += XCB_USE_RENDER
+ XCB_DIR = ../../../3rdparty/xcb
+- INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude
++ QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB
++ QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB
+ LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static
+ } else {
+ LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr
+--- old/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:07:04.641929383 +0000
++++ new/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:10:15.485922059 +0000
+@@ -8,7 +8,7 @@
+
+ XCB_DIR = ../../../../3rdparty/xcb
+
+-INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude
++QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/include/xcb -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB
+
+ # ignore compiler warnings in 3rdparty code
+ QMAKE_CFLAGS_STATIC_LIB+=-w
QMAKE_CFLAGS += -target $${MAC_TARGET}
QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS
-QMAKE_LFLAGS += -target $${MAC_TARGET}
+QMAKE_LFLAGS += -target $${MAC_TARGET} -mlinker-version=$${MAC_LD64_VERSION}
QMAKE_AR = $${CROSS_COMPILE}ar cq
QMAKE_RANLIB=$${CROSS_COMPILE}ranlib
QMAKE_LIBTOOL=$${CROSS_COMPILE}libtool
--- /dev/null
+The following patch was taken from upstream:
+https://qt.gitorious.org/qt/qtbase/commit/70e4428b6f1c6a4bad112203f67ee7d22107616c.patch
+
+The first hunk was removed because it conflicts with 5.2.1, and is not currently needed.
+
+From 70e4428b6f1c6a4bad112203f67ee7d22107616c Mon Sep 17 00:00:00 2001
+Date: Tue, 3 Jun 2014 14:20:20 +0200
+Subject: [PATCH] Cocoa: Adapt to Xcode 6 clang version sudden pickiness
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Yes, that means OS X Yosemite fix.
+
+Change-Id: I236f7af7b803de24ff0895e04c9a9253b5cfdb3b
+---
+ .../platforms/cocoa/qcocoaaccessibilityelement.mm | 2 +-
+ .../platforms/cocoa/qcocoaapplicationdelegate.mm | 2 +-
+ src/plugins/platforms/cocoa/qcocoamenuloader.mm | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+index f841184..548c6a2 100644
+--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
++++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+@@ -124,7 +124,7 @@ static void cleanupCocoaApplicationDelegate()
+ [dockMenu release];
+ [qtMenuLoader release];
+ if (reflectionDelegate) {
+- [NSApp setDelegate:reflectionDelegate];
++ [[NSApplication sharedApplication] setDelegate:reflectionDelegate];
+ [reflectionDelegate release];
+ }
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+index 60bc3b5..9340e94 100644
+--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm
++++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+@@ -174,7 +174,7 @@ QT_END_NAMESPACE
+ - (void)removeActionsFromAppMenu
+ {
+ for (NSMenuItem *item in [appMenu itemArray])
+- [item setTag:nil];
++ [item setTag:0];
+ }
+
+ - (void)dealloc
+--
+1.7.1
+
# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER = 0.9.99
+PROJECT_NUMBER = 0.10.99
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer
-Bitcoin 0.9.99 BETA
+Bitcoin Core 0.10.99
=====================
-Copyright (c) 2009-2014 Bitcoin Developers
-
-
Setup
---------------------
-[Bitcoin Core](http://bitcoin.org/en/download) is the original Bitcoin client and it builds the backbone of the network. However, it downloads and stores the entire history of Bitcoin transactions (which is currently several GBs); depending on the speed of your computer and network connection, the synchronization process can take anywhere from a few hours to a day or more. Thankfully you only have to do this once. If you would like the process to go faster you can [download the blockchain directly](bootstrap.md).
+[Bitcoin Core](http://bitcoin.org/en/download) is the original Bitcoin client and it builds the backbone of the network. However, it downloads and stores the entire history of Bitcoin transactions (which is currently several GBs); depending on the speed of your computer and network connection, the synchronization process can take anywhere from a few hours to a day or more.
Running
---------------------
---------------------
The Bitcoin repo's [root README](https://github.com/bitcoin/bitcoin/blob/master/README.md) contains relevant information on the development process and automated testing.
-- [Coding Guidelines](coding.md)
+- [Developer Notes](developer-notes.md)
- [Multiwallet Qt Development](multiwallet-qt.md)
- [Release Notes](release-notes.md)
- [Release Process](release-process.md)
License
---------------------
-Distributed under the [MIT/X11 software license](http://www.opensource.org/licenses/mit-license.php).
+Distributed under the [MIT software license](http://www.opensource.org/licenses/mit-license.php).
This product includes software developed by the OpenSSL Project for use in the [OpenSSL Toolkit](https://www.openssl.org/). This product includes
To complicate things further, all builds must target an Apple SDK. These SDKs
are free to download, but not redistributable.
-To obtain it, register for a developer account, then download xcode4630916281a.dmg:
-https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6.3/xcode4630916281a.dmg
+To obtain it, register for a developer account, then download the XCode 6.1.1 dmg:
+https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg
+
This file is several gigabytes in size, but only a single directory inside is
-needed: Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk
+needed: Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk
Unfortunately, the usual linux tools (7zip, hpmount, loopback mount) are incapable of opening this file.
To create a tarball suitable for gitian input, mount the dmg in OSX, then create it with:
- $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.7.sdk.tar.gz MacOSX10.7.sdk
+ $ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk
The gitian descriptors build 2 sets of files: Linux tools, then Apple binaries
.DS_Store before creation. The easiest way to create this file is to build a
DMG without one, move it to a device running OSX, customize the layout, then
grab the .DS_Store file for later use. That is the approach taken here.
+
+As of OSX Mavericks (10.9), using an Apple-blessed key to sign binaries is a
+requirement in order to satisfy the new Gatekeeper requirements. Because this
+private key cannot be shared, we'll have to be a bit creative in order for the
+build process to remain somewhat deterministic. Here's how it works:
+
+- Builders use gitian to create an unsigned release. This outputs an unsigned
+ dmg which users may choose to bless and run. It also outputs an unsigned app
+ structure in the form of a tarball, which also contains all of the tools
+ that have been previously (deterministically) built in order to create a
+ final dmg.
+- The Apple keyholder uses this unsigned app to create a detached signature,
+ using the script that is also included there.
+- Builders feed the unsigned app + detached signature back into gitian. It
+ uses the pre-built tools to recombine the pieces into a deterministic dmg.
-Bitcoin 0.9.99 BETA\r
-\r
-Copyright (c) 2009-2014 Bitcoin Core Developers\r
-\r
-Distributed under the MIT/X11 software license, see the accompanying\r
-file COPYING or http://www.opensource.org/licenses/mit-license.php.\r
-This product includes software developed by the OpenSSL Project for use in\r
-the OpenSSL Toolkit (https://www.openssl.org/). This product includes\r
-\r
+Bitcoin Core 0.10.99\r
+=====================\r
\r
Intro\r
-----\r
--- /dev/null
+Unauthenticated REST Interface
+==============================
+
+The REST API can be enabled with the `-rest` option.
+
+Supported API
+-------------
+`GET /rest/tx/TX-HASH.{bin|hex|json}`
+
+Given a transaction hash,
+Returns a transaction, in binary, hex-encoded binary or JSON formats.
+
+For full TX query capability, one must enable the transaction index via "txindex=1" command line / configuration option.
+
+`GET /rest/block/BLOCK-HASH.{bin|hex|json}`
+`GET /rest/block/notxdetails/BLOCK-HASH.{bin|hex|json}`
+
+Given a block hash,
+Returns a block, in binary, hex-encoded binary or JSON formats.
+
+The HTTP request and response are both handled entirely in-memory, thus making maximum memory usage at least 2.66MB (1 MB max block, plus hex encoding) per request.
+
+With the /notxdetails/ option JSON response will only contain the transaction hash instead of the complete transaction details. The option only affects the JSON response.
+
+`GET /rest/chaininfo.json`
+
+Returns various state info regarding block chain processing.
+Only supports JSON as output format.
+* chain : (string) current network name as defined in BIP70 (main, test, regtest)
+* blocks : (numeric) the current number of blocks processed in the server
+* headers : (numeric) the current number of headers we have validated
+* bestblockhash : (string) the hash of the currently best block
+* difficulty : (numeric) the current difficulty
+* verificationprogress : (numeric) estimate of verification progress [0..1]
+* chainwork : (string) total amount of work in active chain, in hexadecimal
+
+Risks
+-------------
+Running a webbrowser on the same node with a REST enabled bitcoind can be a risk. Accessing prepared XSS websites could read out tx/block data of your node by placing links like `<script src="http://127.0.0.1:1234/tx/json/1234567890">` which might break the nodes privacy.
\ No newline at end of file
The following is a list of assets used in the bitcoin source and their proper attribution.
-[Wladimir van der Laan](https://github.com/laanwj)
------------------------
-#### Info
-* License: MIT
-
-### Assets Used
- src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png,
- src/qt/res/src/clock_green.svg, src/qt/res/src/clock1.svg,
- src/qt/res/src/clock2.svg, src/qt/res/src/clock3.svg,
- src/qt/res/src/clock4.svg, src/qt/res/src/clock5.svg,
- src/qt/res/src/inout.svg, src/qt/res/src/questionmark.svg
-
-[David Vignoni](http://www.icon-king.com)
------------------------
-
-### Info
-* Icon Pack: NUVOLA ICON THEME for KDE 3.x
-* License: LGPL
-* Site: [http://www.icon-king.com/projects/nuvola](http://www.icon-king.com/projects/nuvola)
-
-### Assets Used
- src/qt/res/icons/address-book.png, src/qt/res/icons/export.png,
- src/qt/res/icons/history.png, src/qt/res/icons/key.png,
- src/qt/res/icons/lock_*.png, src/qt/res/icons/overview.png,
- src/qt/res/icons/receive.png, src/qt/res/icons/send.png,
- src/qt/res/icons/synced.png, src/qt/res/icons/filesave.png
-
-schollidesign
------------------------
-
-### Info
-* Icon Pack: Human-O2
-* Designer: schollidesign
-* License: GNU/GPL
-* Site: [http://findicons.com/icon/93743/blocks_gnome_netstatus_0](http://findicons.com/icon/93743/blocks_gnome_netstatus_0)
-
-### Assets Used
- src/qt/res/icons/connect*.png
-
-md2k7
------------------------
-
-### Info
-* Designer: md2k7
-* License: You are free to do with these icons as you wish, including selling, copying, modifying etc.
-* License: MIT
-* Site: [https://bitcointalk.org/index.php?topic=15276.0](https://bitcointalk.org/index.php?topic=15276.0)
-
-### Assets Used
- src/qt/res/icons/transaction*.png
-
-[Everaldo.com](http://www.everaldo.com)
+[Typicons/Stephen Hutchings](http://typicons.com)
-----------------------
### Info
-* Icon Pack: Crystal SVG
-* Designer: [http://www.everaldo.com](http://www.everaldo.com)
-* License: LGPL
-
-### Assets Used
- src/qt/res/icons/configure.png, src/qt/res/icons/quit.png,
- src/qt/res/icons/editcopy.png, src/qt/res/icons/editpaste.png,
- src/qt/res/icons/add.png, src/qt/res/icons/edit.png,
- src/qt/res/icons/remove.png (edited)
-
-Everaldo (Everaldo Coelho)
------------------------
-
-### Info
-* Icon Pack: Kids
-* Designer: Everaldo (Everaldo Coelho)
-* License: GNU/GPL
-* Site: [http://findicons.com/icon/17102/reload?id=17102](http://findicons.com/icon/17102/reload?id=17102)
-
-### Assets Used
- scripts/img/reload.xcf (modified), src/qt/res/movies/*.png
-
-[Vignoni David](http://techbase.kde.org/Projects/Oxygen)
------------------------
-
-### Info
-* Designer: Vignoni David
-* License: Oxygen icon theme is dual licensed. You may copy it under the Creative Common Attribution-ShareAlike 3.0 License or the GNU Library General Public License.
-* Site: [http://techbase.kde.org/Projects/Oxygen](http://techbase.kde.org/Projects/Oxygen)
-
-### Assets Used
- src/qt/res/icons/debugwindow.png
+* Icon Pack: Typicons (http://typicons.com)
+* Designer: Stephen Hutchings (and more)
+* License: CC BY-SA
+* Site: [https://github.com/stephenhutchings/typicons.font](https://github.com/stephenhutchings/typicons.font)
+
+### Assets Used
+ src/qt/res/icons/add.png, src/qt/res/icons/address-book.png,
+ src/qt/res/icons/configure.png, src/qt/res/icons/connect4.png,
+ src/qt/res/icons/debugwindow.png, src/qt/res/icons/edit.png,
+ src/qt/res/icons/exitcopy.png, src/qt/res/icons/editpaste.png,
+ src/qt/res/icons/export.png, src/qt/res/icons/eye.png,
+ src/qt/res/icons/filesave.png, src/qt/res/icons/history.png,
+ src/qt/res/icons/info.png, src/qt/res/icons/key.png,
+ src/qt/res/icons/lock_*.png, src/qt/res/icons/open.png,
+ src/qt/res/icons/overview.png, src/qt/res/icons/quit.png,
+ src/qt/res/icons/receive.png, src/qt/res/icons/remove.png,
+ src/qt/res/icons/send.png, src/qt/res/icons/synced.png,
+ src/qt/res/icons/transaction*.png, src/qt/res/icons/tx_output.png,
Jonas Schnelli
-----------------------
### Info
-* Designer: Jonas Schnelli (based on the original bitcoin logo from Bitboy)
+* Designer: Jonas Schnelli
+* Bitcoin Icon: (based on the original bitcoin logo from Bitboy)
+* Some icons are based on Stephan Hutchings Typicons (these are under CC BY-SA license)
* License: MIT
### Assets Used
- src/qt/res/icons/bitcoin.icns, src/qt/res/src/bitcoin.svg,
- src/qt/res/src/bitcoin.ico, src/qt/res/src/bitcoin.png,
- src/qt/res/src/bitcoin_testnet.png, docs/bitcoin_logo_doxygen.png,
- src/qt/res/images/splash.png, src/qt/res/images/splash_testnet.png
+ src/qt/res/icons/about.png, src/qt/res/icons/about_qt.png,
+ src/qt/res/icons/bitcoin.icns, src/qt/res/icons/bitcoin.ico,
+ src/qt/res/icons/bitcoin.png, src/qt/res/icons/clock*.png,
+ src/qt/res/icons/connect[0-3].png, src/qt/res/icons/eye_minus.png,
+ src/qt/res/icons/eye_plus.png, src/qt/res/icons/verify.png,
+ src/qt/res/icons/tx_inout.png, src/qt/res/icons/tx_input.png,
+ src/qt/res/src/verify.svg, src/qt/res/src/bitcoin.svg,
+ src/qt/res/src/clock*.svg, src/qt/res/src/connect*.svg,
+ src/qt/res/src/mine.svg, src/qt/res/src/qt.svg, src/qt/res/src/tx*.svg,
+ src/qt/res/src/verify.svg,
--- /dev/null
+BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.10.0**):
+
+* [`BIP 11`](https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki): Multisig outputs are standard since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
+* [`BIP 13`](https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki): The address format for P2SH addresses has been implemented since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
+* [`BIP 14`](https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki): The subversion string is being used as User Agent since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
+* [`BIP 16`](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki): The pay-to-script-hash evaluation rules have been implemented since **v0.6.0**, and took effect on *April 1st 2012* ([PR #748](https://github.com/bitcoin/bitcoin/pull/748)).
+* [`BIP 21`](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki): The URI format for Bitcoin payments has been implemented since **v0.6.0** ([PR #176](https://github.com/bitcoin/bitcoin/pull/176)).
+* [`BIP 22`](https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki): The 'getblocktemplate' (GBT) RPC protocol for mining has been implemented since **v0.7.0** ([PR #936](https://github.com/bitcoin/bitcoin/pull/936)).
+* [`BIP 23`](https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki): Some extensions to GBT have been implemented since **v0.10.0rc1**, including longpolling and block proposals ([PR #1816](https://github.com/bitcoin/bitcoin/pull/1816)).
+* [`BIP 30`](https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki): The evaluation rules to forbid creating new transactions with the same txid as previous not-fully-spent transactions were implemented since **v0.6.0**, and the rule took effect on *March 15th 2012* ([PR #915](https://github.com/bitcoin/bitcoin/pull/915)).
+* [`BIP 31`](https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki): The 'pong' protocol message (and the protocol version bump to 60001) has been implemented since **v0.6.1** ([PR #1081](https://github.com/bitcoin/bitcoin/pull/1081)).
+* [`BIP 34`](https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki): The rule that requires blocks to contain their height (number) in the coinbase input, and the introduction of version 2 blocks has been implemented since **v0.7.0**. The rule took effect for version 2 blocks as of *block 224413* (March 5th 2013), and version 1 blocks are no longer allowed since *block 227931* (March 25th 2013) ([PR #1526](https://github.com/bitcoin/bitcoin/pull/1526)).
+* [`BIP 35`](https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki): The 'mempool' protocol message (and the protocol version bump to 60002) has been implemented since **v0.7.0** ([PR #1641](https://github.com/bitcoin/bitcoin/pull/1641)).
+* [`BIP 37`](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki): The bloom filtering for transaction relaying, partial merkle trees for blocks , and the protocol version bump to 70001 (enabling low-bandwidth SPV clients) has been implemented since **v0.8.0** ([PR #1795](https://github.com/bitcoin/bitcoin/pull/1795)).
+* [`BIP 42`](https://github.com/bitcoin/bips/blob/master/bip-0042.mediawiki): The bug that would have caused the subsidy schedule to resume after block 13440000 was fixed in **v0.9.2** ([PR #3842](https://github.com/bitcoin/bitcoin/pull/3842)).
+* [`BIP 61`](https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki): The 'reject' protocol message (and the protocol version bump to 70002) was added in **v0.9.0** ([PR #3185](https://github.com/bitcoin/bitcoin/pull/3185)).
+* [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)).
+* [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)).
+++ /dev/null
-### Bootstrap the Blockchain Synchronization
-
-Normally the Bitcoin client will download the transaction and network information, called the blockchain, from the network by syncing with the other clients. This process can take quite some time as the [Bitcoin blockchain](https://blockchain.info/charts/blocks-size) is growing bigger and bigger for each day. Luckily there is a safe and fast way to speed up this process. We'll show you how to bootstrap your blockchain to bring your client up to speed in just a few simple steps.
-
-### Requirements
-
-- A fresh install of the Bitcoin client software.
-
-### Download the blockchain via BitTorrent
-
-Jeff Garzik, Bitcoin Core developer, offers an [torrent file](https://bitcointalk.org/index.php?topic=145386.0) for bootstrapping purposes that is updated often. BitTorrent is a protocol that speeds up the downloading of large files by using the other clients in the network. Examples of free and safe open source clients are [Deluge](http://deluge-torrent.org/) or [qBittorrent](http://www.qbittorrent.org/). A guide to installing and configuring the torrent clients can be found [here](http://dev.deluge-torrent.org/wiki/UserGuide) for Deluge and [here](http://qbforums.shiki.hu/) for qBittorrent. A further in-depth tutorial on BitTorrent can be found [here](http://www.howtogeek.com/howto/31846/bittorrent-for-beginners-how-get-started-downloading-torrents/).
-
-With the client installed we'll proceed to download the blockchain torrent file. Use the following magnet link:
-
- magnet:?xt=urn:btih:2d4e6c1f96c5d5fb260dff92aea4e600227f1aea&dn=bootstrap.dat&tr=udp://tracker.openbittorrent.com:80&tr=udp://tracker.publicbt.com:80&tr=udp://tracker.ccc.de:80&tr=udp://tracker.istole.it:80
-
- or go to [Jeff Garzik's topic](https://bitcointalk.org/index.php?topic=145386.0) for a signed magnet link. Alternatively you can use the [.torrent file](http://sourceforge.net/projects/bitcoin/files/Bitcoin/blockchain/bootstrap.dat.torrent/download) found on SourceForge.
-
-![Fig1](img/bootstrap1.png)
-
-The download page should look like this, with a countdown to the download. If it does not work click the direct download link.
-
-The torrent client installed will recognize the download of the torrent file. Save the bootstrap.dat file to the folder you use for downloads. The image below shows the torrent download in qBittorrent, with current speed and ETA highlighted.
-
-![Fig2](img/bootstrap2.png)
-
-### Importing the blockchain
-Exit the Bitcoin client software if you have it running. Be sure not to have an actively used wallet in use. We are going to copy the download of the blockchain to the Bitcoin client data directory. You should run the client software at least once so it can generate the data directory. Copy the downloaded bootstrap.dat file into the Bitcoin data folder.
-
-**For Windows users:**
-Open explorer, and type into the address bar:
-
- %APPDATA%\Bitcoin
-
-This will open up the data folder. It should look like the image below. Copy over the bootstrap.dat from your download folder to this directory.
-![Fig4](img/bootstrap4.png)
-
-**For OSX users:**
-Open Finder by pressing Press [shift] + [cmd] + [g] and enter:
-
- ~/Library/Application Support/Bitcoin/
-
-**For Linux users:**
-The directory is hidden in your User folder. Go to:
-
- ~/.bitcoin/
-
-### Importing the blockchain
-Now start the Bitcoin client software. It should show "Importing blocks from disk" like the image below.
-![Fig5](img/bootstrap5.png)
-
-Wait until the import finishes. The client will download the last days not covered by the import. Congratulations you have successfully imported the blockchain!
-
-### Is this safe?
-
-Yes, the above method is safe. The download contains only raw blockchain data and the client verifies this on import. Do not download the blockchain from unofficial sources, especially if they provide `*.rev` and `*.sst` files. These files are not verified and can contain malicious edits.
be done in `Xcode > Preferences > Downloads > Components` and generally must
be re-done or updated every time Xcode is updated.
-There's also an assumption that you already have `git` installed. If
-not, it's the path of least resistance to install [Github for Mac](https://mac.github.com/)
-(OS X 10.7+) or
-[Git for OS X](https://code.google.com/p/git-osx-installer/). It is also
-available via Homebrew.
-
You will also need to install [Homebrew](http://brew.sh) in order to install library
dependencies.
#### Install dependencies using Homebrew
- brew install autoconf automake libtool boost miniupnpc openssl pkg-config protobuf qt gmp
+ brew install autoconf automake libtool boost miniupnpc openssl pkg-config protobuf qt5
+
+NOTE: Building with Qt4 is still supported, however, could result in a broken UI. As such, building with Qt5 is recommended.
#### Installing berkeley-db4 using Homebrew
Running this command takes you into brew's interactive mode, which allows you to configure, make, and install by hand:
```
-$ brew install https://raw.github.com/mxcl/homebrew/master/Library/Formula/berkeley-db4.rb -–without-java
+$ brew install https://raw.github.com/homebrew/homebrew/master/Library/Formula/berkeley-db4.rb -–without-java
```
The rest of these commands are run inside brew interactive mode:
2. Build bitcoind:
./autogen.sh
- ./configure
+ ./configure --with-gui=qt5
make
3. It is also a good idea to build and run the unit tests:
-arch x86_64
-isysroot $(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk
-Once dependencies are compiled, see release-process.md for how the Bitcoin-Qt.app
+Once dependencies are compiled, see [doc/release-process.md](release-process.md) for how the Bitcoin-Qt.app
bundle is packaged and signed to create the .dmg disk image that is distributed.
Running
------------|------------------|----------------------
libssl | SSL Support | Secure communications
libboost | Boost | C++ Library
- libgmp | secp256k1 | Arbitrary-precision arithmetic (version >= 3.1)
Optional dependencies:
----------------------------------------------
Build requirements:
- sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev libgmp-dev
+ sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev
for Ubuntu 12.04 and later or Debian 7 and later libboost-all-dev has to be installed:
For Qt 5 you need the following:
- sudo apt-get install libqt5gui5 libqt5core5 libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler
+ sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler
libqrencode (optional) can be installed with:
# Build the library and install to our prefix
cd db-4.8.30.NC/build_unix/
-# Note: Do a static build so that it can be embedded into the exectuable, instead of having to find a .so at runtime
+# Note: Do a static build so that it can be embedded into the executable, instead of having to find a .so at runtime
../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX
make install
* Position Independent Executable
Build position independent code to take advantage of Address Space Layout Randomization
offered by some kernels. An attacker who is able to cause execution of code at an arbitrary
- memory location is thwarted if he doesn't know where anything useful is located.
+ memory location is thwarted if he or she doesn't know where anything useful is located.
The stack and heap are randomly located by default but this allows the code section to be
randomly located as well.
+++ /dev/null
-Coding
-====================
-
-Various coding styles have been used during the history of the codebase,
-and the result is not very consistent. However, we're now trying to converge to
-a single style, so please use it in new code. Old code will be converted
-gradually.
-- Basic rules specified in src/.clang-format. Use a recent clang-format-3.5 to format automatically.
- - Braces on new lines for namespaces, classes, functions, methods.
- - Braces on the same line for everything else.
- - 4 space indentation (no tabs) for every block except namespaces.
- - No indentation for public/protected/private or for namespaces.
- - No extra spaces inside parenthesis; don't do ( this )
- - No space after function names; one space after if, for and while.
-
-Block style example:
-```c++
-namespace foo
-{
-class Class
-{
- bool Function(char* psz, int n)
- {
- // Comment summarising what this section of code does
- for (int i = 0; i < n; i++) {
- // When something fails, return early
- if (!Something())
- return false;
- ...
- }
-
- // Success return is usually at the end
- return true;
- }
-}
-}
-```
-
-Doxygen comments
------------------
-
-To facilitate the generation of documentation, use doxygen-compatible comment blocks for functions, methods and fields.
-
-For example, to describe a function use:
-```c++
-/**
- * ... text ...
- * @param[in] arg1 A description
- * @param[in] arg2 Another argument description
- * @pre Precondition for function...
- */
-bool function(int arg1, const char *arg2)
-```
-A complete list of `@xxx` commands can be found at http://www.stack.nl/~dimitri/doxygen/manual/commands.html.
-As Doxygen recognizes the comments by the delimiters (`/**` and `*/` in this case), you don't
-*need* to provide any commands for a comment to be valid, just a description text is fine.
-
-To describe a class use the same construct above the class definition:
-```c++
-/**
- * Alerts are for notifying old versions if they become too obsolete and
- * need to upgrade. The message is displayed in the status bar.
- * @see GetWarnings()
- */
-class CAlert
-{
-```
-
-To describe a member or variable use:
-```c++
-int var; //!< Detailed description after the member
-```
-
-Also OK:
-```c++
-///
-/// ... text ...
-///
-bool function2(int arg1, const char *arg2)
-```
-
-Not OK (used plenty in the current source, but not picked up):
-```c++
-//
-// ... text ...
-//
-```
-
-A full list of comment syntaxes picked up by doxygen can be found at http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html,
-but if possible use one of the above styles.
-
-Locking/mutex usage notes
--------------------------
-
-The code is multi-threaded, and uses mutexes and the
-LOCK/TRY_LOCK macros to protect data structures.
-
-Deadlocks due to inconsistent lock ordering (thread 1 locks cs_main
-and then cs_wallet, while thread 2 locks them in the opposite order:
-result, deadlock as each waits for the other to release its lock) are
-a problem. Compile with -DDEBUG_LOCKORDER to get lock order
-inconsistencies reported in the debug.log file.
-
-Re-architecting the core code so there are better-defined interfaces
-between the various components is a goal, with any necessary locking
-done by the components (e.g. see the self-contained CKeyStore class
-and its cs_KeyStore lock for example).
-
-Threads
--------
-
-- ThreadScriptCheck : Verifies block scripts.
-
-- ThreadImport : Loads blocks from blk*.dat files or bootstrap.dat.
-
-- StartNode : Starts other threads.
-
-- ThreadDNSAddressSeed : Loads addresses of peers from the DNS.
-
-- ThreadMapPort : Universal plug-and-play startup/shutdown
-
-- ThreadSocketHandler : Sends/Receives data from peers on port 8333.
-
-- ThreadOpenAddedConnections : Opens network connections to added nodes.
-
-- ThreadOpenConnections : Initiates new connections to peers.
-
-- ThreadMessageHandler : Higher-level message handling (sending and receiving).
-
-- DumpAddresses : Dumps IP addresses of nodes to peers.dat.
-
-- ThreadFlushWalletDB : Close the wallet.dat file if it hasn't been used in 500ms.
-
-- ThreadRPCServer : Remote procedure call handler, listens on port 8332 for connections and services them.
-
-- BitcoinMiner : Generates bitcoins (if wallet is enabled).
-
-- Shutdown : Does an orderly shutdown of everything.
--- /dev/null
+Coding
+====================
+
+Various coding styles have been used during the history of the codebase,
+and the result is not very consistent. However, we're now trying to converge to
+a single style, so please use it in new code. Old code will be converted
+gradually.
+- Basic rules specified in src/.clang-format. Use a recent clang-format-3.5 to format automatically.
+ - Braces on new lines for namespaces, classes, functions, methods.
+ - Braces on the same line for everything else.
+ - 4 space indentation (no tabs) for every block except namespaces.
+ - No indentation for public/protected/private or for namespaces.
+ - No extra spaces inside parenthesis; don't do ( this )
+ - No space after function names; one space after if, for and while.
+
+Block style example:
+```c++
+namespace foo
+{
+class Class
+{
+ bool Function(char* psz, int n)
+ {
+ // Comment summarising what this section of code does
+ for (int i = 0; i < n; i++) {
+ // When something fails, return early
+ if (!Something())
+ return false;
+ ...
+ }
+
+ // Success return is usually at the end
+ return true;
+ }
+}
+}
+```
+
+Doxygen comments
+-----------------
+
+To facilitate the generation of documentation, use doxygen-compatible comment blocks for functions, methods and fields.
+
+For example, to describe a function use:
+```c++
+/**
+ * ... text ...
+ * @param[in] arg1 A description
+ * @param[in] arg2 Another argument description
+ * @pre Precondition for function...
+ */
+bool function(int arg1, const char *arg2)
+```
+A complete list of `@xxx` commands can be found at http://www.stack.nl/~dimitri/doxygen/manual/commands.html.
+As Doxygen recognizes the comments by the delimiters (`/**` and `*/` in this case), you don't
+*need* to provide any commands for a comment to be valid, just a description text is fine.
+
+To describe a class use the same construct above the class definition:
+```c++
+/**
+ * Alerts are for notifying old versions if they become too obsolete and
+ * need to upgrade. The message is displayed in the status bar.
+ * @see GetWarnings()
+ */
+class CAlert
+{
+```
+
+To describe a member or variable use:
+```c++
+int var; //!< Detailed description after the member
+```
+
+Also OK:
+```c++
+///
+/// ... text ...
+///
+bool function2(int arg1, const char *arg2)
+```
+
+Not OK (used plenty in the current source, but not picked up):
+```c++
+//
+// ... text ...
+//
+```
+
+A full list of comment syntaxes picked up by doxygen can be found at http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html,
+but if possible use one of the above styles.
+
+Development tips and tricks
+---------------------------
+
+**compiling for debugging**
+
+Run configure with the --enable-debug option, then make. Or run configure with
+CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need.
+
+**debug.log**
+
+If the code is behaving strangely, take a look in the debug.log file in the data directory;
+error and debugging messages are written there.
+
+The -debug=... command-line option controls debugging; running with just -debug will turn
+on all categories (and give you a very large debug.log file).
+
+The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt
+to see it.
+
+**testnet and regtest modes**
+
+Run with the -testnet option to run with "play bitcoins" on the test network, if you
+are testing multi-machine code that needs to operate across the internet.
+
+If you are testing something that can run on one machine, run with the -regtest option.
+In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests
+that run in -regtest mode.
+
+**DEBUG_LOCKORDER**
+
+Bitcoin Core is a multithreaded application, and deadlocks or other multithreading bugs
+can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure
+CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of which locks
+are held, and adds warnings to the debug.log file if inconsistencies are detected.
+
+Locking/mutex usage notes
+-------------------------
+
+The code is multi-threaded, and uses mutexes and the
+LOCK/TRY_LOCK macros to protect data structures.
+
+Deadlocks due to inconsistent lock ordering (thread 1 locks cs_main
+and then cs_wallet, while thread 2 locks them in the opposite order:
+result, deadlock as each waits for the other to release its lock) are
+a problem. Compile with -DDEBUG_LOCKORDER to get lock order
+inconsistencies reported in the debug.log file.
+
+Re-architecting the core code so there are better-defined interfaces
+between the various components is a goal, with any necessary locking
+done by the components (e.g. see the self-contained CKeyStore class
+and its cs_KeyStore lock for example).
+
+Threads
+-------
+
+- ThreadScriptCheck : Verifies block scripts.
+
+- ThreadImport : Loads blocks from blk*.dat files or bootstrap.dat.
+
+- StartNode : Starts other threads.
+
+- ThreadDNSAddressSeed : Loads addresses of peers from the DNS.
+
+- ThreadMapPort : Universal plug-and-play startup/shutdown
+
+- ThreadSocketHandler : Sends/Receives data from peers on port 8333.
+
+- ThreadOpenAddedConnections : Opens network connections to added nodes.
+
+- ThreadOpenConnections : Initiates new connections to peers.
+
+- ThreadMessageHandler : Higher-level message handling (sending and receiving).
+
+- DumpAddresses : Dumps IP addresses of nodes to peers.dat.
+
+- ThreadFlushWalletDB : Close the wallet.dat file if it hasn't been used in 500ms.
+
+- ThreadRPCServer : Remote procedure call handler, listens on port 8332 for connections and services them.
+
+- BitcoinMiner : Generates bitcoins (if wallet is enabled).
+
+- Shutdown : Does an orderly shutdown of everything.
+
+Pull Request Terminology
+------------------------
+
+Concept ACK - Agree with the idea and overall direction, but haven't reviewed the code changes or tested them.
+
+utACK (untested ACK) - Reviewed and agree with the code changes but haven't actually tested them.
+
+Tested ACK - Reviewed the code changes and have verified the functionality or bug fix.
+
+ACK - A loose ACK can be confusing. It's best to avoid them unless it's a documentation/comment only change in which case there is nothing to test/verify; therefore the tested/untested distinction is not there.
+
+NACK - Disagree with the code changes/concept. Should be accompanied by an explanation.
- [Connecting to the VM](#connecting-to-the-vm)
- [Setting up Debian for gitian building](#setting-up-debian-for-gitian-building)
- [Installing gitian](#installing-gitian)
-- [Setting up gitian images](#setting-up-gitian-images)
+- [Setting up the gitian image](#setting-up-the-gitian-image)
- [Getting and building the inputs](#getting-and-building-the-inputs)
- [Building Bitcoin](#building-bitcoin)
- [Building an alternative repository](#building-an-alternative-repository)
- Disk size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side
- Push the `Create` button
-Get the [Debian 7.4 net installer](http://ftp.at.debian.org/debian-jigdo/current/amd64/iso-cd/debian-7.4.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)).
+Get the [Debian 7.7 net installer](http://cdimage.debian.org/debian-cd/7.7.0/amd64/iso-cd/debian-7.7.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)).
This DVD image can be validated using a SHA256 hashing tool, for example on
Unixy OSes by entering the following in a terminal:
- echo "b712a141bc60269db217d3b3e456179bd6b181645f90e4aac9c42ed63de492e9 debian-7.4.0-amd64-netinst.iso" | sha256sum -c
+ echo "d440e85b4121f94608748139f25dbce1ad36771348b002fe07d4d44b9d9e623f debian-7.7.0-amd64-netinst.iso" | sha256sum -c
# (must return OK)
After creating the VM, we need to configure it.
-- Click the `Settings` button, then go to the `Network` tab. Adapter 1 should be attacked to `NAT`.
+- Click the `Settings` button, then go to the `Network` tab. Adapter 1 should be attached to `NAT`.
![](gitian-building/network_settings.png)
Installing Debian
------------------
-In this section it will be explained how to install Debian on the newly created VM.
+This section will explain how to install Debian on the newly created VM.
- Choose the non-graphical installer. We do not need the graphical environment, it will only increase installation time and disk usage.
**Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*.
-Clone the git repositories for bitcoin and gitian and then checkout the bitcoin version that you want to build.
+Clone the git repositories for bitcoin and gitian.
```bash
git clone https://github.com/devrandom/gitian-builder.git
git clone https://github.com/bitcoin/bitcoin
-cd bitcoin
-git checkout v${VERSION}
-cd ..
```
-Setting up gitian images
+Setting up the gitian image
-------------------------
-Gitian needs virtual images of the operating system to build in.
-Currently this is Ubuntu Precise for both x86 architectures.
-These images will be copied and used every time that a build is started to
+Gitian needs a virtual image of the operating system to build in.
+Currently this is Ubuntu Precise x86_64.
+This image will be copied and used every time that a build is started to
make sure that the build is deterministic.
-Creating the images will take a while, but only has to be done once.
+Creating the image will take a while, but only has to be done once.
Execute the following as user `debian`:
```bash
cd gitian-builder
-bin/make-base-vm --lxc --arch i386 --suite precise
bin/make-base-vm --lxc --arch amd64 --suite precise
```
-There will be a lot of warnings printed during build of the images. These can be ignored.
+There will be a lot of warnings printed during build of the image. These can be ignored.
**Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*.
Getting and building the inputs
--------------------------------
-In [doc/release-process.md](release-process.md) in the bitcoin repository under 'Fetch and build inputs'.
-you will find a list of `wget` commands that can be executed to get the dependencies.
+Follow the instructions in [doc/release-process.md](release-process.md) in the bitcoin repository
+under 'Fetch and build inputs' to install sources which require manual intervention. Also follow
+the next step: 'Seed the Gitian sources cache', which will fetch all necessary source files allowing
+for gitian to work offline.
-I needed to add `--no-check-certificate` to the OpenSSL wget line to make it work.
-Likely this is because the ca-certificates in Debian 7.4 is fairly old. This does not create a
-security issue as the gitian descriptors check the integrity of the input archives and refuse to work
-if any one is corrupted.
+Building Bitcoin
+----------------
-After downloading the archives, execute the `gbuild` commands to build the dependencies.
-This can take a long time, but only has to be done when the dependencies change, for example
-to upgrade the used version.
+To build Bitcoin (for Linux, OSX and Windows) just follow the steps under 'perform
+gitian builds' in [doc/release-process.md](release-process.md) in the bitcoin repository.
-**Note**: Do not forget to copy the result from `build/out` to `inputs` after every gbuild command! This will save
-you a lot of time.
+This may take a long time as it also builds the dependencies needed for each descriptor.
+These dependencies will be cached after a successful build to avoid rebuilding them where possible.
At any time you can check the package installation and build progress with
tail -f var/build.log
```
-Building Bitcoin
-----------------
-
-To build Bitcoin (for Linux, OSX and Windows) just follow the steps under 'perform
-gitian builds' in [doc/release-process.md](release-process.md) in the bitcoin repository.
-
Output from `gbuild` will look something like
Initialized empty Git repository in /home/debian/gitian-builder/inputs/bitcoin/.git/
Resolving deltas: 100% (25724/25724), done.
From https://github.com/bitcoin/bitcoin
... (new tags, new branch etc)
- --- Building for precise i386 ---
+ --- Building for precise x86_64 ---
Stopping target if it is up
Making a new image copy
stdin: is not a tty
lxc-start: Connection refused - inotify event with no name (mask 32768)
Running build script (log in var/build.log)
-As when building the dependencies, the progress of package installation and building
-can be inspected in `var/install.log` and `var/build.log`.
-
Building an alternative repository
-----------------------------------
in `gitian.sigs` to your signing machine and do
```bash
- gpg --detach-sign ${VERSION}-linux/${SIGNER}/bitcoin-build.assert
- gpg --detach-sign ${VERSION}-win/${SIGNER}/bitcoin-build.assert
- gpg --detach-sign ${VERSION}-osx/${SIGNER}/bitcoin-build.assert
+ gpg --detach-sign ${VERSION}-linux/${SIGNER}/bitcoin-linux-build.assert
+ gpg --detach-sign ${VERSION}-win/${SIGNER}/bitcoin-win-build.assert
+ gpg --detach-sign ${VERSION}-osx-unsigned/${SIGNER}/bitcoin-osx-build.assert
```
This will create the `.sig` files that can be committed together with the `.assert` files to assert your
contrib/init/bitcoind.openrc: OpenRC compatible SysV style init script
contrib/init/bitcoind.openrcconf: OpenRC conf.d file
contrib/init/bitcoind.conf: Upstart service configuration file
+ contrib/init/bitcoind.init: CentOS compatible SysV style init script
1. Service User
---------------------------------
Data directory: /var/lib/bitcoind
PID file: /var/run/bitcoind/bitcoind.pid (OpenRC and Upstart)
/var/lib/bitcoind/bitcoind.pid (systemd)
+Lock file: /var/lock/subsys/bitcoind (CentOS)
The configuration file, PID directory (if applicable) and data directory
should all be owned by the bitcoin user and group. It is advised for security
it will automatically start on reboot.
NOTE: This script is incompatible with CentOS 5 and Amazon Linux 2014 as they
-use old versions of Upstart and do not supply the start-stop-daemon uitility.
+use old versions of Upstart and do not supply the start-stop-daemon utility.
+
+4d) CentOS
+
+Copy bitcoind.init to /etc/init.d/bitcoind. Test by running "service bitcoind start".
+
+Using this script, you can adjust the path and flags to the bitcoind program by
+setting the BITCOIND and FLAGS environment variables in the file
+/etc/sysconfig/bitcoind. You can also use the DAEMONOPTS environment variable here.
5. Auto-respawn
-----------------------------------
(note: this is a temporary file, to be added-to by anybody, and moved to
release-notes at release time)
-Block file backwards-compatibility warning
-===========================================
-
-Because release 0.10.0 makes use of headers-first synchronization and parallel
-block download, the block files and databases are not backwards-compatible
-with older versions of Bitcoin Core:
-
-* Blocks will be stored on disk out of order (in the order they are
-received, really), which makes it incompatible with some tools or
-other programs. Reindexing using earlier versions will also not work
-anymore as a result of this.
-
-* The block index database will now hold headers for which no block is
-stored on disk, which earlier versions won't support.
-
-If you want to be able to downgrade smoothly, make a backup of your entire data
-directory. Without this your node will need start syncing (or importing from
-bootstrap.dat) anew afterwards.
-
-This does not affect wallet forward or backward compatibility.
-
-Transaction fee changes
-=======================
-
-This release automatically estimates how high a transaction fee (or how
-high a priority) transactions require to be confirmed quickly. The default
-settings will create transactions that confirm quickly; see the new
-'txconfirmtarget' setting to control the tradeoff between fees and
-confirmation times.
-
-Prior releases used hard-coded fees (and priorities), and would
-sometimes create transactions that took a very long time to confirm.
-
-Statistics used to estimate fees and priorities are saved in the
-data directory in the `fee_estimates.dat` file just before
-program shutdown, and are read in at startup.
-
-New Command Line Options
----------------------------
-
-- `-txconfirmtarget=n` : create transactions that have enough fees (or priority)
-so they are likely to confirm within n blocks (default: 1). This setting
-is over-ridden by the -paytxfee option.
-
-New RPC methods
-----------------
-
-- `estimatefee nblocks` : Returns approximate fee-per-1,000-bytes needed for
-a transaction to be confirmed within nblocks. Returns -1 if not enough
-transactions have been observed to compute a good estimate.
-
-- `estimatepriority nblocks` : Returns approximate priority needed for
-a zero-fee transaction to confirm within nblocks. Returns -1 if not
-enough free transactions have been observed to compute a good
-estimate.
-
-RPC access control changes
-==========================================
-
-Subnet matching for the purpose of access control is now done
-by matching the binary network address, instead of with string wildcard matching.
-For the user this means that `-rpcallowip` takes a subnet specification, which can be
-
-- a single IP address (e.g. `1.2.3.4` or `fe80::0012:3456:789a:bcde`)
-- a network/CIDR (e.g. `1.2.3.0/24` or `fe80::0000/64`)
-- a network/netmask (e.g. `1.2.3.4/255.255.255.0` or `fe80::0012:3456:789a:bcde/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff`)
-
-An arbitrary number of `-rpcallow` arguments can be given. An incoming connection will be accepted if its origin address
-matches one of them.
-
-For example:
-
-| 0.9.x and before | 0.10.x |
-|--------------------------------------------|---------------------------------------|
-| `-rpcallowip=192.168.1.1` | `-rpcallowip=192.168.1.1` (unchanged) |
-| `-rpcallowip=192.168.1.*` | `-rpcallowip=192.168.1.0/24` |
-| `-rpcallowip=192.168.*` | `-rpcallowip=192.168.0.0/16` |
-| `-rpcallowip=*` (dangerous!) | `-rpcallowip=::/0` |
-
-Using wildcards will result in the rule being rejected with the following error in debug.log:
-
- Error: Invalid -rpcallowip subnet specification: *. Valid 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).
-
-RPC Server "Warm-Up" Mode
-=========================
-
-The RPC server is started earlier now, before most of the expensive
-intialisations like loading the block index. It is available now almost
-immediately after starting the process. However, until all initialisations
-are done, it always returns an immediate error with code -28 to all calls.
-
-This new behaviour can be useful for clients to know that a server is already
-started and will be available soon (for instance, so that they do not
-have to start it themselves).
###fetch and build inputs: (first time, or when dependency versions change)
- mkdir -p inputs; cd inputs/
+ mkdir -p inputs
Register and download the Apple SDK: (see OSX Readme for details)
- https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6.3/xcode4630916281a.dmg
+ https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_6.1.1/xcode_6.1.1.dmg
- Using a Mac, create a tarball for the 10.7 SDK and copy it to the inputs directory:
+ Using a Mac, create a tarball for the 10.9 SDK and copy it to the inputs directory:
- tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.7.sdk.tar.gz MacOSX10.7.sdk
+ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.9.sdk.tar.gz MacOSX10.9.sdk
- Build Bitcoin Core for Linux, Windows, and OS X:
+###Optional: Seed the Gitian sources cache
+
+ By default, gitian will fetch source files as needed. For offline builds, they can be fetched ahead of time:
+
+ make -C ../bitcoin/depends download SOURCES_PATH=`pwd`/cache/common
+
+ Only missing files will be fetched, so this is safe to re-run for each build.
+
+###Build Bitcoin Core for Linux, Windows, and OS X:
./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
- pushd build/out
- zip -r bitcoin-${VERSION}-linux-gitian.zip *
- mv bitcoin-${VERSION}-linux-gitian.zip ../../../
- popd
+ mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../
./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml
./bin/gsign --signer $SIGNER --release ${VERSION}-win --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml
- pushd build/out
- 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.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
+ mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../
+ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
+ ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
+ mv build/out/bitcoin-*-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz
+ mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../
popd
-
Build output expected:
- 1. linux 32-bit and 64-bit binaries + source (bitcoin-${VERSION}-linux-gitian.zip)
- 2. windows 32-bit and 64-bit binaries + installer + source (bitcoin-${VERSION}-win-gitian.zip)
- 3. OSX installer (Bitcoin-Qt.dmg)
- 4. Gitian signatures (in gitian.sigs/${VERSION}-<linux|win|osx>/(your gitian key)/
-
-repackage gitian builds for release as stand-alone zip/tar/installer exe
-
-**Linux .tar.gz:**
+ 1. source tarball (bitcoin-${VERSION}.tar.gz)
+ 2. linux 32-bit and 64-bit binaries dist tarballs (bitcoin-${VERSION}-linux[32|64].tar.gz)
+ 3. windows 32-bit and 64-bit installers and dist zips (bitcoin-${VERSION}-win[32|64]-setup.exe, bitcoin-${VERSION}-win[32|64].zip)
+ 4. OSX unsigned installer (bitcoin-${VERSION}-osx-unsigned.dmg)
+ 5. Gitian signatures (in gitian.sigs/${VERSION}-<linux|win|osx-unsigned>/(your gitian key)/
- unzip bitcoin-${VERSION}-linux-gitian.zip -d bitcoin-${VERSION}-linux
- tar czvf bitcoin-${VERSION}-linux.tar.gz bitcoin-${VERSION}-linux
- rm -rf bitcoin-${VERSION}-linux
+###Next steps:
-**Windows .zip and setup.exe:**
+Commit your signature to gitian.sigs:
- unzip bitcoin-${VERSION}-win-gitian.zip -d bitcoin-${VERSION}-win
- mv bitcoin-${VERSION}-win/bitcoin-*-setup.exe .
- zip -r bitcoin-${VERSION}-win.zip bitcoin-${VERSION}-win
- rm -rf bitcoin-${VERSION}-win
+ pushd gitian.sigs
+ git add ${VERSION}-linux/${SIGNER}
+ git add ${VERSION}-win/${SIGNER}
+ git add ${VERSION}-osx-unsigned/${SIGNER}
+ git commit -a
+ git push # Assuming you can push to the gitian.sigs tree
+ popd
-**Mac OS X .dmg:**
+ Wait for OSX detached signature:
+ Once the OSX build has 3 matching signatures, Gavin will sign it with the apple App-Store key.
+ He will then upload a detached signature to be combined with the unsigned app to create a signed binary.
- mv Bitcoin-Qt.dmg bitcoin-${VERSION}-osx.dmg
+ Create the signed OSX binary:
-###Next steps:
+ pushd ./gitian-builder
+ # Fetch the signature as instructed by Gavin
+ cp signature.tar.gz inputs/
+ ./bin/gbuild -i ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml
+ ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml
+ mv build/out/bitcoin-osx-signed.dmg ../bitcoin-${VERSION}-osx.dmg
+ popd
-Commit your signature to gitian.sigs:
+Commit your signature for the signed OSX binary:
pushd gitian.sigs
- git add ${VERSION}-linux/${SIGNER}
- git add ${VERSION}-win/${SIGNER}
- git add ${VERSION}-osx/${SIGNER}
+ git add ${VERSION}-osx-signed/${SIGNER}
git commit -a
git push # Assuming you can push to the gitian.sigs tree
popd
- Code-sign Windows -setup.exe (in a Windows virtual machine using signtool)
- - Code-sign MacOSX .dmg
-
Note: only Gavin has the code-signing keys currently.
- Create `SHA256SUMS.asc` for the builds, and GPG-sign it:
rm SHA256SUMS
```
(the digest algorithm is forced to sha256 to avoid confusion of the `Hash:` header that GPG adds with the SHA256 used for the files)
+Note: check that SHA256SUMS itself doesn't end up in SHA256SUMS, which is a spurious/nonsensical entry.
- Upload zips and installers, as well as `SHA256SUMS.asc` from last step, to the bitcoin.org server
Translations
============
-The Bitcoin Core GUI can be easily translated into other languages. Here's how we
-handle those translations.
+The Bitcoin-Core project has been designed to support multiple localisations. This makes adding new phrases, and completely new languages easily achievable. For managing all application translations, Bitcoin-Core makes use of the Transifex online translation management tool.
-Files and Folders
------------------
+### Helping to translate (using Transifex)
+Transifex is setup to monitor the Github repo for updates, and when code containing new translations is found, Transifex will process any changes. It may take several hours after a pull-request has been merged, to appear in the Transifex web interface.
-### bitcoin-qt.pro
+Multiple language support is critical in assisting Bitcoin’s global adoption, and growth. One of Bitcoin’s greatest strengths is cross-boarder money transfers, any help making that easier is greatly appreciated.
-This file takes care of generating `.qm` files from `.ts` files. It is mostly
-automated.
+See the [Transifex Bitcoin project](https://www.transifex.com/projects/p/bitcoin/) to assist in translations. You should also join the translation mailing list for announcements - see details below.
-### src/qt/bitcoin.qrc
+### Writing code with translations
+We use automated scripts to help extract translations in both Qt, and non-Qt source files. It is rarely necessary to manually edit the files in `src/qt/locale/`. The translation source files must adhere to the following format:
+`bitcoin_xx_YY.ts or bitcoin_xx.ts`
-This file must be updated whenever a new translation is added. Please note that
-files must end with `.qm`, not `.ts`.
+`src/qt/locale/bitcoin_en.ts` is treated in a special way. It is used as the source for all other translations. Whenever a string in the source code is changed, this file must be updated to reflect those changes. A custom script is used to extract strings from the non-Qt parts. This script makes use of `gettext`, so make sure that utility is installed (ie, `apt-get install gettext` on Ubuntu/Debian). Once this has been updated, `lupdate` (included in the Qt SDK) is used to update `bitcoin_en.ts`.
-```xml
-<qresource prefix="/translations">
- <file alias="en">locale/bitcoin_en.qm</file>
- ...
-</qresource>
+To automatically regenerate the `bitcoin_en.ts` file, run the following commands:
+```sh
+cd src/
+make translate
```
-### src/qt/locale/
+`contrib/bitcoin-qt.pro` takes care of generating `.qm` (binary compiled) files from `.ts` (source files) files. It’s mostly automated, and you shouldn’t need to worry about it.
-This directory contains all translations. Filenames must adhere to this format:
+**Example Qt translation**
+```cpp
+QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
+```
- bitcoin_xx_YY.ts or bitcoin_xx.ts
+### Creating a pull-request
+For general PRs, you shouldn’t include any updates to the translation source files. They will be updated periodically, primarily around pre-releases, allowing time for any new phrases to be translated before public releases. This is also important in avoiding translation related merge conflicts.
-#### bitcoin_en.ts (Source file)
+When an updated source file is merged into the Github repo, Transifex will automatically detect it (although it can take several hours). Once processed, the new strings will show up as "Remaining" in the Transifex web interface and are ready for translators.
-`src/qt/locale/bitcoin_en.ts` is treated in a special way. It is used as the
-source for all other translations. Whenever a string in the code is changed
-this file must be updated to reflect those changes. A custom script is used
-to extract strings from the non-Qt parts. This script makes use of `gettext`,
-so make sure that utility is installed (ie, `apt-get install gettext` on
-Ubuntu/Debian). Once this has been updated, lupdate (included in the Qt SDK)
-is used to update bitcoin_en.ts. This process has been automated, from src/qt,
-simply run:
- make translate
-
-##### Handling of plurals in the source file
+To create the pull-request, use the following commands:
+```
+git add src/qt/bitcoinstrings.cpp src/qt/locale/bitcoin_en.ts
+git commit
+```
-When new plurals are added to the source file, it's important to do the following steps:
+### Creating a Transifex account
+Visit the [Transifex Signup](https://www.transifex.com/signup/) page to create an account. Take note of your username and password, as they will be required to configure the command-line tool.
-1. Open bitcoin_en.ts in Qt Linguist (also included in the Qt SDK)
-2. Search for `%n`, which will take you to the parts in the translation that use plurals
-3. Look for empty `English Translation (Singular)` and `English Translation (Plural)` fields
-4. Add the appropriate strings for the singular and plural form of the base string
-5. Mark the item as done (via the green arrow symbol in the toolbar)
-6. Repeat from step 2. until all singular and plural forms are in the source file
-7. Save the source file
+You can find the Bitcoin translation project at [https://www.transifex.com/projects/p/bitcoin/](https://www.transifex.com/projects/p/bitcoin/).
-##### Creating the pull-request
+### Installing the Transifex client command-line tool
+The client it used to fetch updated translations. If you are having problems, or need more details, see [http://docs.transifex.com/developer/client/setup](http://docs.transifex.com/developer/client/setup)
-An updated source file should be merged to github and Transifex will pick it
-up from there (can take some hours). Afterwards the new strings show up as "Remaining"
-in Transifex and can be translated.
+**For Linux and Mac**
-To create the pull-request you have to do:
+`pip install transifex-client`
- git add src/qt/bitcoinstrings.cpp src/qt/locale/bitcoin_en.ts
- git commit
+Setup your transifex client config as follows. Please *ignore the token field*.
-Syncing with Transifex
-----------------------
+```ini
+nano ~/.transifexrc
-We are using https://transifex.com as a frontend for translating the client.
+[https://www.transifex.com]
+hostname = https://www.transifex.com
+password = PASSWORD
+token =
+username = USERNAME
+```
-https://www.transifex.com/projects/p/bitcoin/resource/tx/
+**For Windows**
-The "Transifex client" (see: http://support.transifex.com/customer/portal/topics/440187-transifex-client/articles)
-is used to fetch new translations from Transifex. The configuration for this client (`.tx/config`)
-is part of the repository.
+Please see [http://docs.transifex.com/developer/client/setup#windows](http://docs.transifex.com/developer/client/setup#windows) for details on installation.
-Do not directly download translations one by one from the Transifex website, as we do a few
-postprocessing steps before committing the translations.
+The Transifex Bitcoin project config file is included as part of the repo. It can be found at `.tx/config`, however you shouldn’t need change anything.
-### Fetching new translations
+### Synchronising translations
+To assist in updating translations, we have created a script to help.
1. `python contrib/devtools/update-translations.py`
-2. update `src/qt/bitcoin.qrc` manually or via
+2. Update `src/qt/bitcoin.qrc` manually or via
`ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/<file alias="\2">locale\/\1.qm<\/file>/'`
-3. update `src/qt/Makefile.am` manually or via
+3. Update `src/qt/Makefile.am` manually or via
`ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/ locale\/\1.ts \\/'`
4. `git add` new translations from `src/qt/locale/`
+
+**Do not directly download translations** one by one from the Transifex website, as we do a few post-processing steps before committing the translations.
+
+### Handling Plurals (in source files)
+When new plurals are added to the source file, it's important to do the following steps:
+
+1. Open `bitcoin_en.ts` in Qt Linguist (included in the Qt SDK)
+2. Search for `%n`, which will take you to the parts in the translation that use plurals
+3. Look for empty `English Translation (Singular)` and `English Translation (Plural)` fields
+4. Add the appropriate strings for the singular and plural form of the base string
+5. Mark the item as done (via the green arrow symbol in the toolbar)
+6. Repeat from step 2, until all singular and plural forms are in the source file
+7. Save the source file
+
+### Translating a new language
+To create a new language template, you will need to edit the languages manifest file `src/qt/bitcoin.qrc` and add a new entry. Below is an example of the english language entry.
+
+```xml
+<qresource prefix="/translations">
+ <file alias="en">locale/bitcoin_en.qm</file>
+ ...
+</qresource>
+```
+
+**Note:** that the language translation file **must end in `.qm`** (the compiled extension), and not `.ts`.
+
+### Questions and general assistance
+The Bitcoin-Core translation maintainers include *tcatm, seone, Diapolo, wumpus and luke-jr*.You can find them, and others, in the Freenode IRC chatroom - `irc.freenode.net #bitcoin-dev`.
+
+If you are a translator, you should also subscribe to the mailing list, https://groups.google.com/forum/#!forum/bitcoin-translators. Announcements will be posted during application pre-releases to notify translators to check for updates.
\ No newline at end of file
.cpp files in the test/ directory or add new .cpp files that
implement new BOOST_AUTO_TEST_SUITE sections.
-To run the bitcoin-qt tests manually, launch src/qt/test/bitcoin-qt_test
+To run the bitcoin-qt tests manually, launch src/qt/test/test_bitcoin-qt
To add more bitcoin-qt tests, add them to the `src/qt/test/` directory and
the `src/qt/test/test_main.cpp` file.
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Bitcoin Core consensus library
+Description: Library for the Bitcoin consensus protocol.
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lbitcoinconsensus
+Cflags: -I${includedir}
+Requires.private: libcrypto
+++ /dev/null
-# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
-# serial 1 (pkg-config-0.24)
-#
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# PKG_PROG_PKG_CONFIG([MIN-VERSION])
-# ----------------------------------
-AC_DEFUN([PKG_PROG_PKG_CONFIG],
-[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
-m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
-m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
-AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
-AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
-AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
-
-if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
- AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
-fi
-if test -n "$PKG_CONFIG"; then
- _pkg_min_version=m4_default([$1], [0.9.0])
- AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
- if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- PKG_CONFIG=""
- fi
-fi[]dnl
-])# PKG_PROG_PKG_CONFIG
-
-# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
-#
-# Check to see whether a particular set of modules exists. Similar
-# to PKG_CHECK_MODULES(), but does not set variables or print errors.
-#
-# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
-# only at the first occurence in configure.ac, so if the first place
-# it's called might be skipped (such as if it is within an "if", you
-# have to call PKG_CHECK_EXISTS manually
-# --------------------------------------------------------------
-AC_DEFUN([PKG_CHECK_EXISTS],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
-if test -n "$PKG_CONFIG" && \
- AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
- m4_default([$2], [:])
-m4_ifvaln([$3], [else
- $3])dnl
-fi])
-
-# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
-# ---------------------------------------------
-m4_define([_PKG_CONFIG],
-[if test -n "$$1"; then
- pkg_cv_[]$1="$$1"
- elif test -n "$PKG_CONFIG"; then
- PKG_CHECK_EXISTS([$3],
- [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
- test "x$?" != "x0" && pkg_failed=yes ],
- [pkg_failed=yes])
- else
- pkg_failed=untried
-fi[]dnl
-])# _PKG_CONFIG
-
-# _PKG_SHORT_ERRORS_SUPPORTED
-# -----------------------------
-AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
- _pkg_short_errors_supported=yes
-else
- _pkg_short_errors_supported=no
-fi[]dnl
-])# _PKG_SHORT_ERRORS_SUPPORTED
-
-
-# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
-# [ACTION-IF-NOT-FOUND])
-#
-#
-# Note that if there is a possibility the first call to
-# PKG_CHECK_MODULES might not happen, you should be sure to include an
-# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
-#
-#
-# --------------------------------------------------------------
-AC_DEFUN([PKG_CHECK_MODULES],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
-AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
-AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
-
-pkg_failed=no
-AC_MSG_CHECKING([for $1])
-
-_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
-_PKG_CONFIG([$1][_LIBS], [libs], [$2])
-
-m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
-and $1[]_LIBS to avoid the need to call pkg-config.
-See the pkg-config man page for more details.])
-
-if test $pkg_failed = yes; then
- AC_MSG_RESULT([no])
- _PKG_SHORT_ERRORS_SUPPORTED
- if test $_pkg_short_errors_supported = yes; then
- $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
- else
- $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
- fi
- # Put the nasty error message in config.log where it belongs
- echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
-
- m4_default([$4], [AC_MSG_ERROR(
-[Package requirements ($2) were not met:
-
-$$1_PKG_ERRORS
-
-Consider adjusting the PKG_CONFIG_PATH environment variable if you
-installed software in a non-standard prefix.
-
-_PKG_TEXT])[]dnl
- ])
-elif test $pkg_failed = untried; then
- AC_MSG_RESULT([no])
- m4_default([$4], [AC_MSG_FAILURE(
-[The pkg-config script could not be found or is too old. Make sure it
-is in your PATH or set the PKG_CONFIG environment variable to the full
-path to pkg-config.
-
-_PKG_TEXT
-
-To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
- ])
-else
- $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
- $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
- AC_MSG_RESULT([yes])
- $3
-fi[]dnl
-])# PKG_CHECK_MODULES
-
-
-# PKG_INSTALLDIR(DIRECTORY)
-# -------------------------
-# Substitutes the variable pkgconfigdir as the location where a module
-# should install pkg-config .pc files. By default the directory is
-# $libdir/pkgconfig, but the default can be changed by passing
-# DIRECTORY. The user can override through the --with-pkgconfigdir
-# parameter.
-AC_DEFUN([PKG_INSTALLDIR],
-[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
-m4_pushdef([pkg_description],
- [pkg-config installation directory @<:@]pkg_default[@:>@])
-AC_ARG_WITH([pkgconfigdir],
- [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
- [with_pkgconfigdir=]pkg_default)
-AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
-m4_popdef([pkg_default])
-m4_popdef([pkg_description])
-]) dnl PKG_INSTALLDIR
-
-
-# PKG_NOARCH_INSTALLDIR(DIRECTORY)
-# -------------------------
-# Substitutes the variable noarch_pkgconfigdir as the location where a
-# module should install arch-independent pkg-config .pc files. By
-# default the directory is $datadir/pkgconfig, but the default can be
-# changed by passing DIRECTORY. The user can override through the
-# --with-noarch-pkgconfigdir parameter.
-AC_DEFUN([PKG_NOARCH_INSTALLDIR],
-[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
-m4_pushdef([pkg_description],
- [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
-AC_ARG_WITH([noarch-pkgconfigdir],
- [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
- [with_noarch_pkgconfigdir=]pkg_default)
-AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
-m4_popdef([pkg_default])
-m4_popdef([pkg_description])
-]) dnl PKG_NOARCH_INSTALLDIR
-
-
-# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
-# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
-# -------------------------------------------
-# Retrieves the value of the pkg-config variable for the given module.
-AC_DEFUN([PKG_CHECK_VAR],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
-AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
-
-_PKG_CONFIG([$1], [variable="][$3]["], [$2])
-AS_VAR_COPY([$1], [pkg_cv_][$1])
-
-AS_VAR_IF([$1], [""], [$5], [$4])dnl
-])# PKG_CHECK_VAR
#Run the tests
+testScripts=(
+ 'wallet.py'
+ 'listtransactions.py'
+ 'mempool_resurrect_test.py'
+ 'txn_doublespend.py'
+ 'txn_doublespend.py --mineblock'
+ 'getchaintips.py'
+ 'rest.py'
+ 'mempool_spendcoinbase.py'
+ 'mempool_coinbase_spends.py'
+ 'httpbasics.py'
+ 'zapwallettxes.py'
+# 'forknotify.py'
+);
if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then
- ${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"
+ for (( i = 0; i < ${#testScripts[@]}; i++ ))
+ do
+ if [ -z "$1" ] || [ "$1" == "${testScripts[$i]}" ] || [ "$1.py" == "${testScripts[$i]}" ]
+ then
+ echo -e "Running testscript \033[1m${testScripts[$i]}...\033[0m"
+ ${BUILDDIR}/qa/rpc-tests/${testScripts[$i]} --srcdir "${BUILDDIR}/src"
+ fi
+ done
else
echo "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled"
fi
tail -q -n 1 -F "$DATADIR/regtest/debug.log" | grep -m 1 -q "Done loading" &
WAITER=$!
PORT=`expr 10000 + $$ % 55536`
-"@abs_top_builddir@/src/bitcoind@EXEEXT@" -connect=0.0.0.0 -datadir="$DATADIR" -rpcuser=user -rpcpassword=pass -listen -keypool=3 -debug -debug=net -logtimestamps -checkmempool=0 -port=$PORT -whitelist=127.0.0.1 -regtest -rpcport=`expr $PORT + 1` &
+"@abs_top_builddir@/src/bitcoind@EXEEXT@" -connect=0.0.0.0 -datadir="$DATADIR" -rpcuser=user -rpcpassword=pass -listen -keypool=3 -debug -debug=net -logtimestamps -checkmempool=0 -relaypriority=0 -port=$PORT -whitelist=127.0.0.1 -regtest -rpcport=`expr $PORT + 1` &
BITCOIND=$!
#Install a watchdog.
### [listtransactions.py](listtransactions.py)
Tests for the listtransactions RPC call.
-### [util.py](util.sh)
+### [util.py](util.py)
Generally useful functions.
Bash-based tests, to be ported to Python:
--- /dev/null
+#!/usr/bin/env python2
+# 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 the BIP66 changeover logic
+#
+
+from test_framework import BitcoinTestFramework
+from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
+from util import *
+import os
+import shutil
+
+class BIP66Test(BitcoinTestFramework):
+
+ def setup_network(self):
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, []))
+ self.nodes.append(start_node(1, self.options.tmpdir, ["-blockversion=2"]))
+ self.nodes.append(start_node(2, self.options.tmpdir, ["-blockversion=3"]))
+ connect_nodes(self.nodes[1], 0)
+ connect_nodes(self.nodes[2], 0)
+ self.is_network_split = False
+ self.sync_all()
+
+ def run_test(self):
+ cnt = self.nodes[0].getblockcount()
+
+ # Mine some old-version blocks
+ self.nodes[1].setgenerate(True, 100)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 100):
+ raise AssertionError("Failed to mine 100 version=2 blocks")
+
+ # Mine 750 new-version blocks
+ for i in xrange(15):
+ self.nodes[2].setgenerate(True, 50)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 850):
+ raise AssertionError("Failed to mine 750 version=3 blocks")
+
+ # TODO: check that new DERSIG rules are not enforced
+
+ # Mine 1 new-version block
+ self.nodes[2].setgenerate(True, 1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 851):
+ raise AssertionFailure("Failed to mine a version=3 blocks")
+
+ # TODO: check that new DERSIG rules are enforced
+
+ # Mine 198 new-version blocks
+ for i in xrange(2):
+ self.nodes[2].setgenerate(True, 99)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1049):
+ raise AssertionError("Failed to mine 198 version=3 blocks")
+
+ # Mine 1 old-version block
+ self.nodes[1].setgenerate(True, 1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1050):
+ raise AssertionError("Failed to mine a version=2 block after 949 version=3 blocks")
+
+ # Mine 1 new-version blocks
+ self.nodes[2].setgenerate(True, 1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1051):
+ raise AssertionError("Failed to mine a version=3 block")
+
+ # Mine 1 old-version blocks
+ try:
+ self.nodes[1].setgenerate(True, 1)
+ raise AssertionError("Succeeded to mine a version=2 block after 950 version=3 blocks")
+ except JSONRPCException:
+ pass
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1051):
+ raise AssertionError("Accepted a version=2 block after 950 version=3 blocks")
+
+ # Mine 1 new-version blocks
+ self.nodes[2].setgenerate(True, 1)
+ self.sync_all()
+ if (self.nodes[0].getblockcount() != cnt + 1052):
+ raise AssertionError("Failed to mine a version=3 block")
+
+if __name__ == '__main__':
+ BIP66Test().main()
-#!/usr/bin/env python
+#!/usr/bin/env python2
# 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.
-#!/usr/bin/env python
+#!/usr/bin/env python2
# 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.
-#!/usr/bin/env python
+#!/usr/bin/env python2
# 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.
def run_test(self):
node = self.nodes[0]
+ node.setgenerate(True, 1) # Mine a block to leave initial block download
tmpl = node.getblocktemplate()
if 'coinbasetxn' not in tmpl:
rawcoinbase = encodeUNum(tmpl['height'])
-#!/usr/bin/env python
+#!/usr/bin/env python2
# 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.
assert_equal (len (tips), 1)
assert_equal (tips[0]['branchlen'], 0)
assert_equal (tips[0]['height'], 200)
+ assert_equal (tips[0]['status'], 'active')
# Split the network and build two chains of different lengths.
self.split_network ()
shortTip = tips[0]
assert_equal (shortTip['branchlen'], 0)
assert_equal (shortTip['height'], 210)
+ assert_equal (tips[0]['status'], 'active')
tips = self.nodes[3].getchaintips ()
assert_equal (len (tips), 1)
longTip = tips[0]
assert_equal (longTip['branchlen'], 0)
assert_equal (longTip['height'], 220)
+ assert_equal (tips[0]['status'], 'active')
# Join the network halves and check that we now have two tips
# (at least at the nodes that previously had the short chain).
assert_equal (tips[0], longTip)
assert_equal (tips[1]['branchlen'], 10)
- tips[1]['branchlen'] = 0;
+ assert_equal (tips[1]['status'], 'valid-fork')
+ tips[1]['branchlen'] = 0
+ tips[1]['status'] = 'active'
assert_equal (tips[1], shortTip)
if __name__ == '__main__':
--- /dev/null
+#!/usr/bin/env python2
+# 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 REST interface
+#
+
+from test_framework import BitcoinTestFramework
+from util import *
+import base64
+
+try:
+ import http.client as httplib
+except ImportError:
+ import httplib
+try:
+ import urllib.parse as urlparse
+except ImportError:
+ import urlparse
+
+class HTTPBasicsTest (BitcoinTestFramework):
+ def setup_nodes(self):
+ return start_nodes(4, self.options.tmpdir, extra_args=[['-rpckeepalive=1'], ['-rpckeepalive=0'], [], []])
+
+ def run_test(self):
+
+ #################################################
+ # lowlevel check for http persistent connection #
+ #################################################
+ url = urlparse.urlparse(self.nodes[0].url)
+ authpair = url.username + ':' + url.password
+ headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
+
+ conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn.connect()
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
+ out1 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True)
+ assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
+
+ #send 2nd request without closing connection
+ conn.request('POST', '/', '{"method": "getchaintips"}', headers)
+ out2 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message
+ assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
+ conn.close()
+
+ #same should be if we add keep-alive because this should be the std. behaviour
+ headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection": "keep-alive"}
+
+ conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn.connect()
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
+ out1 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True)
+ assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
+
+ #send 2nd request without closing connection
+ conn.request('POST', '/', '{"method": "getchaintips"}', headers)
+ out2 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message
+ assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
+ conn.close()
+
+ #now do the same with "Connection: close"
+ headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection":"close"}
+
+ conn = httplib.HTTPConnection(url.hostname, url.port)
+ conn.connect()
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
+ out1 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True)
+ assert_equal(conn.sock!=None, False) #now the connection must be closed after the response
+
+ #node1 (2nd node) is running with disabled keep-alive option
+ urlNode1 = urlparse.urlparse(self.nodes[1].url)
+ authpair = urlNode1.username + ':' + urlNode1.password
+ headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
+
+ conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port)
+ conn.connect()
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
+ out1 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True)
+ assert_equal(conn.sock!=None, False) #connection must be closed because keep-alive was set to false
+
+ #node2 (third node) is running with standard keep-alive parameters which means keep-alive is off
+ urlNode2 = urlparse.urlparse(self.nodes[2].url)
+ authpair = urlNode2.username + ':' + urlNode2.password
+ headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
+
+ conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)
+ conn.connect()
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
+ out1 = conn.getresponse().read();
+ assert_equal('"error":null' in out1, True)
+ assert_equal(conn.sock!=None, True) #connection must be closed because bitcoind should use keep-alive by default
+
+if __name__ == '__main__':
+ HTTPBasicsTest ().main ()
--- /dev/null
+#!/usr/bin/env python2
+# 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 InvalidateBlock code
+#
+
+from test_framework import BitcoinTestFramework
+from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
+from util import *
+
+class InvalidateTest(BitcoinTestFramework):
+
+
+ def setup_chain(self):
+ print("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 2)
+
+ def setup_network(self):
+ self.nodes = []
+ self.is_network_split = False
+ self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"]))
+ self.nodes.append(start_node(1, self.options.tmpdir, ["-debug"]))
+
+ def run_test(self):
+ print "Mine 4 blocks on Node 0"
+ self.nodes[0].setgenerate(True, 4)
+ assert(self.nodes[0].getblockcount() == 4)
+ besthash = self.nodes[0].getbestblockhash()
+
+ print "Mine competing 6 blocks on Node 1"
+ self.nodes[1].setgenerate(True, 6)
+ assert(self.nodes[1].getblockcount() == 6)
+
+ print "Connect nodes to force a reorg"
+ connect_nodes_bi(self.nodes,0,1)
+ sync_blocks(self.nodes)
+ assert(self.nodes[0].getblockcount() == 6)
+ badhash = self.nodes[1].getblockhash(2)
+
+ print "Invalidate block 2 on node 0 and verify we reorg to node 0's original chain"
+ self.nodes[0].invalidateblock(badhash)
+ newheight = self.nodes[0].getblockcount()
+ newhash = self.nodes[0].getbestblockhash()
+ if (newheight != 4 or newhash != besthash):
+ raise AssertionError("Wrong tip for node0, hash %s, height %d"%(newhash,newheight))
+
+if __name__ == '__main__':
+ InvalidateTest().main()
-#!/usr/bin/env python
+#!/usr/bin/env python2
# 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.
-#!/usr/bin/env python
+#!/usr/bin/env python2
# 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.
--- /dev/null
+#!/usr/bin/env python2
+# 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 re-org scenarios with a mempool that contains transactions
+# that spend (directly or indirectly) coinbase transactions.
+#
+
+from test_framework import BitcoinTestFramework
+from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
+from util import *
+import os
+import shutil
+
+# Create one-input, one-output, no-fee transaction:
+class MempoolCoinbaseTest(BitcoinTestFramework):
+
+ alert_filename = None # Set by setup_network
+
+ def setup_network(self):
+ args = ["-checkmempool", "-debug=mempool"]
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, args))
+ self.nodes.append(start_node(1, self.options.tmpdir, args))
+ connect_nodes(self.nodes[1], 0)
+ self.is_network_split = False
+ self.sync_all
+
+ def create_tx(self, from_txid, to_address, amount):
+ inputs = [{ "txid" : from_txid, "vout" : 0}]
+ outputs = { to_address : amount }
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ signresult = self.nodes[0].signrawtransaction(rawtx)
+ assert_equal(signresult["complete"], True)
+ return signresult["hex"]
+
+ def run_test(self):
+ start_count = self.nodes[0].getblockcount()
+
+ # Mine three blocks. After this, nodes[0] blocks
+ # 101, 102, and 103 are spend-able.
+ new_blocks = self.nodes[1].setgenerate(True, 4)
+ self.sync_all()
+
+ node0_address = self.nodes[0].getnewaddress()
+ node1_address = self.nodes[1].getnewaddress()
+
+ # Three scenarios for re-orging coinbase spends in the memory pool:
+ # 1. Direct coinbase spend : spend_101
+ # 2. Indirect (coinbase spend in chain, child in mempool) : spend_102 and spend_102_1
+ # 3. Indirect (coinbase and child both in chain) : spend_103 and spend_103_1
+ # Use invalidatblock to make all of the above coinbase spends invalid (immature coinbase),
+ # and make sure the mempool code behaves correctly.
+ b = [ self.nodes[0].getblockhash(n) for n in range(102, 105) ]
+ coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
+ spend_101_raw = self.create_tx(coinbase_txids[0], node1_address, 50)
+ spend_102_raw = self.create_tx(coinbase_txids[1], node0_address, 50)
+ spend_103_raw = self.create_tx(coinbase_txids[2], node0_address, 50)
+
+ # Broadcast and mine spend_102 and 103:
+ spend_102_id = self.nodes[0].sendrawtransaction(spend_102_raw)
+ spend_103_id = self.nodes[0].sendrawtransaction(spend_103_raw)
+ self.nodes[0].setgenerate(True, 1)
+
+ # Create 102_1 and 103_1:
+ spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 50)
+ spend_103_1_raw = self.create_tx(spend_103_id, node1_address, 50)
+
+ # Broadcast and mine 103_1:
+ spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw)
+ self.nodes[0].setgenerate(True, 1)
+
+ # ... now put spend_101 and spend_102_1 in memory pools:
+ spend_101_id = self.nodes[0].sendrawtransaction(spend_101_raw)
+ spend_102_1_id = self.nodes[0].sendrawtransaction(spend_102_1_raw)
+
+ self.sync_all()
+
+ assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_101_id, spend_102_1_id ]))
+
+ # Use invalidateblock to re-org back and make all those coinbase spends
+ # immature/invalid:
+ for node in self.nodes:
+ node.invalidateblock(new_blocks[0])
+
+ self.sync_all()
+
+ # mempool should be empty.
+ assert_equal(set(self.nodes[0].getrawmempool()), set())
+
+if __name__ == '__main__':
+ MempoolCoinbaseTest().main()
--- /dev/null
+#!/usr/bin/env python2
+# 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 resurrection of mined transactions when
+# the blockchain is re-organized.
+#
+
+from test_framework import BitcoinTestFramework
+from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
+from util import *
+import os
+import shutil
+
+# Create one-input, one-output, no-fee transaction:
+class MempoolCoinbaseTest(BitcoinTestFramework):
+
+ def setup_network(self):
+ # Just need one node for this test
+ args = ["-checkmempool", "-debug=mempool"]
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, args))
+ self.is_network_split = False
+
+ def create_tx(self, from_txid, to_address, amount):
+ inputs = [{ "txid" : from_txid, "vout" : 0}]
+ outputs = { to_address : amount }
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ signresult = self.nodes[0].signrawtransaction(rawtx)
+ assert_equal(signresult["complete"], True)
+ return signresult["hex"]
+
+ def run_test(self):
+ node0_address = self.nodes[0].getnewaddress()
+
+ # Spend block 1/2/3's coinbase transactions
+ # Mine a block.
+ # Create three more transactions, spending the spends
+ # Mine another block.
+ # ... make sure all the transactions are confirmed
+ # Invalidate both blocks
+ # ... make sure all the transactions are put back in the mempool
+ # Mine a new block
+ # ... make sure all the transactions are confirmed again.
+
+ b = [ self.nodes[0].getblockhash(n) for n in range(1, 4) ]
+ coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
+ spends1_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ]
+ spends1_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw ]
+
+ blocks = []
+ blocks.extend(self.nodes[0].setgenerate(True, 1))
+
+ spends2_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in spends1_id ]
+ spends2_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw ]
+
+ blocks.extend(self.nodes[0].setgenerate(True, 1))
+
+ # mempool should be empty, all txns confirmed
+ assert_equal(set(self.nodes[0].getrawmempool()), set())
+ for txid in spends1_id+spends2_id:
+ tx = self.nodes[0].gettransaction(txid)
+ assert(tx["confirmations"] > 0)
+
+ # Use invalidateblock to re-org back; all transactions should
+ # end up unconfirmed and back in the mempool
+ for node in self.nodes:
+ node.invalidateblock(blocks[0])
+
+ # mempool should be empty, all txns confirmed
+ assert_equal(set(self.nodes[0].getrawmempool()), set(spends1_id+spends2_id))
+ for txid in spends1_id+spends2_id:
+ tx = self.nodes[0].gettransaction(txid)
+ assert(tx["confirmations"] == 0)
+
+ # Generate another block, they should all get mined
+ self.nodes[0].setgenerate(True, 1)
+ # mempool should be empty, all txns confirmed
+ assert_equal(set(self.nodes[0].getrawmempool()), set())
+ for txid in spends1_id+spends2_id:
+ tx = self.nodes[0].gettransaction(txid)
+ assert(tx["confirmations"] > 0)
+
+
+if __name__ == '__main__':
+ MempoolCoinbaseTest().main()
--- /dev/null
+#!/usr/bin/env python2
+# 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 spending coinbase transactions.
+# The coinbase transaction in block N can appear in block
+# N+100... so is valid in the mempool when the best block
+# height is N+99.
+# This test makes sure coinbase spends that will be mature
+# in the next block are accepted into the memory pool,
+# but less mature coinbase spends are NOT.
+#
+
+from test_framework import BitcoinTestFramework
+from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
+from util import *
+import os
+import shutil
+
+# Create one-input, one-output, no-fee transaction:
+class MempoolSpendCoinbaseTest(BitcoinTestFramework):
+
+ def setup_network(self):
+ # Just need one node for this test
+ args = ["-checkmempool", "-debug=mempool"]
+ self.nodes = []
+ self.nodes.append(start_node(0, self.options.tmpdir, args))
+ self.is_network_split = False
+
+ def create_tx(self, from_txid, to_address, amount):
+ inputs = [{ "txid" : from_txid, "vout" : 0}]
+ outputs = { to_address : amount }
+ rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
+ signresult = self.nodes[0].signrawtransaction(rawtx)
+ assert_equal(signresult["complete"], True)
+ return signresult["hex"]
+
+ def run_test(self):
+ chain_height = self.nodes[0].getblockcount()
+ assert_equal(chain_height, 200)
+ node0_address = self.nodes[0].getnewaddress()
+
+ # Coinbase at height chain_height-100+1 ok in mempool, should
+ # get mined. Coinbase at height chain_height-100+2 is
+ # is too immature to spend.
+ b = [ self.nodes[0].getblockhash(n) for n in range(101, 103) ]
+ coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
+ spends_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ]
+
+ spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0])
+
+ # coinbase at height 102 should be too immature to spend
+ assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, spends_raw[1])
+
+ # mempool should have just spend_101:
+ assert_equal(self.nodes[0].getrawmempool(), [ spend_101_id ])
+
+ # mine a block, spend_101 should get confirmed
+ self.nodes[0].setgenerate(True, 1)
+ assert_equal(set(self.nodes[0].getrawmempool()), set())
+
+ # ... and now height 102 can be spent:
+ spend_102_id = self.nodes[0].sendrawtransaction(spends_raw[1])
+ assert_equal(self.nodes[0].getrawmempool(), [ spend_102_id ])
+
+if __name__ == '__main__':
+ MempoolSpendCoinbaseTest().main()
-#!/usr/bin/env python
+#!/usr/bin/env python2
# 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.
-#!/usr/bin/env python
+#!/usr/bin/env python2
from distutils.core import setup
-#!/usr/bin/env python
+#!/usr/bin/env python2
# 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.
--- /dev/null
+#!/usr/bin/env python2
+# 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 REST interface
+#
+
+from test_framework import BitcoinTestFramework
+from util import *
+import json
+
+try:
+ import http.client as httplib
+except ImportError:
+ import httplib
+try:
+ import urllib.parse as urlparse
+except ImportError:
+ import urlparse
+
+def http_get_call(host, port, path, response_object = 0):
+ conn = httplib.HTTPConnection(host, port)
+ conn.request('GET', path)
+
+ if response_object:
+ return conn.getresponse()
+
+ return conn.getresponse().read()
+
+
+class RESTTest (BitcoinTestFramework):
+ FORMAT_SEPARATOR = "."
+
+ def run_test(self):
+ url = urlparse.urlparse(self.nodes[0].url)
+ bb_hash = self.nodes[0].getbestblockhash()
+
+ # check binary format
+ response = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+"bin", True)
+ assert_equal(response.status, 200)
+ assert_greater_than(int(response.getheader('content-length')), 80)
+ response_str = response.read()
+
+ # compare with block header
+ response_header = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"bin", True)
+ assert_equal(response_header.status, 200)
+ assert_equal(int(response_header.getheader('content-length')), 80)
+ response_header_str = response_header.read()
+ assert_equal(response_str[0:80], response_header_str)
+
+ # check block hex format
+ response_hex = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+"hex", True)
+ assert_equal(response_hex.status, 200)
+ assert_greater_than(int(response_hex.getheader('content-length')), 160)
+ response_hex_str = response_hex.read()
+ assert_equal(response_str.encode("hex")[0:160], response_hex_str[0:160])
+
+ # compare with hex block header
+ response_header_hex = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"hex", True)
+ assert_equal(response_header_hex.status, 200)
+ assert_greater_than(int(response_header_hex.getheader('content-length')), 160)
+ response_header_hex_str = response_header_hex.read()
+ assert_equal(response_hex_str[0:160], response_header_hex_str[0:160])
+ assert_equal(response_header_str.encode("hex")[0:160], response_header_hex_str[0:160])
+
+ # check json format
+ json_string = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+'json')
+ json_obj = json.loads(json_string)
+ assert_equal(json_obj['hash'], bb_hash)
+
+ # do tx test
+ tx_hash = json_obj['tx'][0]['txid'];
+ json_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"json")
+ json_obj = json.loads(json_string)
+ assert_equal(json_obj['txid'], tx_hash)
+
+ # check hex format response
+ hex_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"hex", True)
+ assert_equal(hex_string.status, 200)
+ assert_greater_than(int(response.getheader('content-length')), 10)
+
+ # check block tx details
+ # let's make 3 tx and mine them on node 1
+ txs = []
+ txs.append(self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11))
+ txs.append(self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11))
+ txs.append(self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11))
+ self.sync_all()
+
+ # now mine the transactions
+ newblockhash = self.nodes[1].setgenerate(True, 1)
+ self.sync_all()
+
+ #check if the 3 tx show up in the new block
+ json_string = http_get_call(url.hostname, url.port, '/rest/block/'+newblockhash[0]+self.FORMAT_SEPARATOR+'json')
+ json_obj = json.loads(json_string)
+ for tx in json_obj['tx']:
+ if not 'coinbase' in tx['vin'][0]: #exclude coinbase
+ assert_equal(tx['txid'] in txs, True)
+
+ #check the same but without tx details
+ json_string = http_get_call(url.hostname, url.port, '/rest/block/notxdetails/'+newblockhash[0]+self.FORMAT_SEPARATOR+'json')
+ json_obj = json.loads(json_string)
+ for tx in txs:
+ assert_equal(tx in json_obj['tx'], True)
+
+ #test rest bestblock
+ bb_hash = self.nodes[0].getbestblockhash()
+
+ json_string = http_get_call(url.hostname, url.port, '/rest/chaininfo.json')
+ json_obj = json.loads(json_string)
+ assert_equal(json_obj['bestblockhash'], bb_hash)
+
+if __name__ == '__main__':
+ RESTTest ().main ()
-#!/usr/bin/env python
+#!/usr/bin/env python2
# 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.
-#!/usr/bin/env python
+#!/usr/bin/env python2
# 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.
def setup_network(self):
self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir,
- ["-debug=mempool", "-debug=estimatefee"]))
+ ["-debug=mempool", "-debug=estimatefee", "-relaypriority=0"]))
# Node1 mines small-but-not-tiny blocks, and allows free transactions.
# NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes,
# so blockmaxsize of 2,000 is really just 1,000 bytes (room enough for
# 6 or 7 transactions)
self.nodes.append(start_node(1, self.options.tmpdir,
["-blockprioritysize=1500", "-blockmaxsize=2000",
- "-debug=mempool", "-debug=estimatefee"]))
+ "-debug=mempool", "-debug=estimatefee", "-relaypriority=0"]))
connect_nodes(self.nodes[1], 0)
# Node2 is a stingy miner, that
# produces very small blocks (room for only 3 or so transactions)
node2args = [ "-blockprioritysize=0", "-blockmaxsize=1500",
- "-debug=mempool", "-debug=estimatefee"]
+ "-debug=mempool", "-debug=estimatefee", "-relaypriority=0"]
self.nodes.append(start_node(2, self.options.tmpdir, node2args))
connect_nodes(self.nodes[2], 0)
-#!/usr/bin/env python
+#!/usr/bin/env python2
# 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.
print("Initializing test directory "+self.options.tmpdir)
initialize_chain(self.options.tmpdir)
+ def setup_nodes(self):
+ return start_nodes(4, self.options.tmpdir)
+
def setup_network(self, split = False):
- self.nodes = start_nodes(4, self.options.tmpdir)
+ self.nodes = self.setup_nodes()
# Connect the nodes as a "chain". This allows us
# to split the network between nodes 1 and 2 to get
-#!/usr/bin/env python
+#!/usr/bin/env python2
# 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.
Start a bitcoind and return RPC connection to it
"""
datadir = os.path.join(dirname, "node"+str(i))
- args = [ os.getenv("BITCOIND", "bitcoind"), "-datadir="+datadir, "-keypool=1", "-discover=0" ]
+ args = [ os.getenv("BITCOIND", "bitcoind"), "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ]
if extra_args is not None: args.extend(extra_args)
bitcoind_processes[i] = subprocess.Popen(args)
devnull = open("/dev/null", "w+")
def assert_equal(thing1, thing2):
if thing1 != thing2:
raise AssertionError("%s != %s"%(str(thing1),str(thing2)))
+
+def assert_greater_than(thing1, thing2):
+ if thing1 <= thing2:
+ raise AssertionError("%s <= %s"%(str(thing1),str(thing2)))
+
+def assert_raises(exc, fun, *args, **kwds):
+ try:
+ fun(*args, **kwds)
+ except exc:
+ pass
+ except Exception as e:
+ raise AssertionError("Unexpected exception raised: "+type(e).__name__)
+ else:
+ raise AssertionError("No exception raised")
-#!/usr/bin/env python
+#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core 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.
#
self.nodes[0].setgenerate(True, 1)
+ walletinfo = self.nodes[0].getwalletinfo()
+ assert_equal(walletinfo['immature_balance'], 50)
+ assert_equal(walletinfo['balance'], 0)
+
self.sync_all()
self.nodes[1].setgenerate(True, 101)
self.sync_all()
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.
+ walletinfo = self.nodes[0].getwalletinfo()
+ assert_equal(walletinfo['immature_balance'], 0)
+
+ # Have node0 mine a block, thus they will collect their own fee.
self.nodes[0].setgenerate(True, 1)
self.sync_all()
assert_equal(self.nodes[2].getbalance(), 100)
assert_equal(self.nodes[2].getbalance("from1"), 100-21)
+ # Send 10 BTC normal
+ address = self.nodes[0].getnewaddress("test")
+ self.nodes[2].settxfee(Decimal('0.001'))
+ txid = self.nodes[2].sendtoaddress(address, 10, "", "", False)
+ self.nodes[2].setgenerate(True, 1)
+ self.sync_all()
+ assert_equal(self.nodes[2].getbalance(), Decimal('89.99900000'))
+ assert_equal(self.nodes[0].getbalance(), Decimal('10.00000000'))
+
+ # Send 10 BTC with subtract fee from amount
+ txid = self.nodes[2].sendtoaddress(address, 10, "", "", True)
+ self.nodes[2].setgenerate(True, 1)
+ self.sync_all()
+ assert_equal(self.nodes[2].getbalance(), Decimal('79.99900000'))
+ assert_equal(self.nodes[0].getbalance(), Decimal('19.99900000'))
+
+ # Sendmany 10 BTC
+ txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [])
+ self.nodes[2].setgenerate(True, 1)
+ self.sync_all()
+ assert_equal(self.nodes[2].getbalance(), Decimal('69.99800000'))
+ assert_equal(self.nodes[0].getbalance(), Decimal('29.99900000'))
+
+ # Sendmany 10 BTC with subtract fee from amount
+ txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [address])
+ self.nodes[2].setgenerate(True, 1)
+ self.sync_all()
+ assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000'))
+ assert_equal(self.nodes[0].getbalance(), Decimal('39.99800000'))
if __name__ == '__main__':
WalletTest ().main ()
--- /dev/null
+#!/usr/bin/env python2
+# 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.
+
+"""
+Exercise the wallet backup code. Ported from walletbackup.sh.
+
+Test case is:
+4 nodes. 1 2 and 3 send transactions between each other,
+fourth node is a miner.
+1 2 3 each mine a block to start, then
+Miner creates 100 blocks so 1 2 3 each have 50 mature
+coins to spend.
+Then 5 iterations of 1/2/3 sending coins amongst
+themselves to get transactions in the wallets,
+and the miner mining one block.
+
+Wallets are backed up using dumpwallet/backupwallet.
+Then 5 more iterations of transactions and mining a block.
+
+Miner then generates 101 more blocks, so any
+transaction fees paid mature.
+
+Sanity check:
+ Sum(1,2,3,4 balances) == 114*50
+
+1/2/3 are shutdown, and their wallets erased.
+Then restore using wallet.dat backup. And
+confirm 1/2/3/4 balances are same as before.
+
+Shutdown again, restore using importwallet,
+and confirm again balances are correct.
+"""
+
+from test_framework import BitcoinTestFramework
+from util import *
+from random import randint
+import logging
+logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO)
+
+class WalletBackupTest(BitcoinTestFramework):
+
+ def setup_chain(self):
+ logging.info("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 4)
+
+ # This mirrors how the network was setup in the bash test
+ def setup_network(self, split=False):
+ # nodes 1, 2,3 are spenders, let's give them a keypool=100
+ extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []]
+ self.nodes = start_nodes(4, self.options.tmpdir, extra_args)
+ connect_nodes(self.nodes[0], 3)
+ connect_nodes(self.nodes[1], 3)
+ connect_nodes(self.nodes[2], 3)
+ connect_nodes(self.nodes[2], 0)
+ self.is_network_split=False
+ self.sync_all()
+
+ def one_send(self, from_node, to_address):
+ if (randint(1,2) == 1):
+ amount = Decimal(randint(1,10)) / Decimal(10)
+ self.nodes[from_node].sendtoaddress(to_address, amount)
+
+ def do_one_round(self):
+ a0 = self.nodes[0].getnewaddress()
+ a1 = self.nodes[1].getnewaddress()
+ a2 = self.nodes[2].getnewaddress()
+
+ self.one_send(0, a1)
+ self.one_send(0, a2)
+ self.one_send(1, a0)
+ self.one_send(1, a2)
+ self.one_send(2, a0)
+ self.one_send(2, a1)
+
+ # Have the miner (node3) mine a block.
+ # Must sync mempools before mining.
+ sync_mempools(self.nodes)
+ self.nodes[3].setgenerate(True, 1)
+
+ # As above, this mirrors the original bash test.
+ def start_three(self):
+ self.nodes[0] = start_node(0, self.options.tmpdir)
+ self.nodes[1] = start_node(1, self.options.tmpdir)
+ self.nodes[2] = start_node(2, self.options.tmpdir)
+ connect_nodes(self.nodes[0], 3)
+ connect_nodes(self.nodes[1], 3)
+ connect_nodes(self.nodes[2], 3)
+ connect_nodes(self.nodes[2], 0)
+
+ def stop_three(self):
+ stop_node(self.nodes[0], 0)
+ stop_node(self.nodes[1], 1)
+ stop_node(self.nodes[2], 2)
+
+ def erase_three(self):
+ os.remove(self.options.tmpdir + "/node0/regtest/wallet.dat")
+ os.remove(self.options.tmpdir + "/node1/regtest/wallet.dat")
+ os.remove(self.options.tmpdir + "/node2/regtest/wallet.dat")
+
+ def run_test(self):
+ logging.info("Generating initial blockchain")
+ self.nodes[0].setgenerate(True, 1)
+ sync_blocks(self.nodes)
+ self.nodes[1].setgenerate(True, 1)
+ sync_blocks(self.nodes)
+ self.nodes[2].setgenerate(True, 1)
+ sync_blocks(self.nodes)
+ self.nodes[3].setgenerate(True, 100)
+ sync_blocks(self.nodes)
+
+ assert_equal(self.nodes[0].getbalance(), 50)
+ assert_equal(self.nodes[1].getbalance(), 50)
+ assert_equal(self.nodes[2].getbalance(), 50)
+ assert_equal(self.nodes[3].getbalance(), 0)
+
+ logging.info("Creating transactions")
+ # Five rounds of sending each other transactions.
+ for i in range(5):
+ self.do_one_round()
+
+ logging.info("Backing up")
+ tmpdir = self.options.tmpdir
+ self.nodes[0].backupwallet(tmpdir + "/node0/wallet.bak")
+ self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.dump")
+ self.nodes[1].backupwallet(tmpdir + "/node1/wallet.bak")
+ self.nodes[1].dumpwallet(tmpdir + "/node1/wallet.dump")
+ self.nodes[2].backupwallet(tmpdir + "/node2/wallet.bak")
+ self.nodes[2].dumpwallet(tmpdir + "/node2/wallet.dump")
+
+ logging.info("More transactions")
+ for i in range(5):
+ self.do_one_round()
+
+ # Generate 101 more blocks, so any fees paid mature
+ self.nodes[3].setgenerate(True, 101)
+ self.sync_all()
+
+ balance0 = self.nodes[0].getbalance()
+ balance1 = self.nodes[1].getbalance()
+ balance2 = self.nodes[2].getbalance()
+ balance3 = self.nodes[3].getbalance()
+ total = balance0 + balance1 + balance2 + balance3
+
+ # At this point, there are 214 blocks (103 for setup, then 10 rounds, then 101.)
+ # 114 are mature, so the sum of all wallets should be 114 * 50 = 5700.
+ assert_equal(total, 5700)
+
+ ##
+ # Test restoring spender wallets from backups
+ ##
+ logging.info("Restoring using wallet.dat")
+ self.stop_three()
+ self.erase_three()
+
+ # Start node2 with no chain
+ shutil.rmtree(self.options.tmpdir + "/node2/regtest/blocks")
+ shutil.rmtree(self.options.tmpdir + "/node2/regtest/chainstate")
+
+ # Restore wallets from backup
+ shutil.copyfile(tmpdir + "/node0/wallet.bak", tmpdir + "/node0/regtest/wallet.dat")
+ shutil.copyfile(tmpdir + "/node1/wallet.bak", tmpdir + "/node1/regtest/wallet.dat")
+ shutil.copyfile(tmpdir + "/node2/wallet.bak", tmpdir + "/node2/regtest/wallet.dat")
+
+ logging.info("Re-starting nodes")
+ self.start_three()
+ sync_blocks(self.nodes)
+
+ assert_equal(self.nodes[0].getbalance(), balance0)
+ assert_equal(self.nodes[1].getbalance(), balance1)
+ assert_equal(self.nodes[2].getbalance(), balance2)
+
+ logging.info("Restoring using dumped wallet")
+ self.stop_three()
+ self.erase_three()
+
+ #start node2 with no chain
+ shutil.rmtree(self.options.tmpdir + "/node2/regtest/blocks")
+ shutil.rmtree(self.options.tmpdir + "/node2/regtest/chainstate")
+
+ self.start_three()
+
+ assert_equal(self.nodes[0].getbalance(), 0)
+ assert_equal(self.nodes[1].getbalance(), 0)
+ assert_equal(self.nodes[2].getbalance(), 0)
+
+ self.nodes[0].importwallet(tmpdir + "/node0/wallet.dump")
+ self.nodes[1].importwallet(tmpdir + "/node1/wallet.dump")
+ self.nodes[2].importwallet(tmpdir + "/node2/wallet.dump")
+
+ sync_blocks(self.nodes)
+
+ assert_equal(self.nodes[0].getbalance(), balance0)
+ assert_equal(self.nodes[1].getbalance(), balance1)
+ assert_equal(self.nodes[2].getbalance(), balance2)
+
+
+if __name__ == '__main__':
+ WalletBackupTest().main()
+++ /dev/null
-#!/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 wallet backup / dump / restore functionality
-
-# Test case is:
-# 4 nodes. 1 2 3 and send transactions between each other,
-# fourth node is a miner.
-# 1 2 3 and each mine a block to start, then
-# miner creates 100 blocks so 1 2 3 each have 50 mature
-# coins to spend.
-# Then 5 iterations of 1/2/3 sending coins amongst
-# themselves to get transactions in the wallets,
-# and the miner mining one block.
-#
-# Wallets are backed up using dumpwallet/backupwallet.
-# Then 5 more iterations of transactions, then block.
-#
-# Miner then generates 101 more blocks, so any
-# transaction fees paid mature.
-#
-# Sanity checks done:
-# Miner balance >= 150*50
-# Sum(1,2,3,4 balances) == 153*150
-#
-# 1/2/3 are shutdown, and their wallets erased.
-# Then restore using wallet.dat backup. And
-# confirm 1/2/3/4 balances are same as before.
-#
-# Shutdown again, restore using importwallet,
-# and confirm again balances are correct.
-#
-
-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
-
-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)
-
-echo "Starting nodes..."
-
-# "Miner":
-D4=${D}/node4
-CreateDataDir $D4 port=11030 rpcport=11031
-B4ARGS="-datadir=$D4"
-$BITCOIND $BITCOINDARGS $B4ARGS &
-B4PID=$!
-
-# Want default keypool for 1/2/3, and
-# don't need send-and-wait functionality,
-# so don't use CreateDataDir:
-function CreateConfDir {
- DIR=$1
- mkdir -p $DIR
- CONF=$DIR/bitcoin.conf
- echo "regtest=1" >> $CONF
- echo "rpcuser=rt" >> $CONF
- echo "rpcpassword=rt" >> $CONF
- echo "rpcwait=1" >> $CONF
- shift
- while (( "$#" )); do
- echo $1 >> $CONF
- shift
- done
-}
-
-# "Spenders" 1/2/3
-D1=${D}/node1
-CreateConfDir $D1 port=11000 rpcport=11001 addnode=127.0.0.1:11030
-B1ARGS="-datadir=$D1"
-$BITCOIND $B1ARGS &
-B1PID=$!
-D2=${D}/node2
-CreateConfDir $D2 port=11010 rpcport=11011 addnode=127.0.0.1:11030
-B2ARGS="-datadir=$D2"
-$BITCOIND $B2ARGS &
-B2PID=$!
-D3=${D}/node3
-CreateConfDir $D3 port=11020 rpcport=11021 addnode=127.0.0.1:11030 addnode=127.0.0.1:11000
-B3ARGS="-datadir=$D3"
-$BITCOIND $BITCOINDARGS $B3ARGS &
-B3PID=$!
-
-# Wait until all nodes are at the same block number
-function WaitBlocks {
- while :
- do
- sleep 1
- BLOCKS1=$( GetBlocks "$B1ARGS" )
- BLOCKS2=$( GetBlocks "$B2ARGS" )
- BLOCKS3=$( GetBlocks "$B3ARGS" )
- BLOCKS4=$( GetBlocks "$B4ARGS" )
- if (( BLOCKS1 == BLOCKS4 && BLOCKS2 == BLOCKS4 && BLOCKS3 == BLOCKS4 ))
- then
- break
- fi
- done
-}
-
-# Wait until all nodes have the same txns in
-# their memory pools
-function WaitMemPools {
- while :
- do
- sleep 1
- MEMPOOL1=$( $CLI "$B1ARGS" getrawmempool | sort | shasum )
- MEMPOOL2=$( $CLI "$B2ARGS" getrawmempool | sort | shasum )
- MEMPOOL3=$( $CLI "$B3ARGS" getrawmempool | sort | shasum )
- MEMPOOL4=$( $CLI "$B4ARGS" getrawmempool | sort | shasum )
- if [[ $MEMPOOL1 = $MEMPOOL4 && $MEMPOOL2 = $MEMPOOL4 && $MEMPOOL3 = $MEMPOOL4 ]]
- then
- break
- fi
- done
-}
-
-echo "Generating initial blockchain..."
-
-# 1 block, 50 XBT each == 50 BTC
-$CLI $B1ARGS setgenerate true 1
-WaitBlocks
-$CLI $B2ARGS setgenerate true 1
-WaitBlocks
-$CLI $B3ARGS setgenerate true 1
-WaitBlocks
-
-# 100 blocks, 0 mature
-$CLI $B4ARGS setgenerate true 100
-WaitBlocks
-
-CheckBalance "$B1ARGS" 50
-CheckBalance "$B2ARGS" 50
-CheckBalance "$B3ARGS" 50
-CheckBalance "$B4ARGS" 0
-
-echo "Creating transactions..."
-
-function S {
- TXID=$( $CLI -datadir=${D}/node${1} sendtoaddress ${2} "${3}" 0 )
- if [ x$TXID = x ] ; then
- echoerr "node${1}: error sending ${3} btc"
- echo -n "node${1} balance: "
- $CLI -datadir=${D}/node${1} getbalance "*" 0
- exit 1
- fi
-}
-
-function OneRound {
- A1=$( $CLI $B1ARGS getnewaddress )
- A2=$( $CLI $B2ARGS getnewaddress )
- A3=$( $CLI $B3ARGS getnewaddress )
- if [[ $(( $RANDOM%2 )) < 1 ]] ; then
- N=$(( $RANDOM % 9 + 1 ))
- S 1 $A2 "0.$N"
- fi
- if [[ $(( $RANDOM%2 )) < 1 ]] ; then
- N=$(( $RANDOM % 9 + 1 ))
- S 1 $A3 "0.0$N"
- fi
- if [[ $(( $RANDOM%2 )) < 1 ]] ; then
- N=$(( $RANDOM % 9 + 1 ))
- S 2 $A1 "0.$N"
- fi
- if [[ $(( $RANDOM%2 )) < 1 ]] ; then
- N=$(( $RANDOM % 9 + 1 ))
- S 2 $A3 "0.$N"
- fi
- if [[ $(( $RANDOM%2 )) < 1 ]] ; then
- N=$(( $RANDOM % 9 + 1 ))
- S 3 $A1 "0.$N"
- fi
- if [[ $(( $RANDOM%2 )) < 1 ]] ; then
- N=$(( $RANDOM % 9 + 1 ))
- S 3 $A2 "0.0$N"
- fi
- $CLI "$B4ARGS" setgenerate true 1
-}
-
-for i in {1..5}; do OneRound ; done
-
-echo "Backing up..."
-
-$CLI "$B1ARGS" backupwallet "$D1/wallet.bak"
-$CLI "$B1ARGS" dumpwallet "$D1/wallet.dump"
-$CLI "$B2ARGS" backupwallet "$D2/wallet.bak"
-$CLI "$B2ARGS" dumpwallet "$D2/wallet.dump"
-$CLI "$B3ARGS" backupwallet "$D3/wallet.bak"
-$CLI "$B3ARGS" dumpwallet "$D3/wallet.dump"
-
-echo "More transactions..."
-for i in {1..5}; do OneRound ; done
-
-WaitMemPools
-
-# Generate 101 more blocks, so any fees paid
-# mature
-$CLI "$B4ARGS" setgenerate true 101
-
-BALANCE1=$( $CLI "$B1ARGS" getbalance )
-BALANCE2=$( $CLI "$B2ARGS" getbalance )
-BALANCE3=$( $CLI "$B3ARGS" getbalance )
-BALANCE4=$( $CLI "$B4ARGS" getbalance )
-
-TOTAL=$( dc -e "$BALANCE1 $BALANCE2 $BALANCE3 $BALANCE4 + + + p" )
-
-AssertEqual $TOTAL 5700.00000000
-
-function StopThree {
- $CLI $B1ARGS stop > /dev/null 2>&1
- $CLI $B2ARGS stop > /dev/null 2>&1
- $CLI $B3ARGS stop > /dev/null 2>&1
- wait $B1PID
- wait $B2PID
- wait $B3PID
-}
-function EraseThree {
- rm $D1/regtest/wallet.dat
- rm $D2/regtest/wallet.dat
- rm $D3/regtest/wallet.dat
-}
-function StartThree {
- $BITCOIND $BITCOINDARGS $B1ARGS &
- B1PID=$!
- $BITCOIND $BITCOINDARGS $B2ARGS &
- B2PID=$!
- $BITCOIND $BITCOINDARGS $B3ARGS &
- B3PID=$!
-}
-
-echo "Restoring using wallet.dat"
-
-StopThree
-EraseThree
-
-# Start node3 with no chain
-rm -rf $D3/regtest/blocks
-rm -rf $D3/regtest/chainstate
-rm -rf $D3/regtest/database
-
-cp $D1/wallet.bak $D1/regtest/wallet.dat
-cp $D2/wallet.bak $D2/regtest/wallet.dat
-cp $D3/wallet.bak $D3/regtest/wallet.dat
-
-StartThree
-WaitBlocks
-
-AssertEqual $BALANCE1 $( $CLI "$B1ARGS" getbalance )
-AssertEqual $BALANCE2 $( $CLI "$B2ARGS" getbalance )
-AssertEqual $BALANCE3 $( $CLI "$B3ARGS" getbalance )
-
-echo "Restoring using dumped wallet"
-
-StopThree
-EraseThree
-
-# Start node3 with no chain
-rm -rf $D3/regtest/blocks
-rm -rf $D3/regtest/chainstate
-rm -rf $D3/regtest/database
-
-StartThree
-
-AssertEqual 0 $( $CLI "$B1ARGS" getbalance )
-AssertEqual 0 $( $CLI "$B2ARGS" getbalance )
-AssertEqual 0 $( $CLI "$B3ARGS" getbalance )
-
-$CLI "$B1ARGS" importwallet $D1/wallet.dump
-$CLI "$B2ARGS" importwallet $D2/wallet.dump
-$CLI "$B3ARGS" importwallet $D3/wallet.dump
-
-WaitBlocks
-
-AssertEqual $BALANCE1 $( $CLI "$B1ARGS" getbalance )
-AssertEqual $BALANCE2 $( $CLI "$B2ARGS" getbalance )
-AssertEqual $BALANCE3 $( $CLI "$B3ARGS" getbalance )
-
-StopThree
-$CLI $B4ARGS stop > /dev/null 2>&1
-wait $B4PID
-
-echo "Tests successful, cleaning up"
-trap "" EXIT
-rm -rf $D
-exit 0
--- /dev/null
+#!/usr/bin/env python2
+# 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 util import *
+
+
+class ZapWalletTXesTest (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)
+
+ txid0 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
+ txid1 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
+ self.sync_all()
+ self.nodes[0].setgenerate(True, 1)
+ self.sync_all()
+
+ txid2 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
+ txid3 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
+
+ tx0 = self.nodes[0].gettransaction(txid0)
+ assert_equal(tx0['txid'], txid0) #tx0 must be available (confirmed)
+
+ tx1 = self.nodes[0].gettransaction(txid1)
+ assert_equal(tx1['txid'], txid1) #tx1 must be available (confirmed)
+
+ tx2 = self.nodes[0].gettransaction(txid2)
+ assert_equal(tx2['txid'], txid2) #tx2 must be available (unconfirmed)
+
+ tx3 = self.nodes[0].gettransaction(txid3)
+ assert_equal(tx3['txid'], txid3) #tx3 must be available (unconfirmed)
+
+ #restart bitcoind
+ self.nodes[0].stop()
+ bitcoind_processes[0].wait()
+ self.nodes[0] = start_node(0,self.options.tmpdir)
+
+ tx3 = self.nodes[0].gettransaction(txid3)
+ assert_equal(tx3['txid'], txid3) #tx must be available (unconfirmed)
+
+ self.nodes[0].stop()
+ bitcoind_processes[0].wait()
+
+ #restart bitcoind with zapwallettxes
+ self.nodes[0] = start_node(0,self.options.tmpdir, ["-zapwallettxes=1"])
+
+ aException = False
+ try:
+ tx3 = self.nodes[0].gettransaction(txid3)
+ except JSONRPCException,e:
+ print e
+ aException = True
+
+ assert_equal(aException, True) #there must be a expection because the unconfirmed wallettx0 must be gone by now
+
+ tx0 = self.nodes[0].gettransaction(txid0)
+ assert_equal(tx0['txid'], txid0) #tx0 (confirmed) must still be available because it was confirmed
+
+
+if __name__ == '__main__':
+ ZapWalletTXesTest ().main ()
+++ /dev/null
-#!/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 -zapwallettxes=<mode>
-
-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
-B2ARGS="-datadir=$D2"
-$BITCOIND $B2ARGS &
-B2PID=$!
-
-function CleanUp {
-$CLI $B2ARGS stop > /dev/null 2>&1
-wait $B2PID
-$CLI $B1ARGS stop > /dev/null 2>&1
-wait $B1PID
-
-rm -rf $D
-}
-
-# 110 blocks, 10 mature == 500 XBT
-$CLI $B1ARGS setgenerate true 110
-$CLI $B2ARGS setgenerate true 110
-
-CheckBalance "$B1ARGS" 500
-CheckBalance "$B2ARGS" 500
-
-# Send 10 XBT
-TXID1_DEFAULT=$($CLI $B1ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 10)
-TXID2_DEFAULT=$($CLI $B2ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 10)
-
-CheckBalance $B1ARGS 490
-CheckBalance $B2ARGS 490
-
-# Move 10 XBT to testaccount
-TMP=$($CLI $B1ARGS move "" "testaccount" 10)
-TMP=$($CLI $B2ARGS move "" "testaccount" 10)
-
-CheckBalance $B1ARGS 10 "testaccount"
-CheckBalance $B2ARGS 10 "testaccount"
-
-# Send 1 XBT from testaccount
-TXID1_TESTACCOUNT=$($CLI $B1ARGS sendfrom "testaccount" "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
-TXID2_TESTACCOUNT=$($CLI $B2ARGS sendfrom "testaccount" "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
-
-CheckBalance $B1ARGS 9 "testaccount"
-CheckBalance $B2ARGS 9 "testaccount"
-
-CheckBalance $B1ARGS 489
-CheckBalance $B2ARGS 489
-
-# Confirm transactions
-$CLI $B1ARGS setgenerate true 1
-$CLI $B2ARGS setgenerate true 1
-
-# Create unconfirmed transaction
-TXID1_UNCONFIRMED=$($CLI $B1ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
-TXID2_UNCONFIRMED=$($CLI $B2ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
-
-# check balance (we created another 50 and spent 1 in the meantime)
-CheckBalance $B1ARGS 538
-CheckBalance $B2ARGS 538
-
-# Safety check, if unconfirmed transactions are there
-$CLI $B1ARGS gettransaction $TXID1_UNCONFIRMED > /dev/null 2>&1
-if [[ $? -ne 0 ]] ; then
- echoerr "gettransaction1_1: $TXID1_UNCONFIRMED failed"
- CleanUp
- exit 1
-fi
-$CLI $B2ARGS gettransaction $TXID2_UNCONFIRMED > /dev/null 2>&1
-if [[ $? -ne 0 ]] ; then
- echoerr "gettransaction2_1: $TXID2_UNCONFIRMED failed"
- CleanUp
- exit 1
-fi
-
-# stop nodes
-$CLI $B2ARGS stop > /dev/null 2>&1
-wait $B2PID
-$CLI $B1ARGS stop > /dev/null 2>&1
-wait $B1PID
-
-# restart nodes with -zapwallettxes
-$BITCOIND -zapwallettxes=1 $B1ARGS &
-B1PID=$!
-$BITCOIND -zapwallettxes=2 $B2ARGS &
-B2PID=$!
-
-# check if confirmed transactions are there
-$CLI $B1ARGS gettransaction $TXID1_DEFAULT > /dev/null 2>&1
-if [[ $? -ne 0 ]] ; then
- echoerr "check confirmed transaction 1: $TXID1_DEFAULT failed"
- CleanUp
- exit 1
-fi
-$CLI $B2ARGS gettransaction $TXID2_DEFAULT > /dev/null 2>&1
-if [[ $? -ne 0 ]] ; then
- echoerr "check confirmed transaction 2: $TXID2_DEFAULT failed"
- CleanUp
- exit 1
-fi
-$CLI $B1ARGS gettransaction $TXID1_TESTACCOUNT > /dev/null 2>&1
-if [[ $? -ne 0 ]] ; then
- echoerr "check confirmed transaction 3: $TXID1_TESTACCOUNT failed"
- CleanUp
- exit 1
-fi
-$CLI $B2ARGS gettransaction $TXID2_TESTACCOUNT > /dev/null 2>&1
-if [[ $? -ne 0 ]] ; then
- echoerr "check confirmed transaction 4: $TXID2_TESTACCOUNT failed"
- CleanUp
- exit 1
-fi
-
-# check if unconfirmed transaction is gone
-$CLI $B1ARGS gettransaction $TXID1_UNCONFIRMED > /dev/null 2>&1
-if [[ $? -eq 0 ]] ; then
- echoerr "check unconfirmed transaction 1: $TXID1_UNCONFIRMED failed"
- CleanUp
- exit 1
-fi
-$CLI $B2ARGS gettransaction $TXID2_UNCONFIRMED > /dev/null 2>&1
-if [[ $? -eq 0 ]] ; then
- echoerr "check unconfirmed transaction 2: $TXID2_UNCONFIRMED failed"
- CleanUp
- exit 1
-fi
-
-# check zapwallet mode 1, testaccount balance must be 9 (keeping transaction metadata)
-CheckBalance $B1ARGS 9 "testaccount"
-
-# check zapwallet mode 2, testaccount balance must be 10 (dropping transaction metadata)
-CheckBalance $B2ARGS 10 "testaccount"
-
-echo "Tests successful, cleaning up"
-CleanUp
-exit 0
# List of fixed seed nodes for main network
-# IPv4 nodes (in old chainparams.cpp 0xDDCCBBAA format)
-# n.b. when importing a new list, there is no need to use this format, just use IPv4 dotted addresses directly
-0x7e6a692e # 46.105.106.126
-0x7d04d1a2 # 162.209.4.125
-0x6c0c17d9 # 217.23.12.108
-0xdb330ab9 # 185.10.51.219
-0xc649c7c6 # 198.199.73.198
-0x7895484d # 77.72.149.120
-0x047109b0 # 176.9.113.4
-0xb90ca5bc # 188.165.12.185
-0xd130805f # 95.128.48.209
-0xbd074ea6 # 166.78.7.189
-0x578ff1c0 # 192.241.143.87
-0x286e09b0 # 176.9.110.40
-0xd4dcaf42 # 66.175.220.212
-0x529b6bb8 # 184.107.155.82
-0x635cc6c0 # 192.198.92.99
-0xedde892e # 46.137.222.237
-0xa976d9c7 # 199.217.118.169
-0xea91a4b8 # 184.164.145.234
-0x03fa4eb2 # 178.78.250.3
-0x6ca9008d # 141.0.169.108
-0xaf62c825 # 37.200.98.175
-0x93f3ba51 # 81.186.243.147
-0xc2c9efd5 # 213.239.201.194
-0x0ed5175e # 94.23.213.14
-0x487028bc # 188.40.112.72
-0x7297c225 # 37.194.151.114
-0x8af0c658 # 88.198.240.138
-0x2e57ba1f # 31.186.87.46
-0xd0098abc # 188.138.9.208
-0x46a8853e # 62.133.168.70
-0xcc92dc3e # 62.220.146.204
-0xeb6f1955 # 85.25.111.235
-0x8cce175e # 94.23.206.140
-0x237281ae # 174.129.114.35
-0x9d42795b # 91.121.66.157
-0x4f4f0905 # 5.9.79.79
-0xc50151d0 # 208.81.1.197
-0xb1ba90c6 # 198.144.186.177
-0xaed7175e # 94.23.215.174
-0x204de55b # 91.229.77.32
-0x4bb03245 # 69.50.176.75
-0x932b28bc # 188.40.43.147
-0x2dcce65b # 91.230.204.45
-0xe2708abc # 188.138.112.226
-0x1b08b8d5 # 213.184.8.27
-0x12a3dc5b # 91.220.163.18
-0x8a884c90 # 144.76.136.138
-0xa386a8b8 # 184.168.134.163
-0x18e417c6 # 198.23.228.24
-0x2e709ac3 # 195.154.112.46
-0xeb62e925 # 37.233.98.235
-0x6f6503ae # 174.3.101.111
-0x05d0814e # 78.129.208.5
-0x8a9ac545 # 69.197.154.138
-0x946fd65e # 94.214.111.148
-0x3f57495d # 93.73.87.63
-0x4a29c658 # 88.198.41.74
-0xad454c90 # 144.76.69.173
-0x15340905 # 5.9.52.21
-0x4c3f3b25 # 37.59.63.76
-0x01fe19b9 # 185.25.254.1
-0x5620595b # 91.89.32.86
-0x443c795b # 91.121.60.68
-0x44f24ac8 # 200.74.242.68
-0x0442464e # 78.70.66.4
-0xc8665882 # 130.88.102.200
-0xed3f3ec3 # 195.62.63.237
-0xf585bf5d # 93.191.133.245
-0x5dd141da # 218.65.209.93
-0xf93a084e # 78.8.58.249
-0x1264dd52 # 82.221.100.18
-0x0711c658 # 88.198.17.7
-0xf12e7bbe # 190.123.46.241
-0x5b02b740 # 64.183.2.91
-0x7d526dd5 # 213.109.82.125
-0x0cb04c90 # 144.76.176.12
-0x2abe1132 # 50.17.190.42
-0x61a39f58 # 88.159.163.97
-0x044a0618 # 24.6.74.4
-0xf3af7dce # 206.125.175.243
-0xb994c96d # 109.201.148.185
-0x361c5058 # 88.80.28.54
-0xca735d53 # 83.93.115.202
-0xeca743b0 # 176.67.167.236
-0xec790905 # 5.9.121.236
-0xc4d37845 # 69.120.211.196
-0xa1c4a2b2 # 178.162.196.161
-0x726fd453 # 83.212.111.114
-0x625cc6c0 # 192.198.92.98
-0x6c20132e # 46.19.32.108
-0xb7aa0c79 # 121.12.170.183
-0xc6ed983d # 61.152.237.198
-0x47e4cbc0 # 192.203.228.71
-0xa4ac75d4 # 212.117.172.164
-0xe2e59345 # 69.147.229.226
-0x4d784ad0 # 208.74.120.77
-0x18a5ec5e # 94.236.165.24
-0x481cc85b # 91.200.28.72
-0x7c6c2fd5 # 213.47.108.124
-0x5e4d6018 # 24.96.77.94
-0x5b4b6c18 # 24.108.75.91
-0xd99b4c90 # 144.76.155.217
-0xe63987dc # 220.135.57.230
-0xb817bb25 # 37.187.23.184
-0x141cfeb2 # 178.254.28.20
-0x5f005058 # 88.80.0.95
-0x0d987f47 # 71.127.152.13
-0x242a496d # 109.73.42.36
-0x3e519bc0 # 192.155.81.62
-0x02b2454b # 75.69.178.2
-0xdfaf3dc6 # 198.61.175.223
-0x888128bc # 188.40.129.136
-0x1165bb25 # 37.187.101.17
-0xabfeca5b # 91.202.254.171
-0x2ef63540 # 64.53.246.46
-0x5773c7c6 # 198.199.115.87
-0x1280dd52 # 82.221.128.18
-0x8ebcacd9 # 217.172.188.142
-0x81c439c6 # 198.57.196.129
-0x39fcfa45 # 69.250.252.57
-0x62177d41 # 65.125.23.98
-0xc975ed62 # 98.237.117.201
-0x05cff476 # 118.244.207.5
-0xdabda743 # 67.167.189.218
-0xaa1ac24e # 78.194.26.170
-0xe255a22e # 46.162.85.226
-0x88aac705 # 5.199.170.136
-0xe707c658 # 88.198.7.231
-0xa9e94b5e # 94.75.233.169
-0x2893484b # 75.72.147.40
-0x99512705 # 5.39.81.153
-0xd63970ca # 202.112.57.214
-0x45994f32 # 50.79.153.69
-0xe519a8ad # 173.168.25.229
-0x92e25f5d # 93.95.226.146
-0x8b84a9c1 # 193.169.132.139
-0x5eaa0a05 # 5.10.170.94
-0xa74de55b # 91.229.77.167
-0xb090ff62 # 98.255.144.176
-0x5eee326c # 108.50.238.94
-0xc331a679 # 121.166.49.195
-0xc1d9b72e # 46.183.217.193
-0x0c6ab982 # 130.185.106.12
-0x7362bb25 # 37.187.98.115
-0x4cfedd42 # 66.221.254.76
-0x1e09a032 # 50.160.9.30
-0xa4c34c5e # 94.76.195.164
-0x3777d9c7 # 199.217.119.55
-0x5edcf260 # 96.242.220.94
-0x3ce2b548 # 72.181.226.60
-0xd2ac0360 # 96.3.172.210
-0x2f80b992 # 146.185.128.47
-0x3e4cbb25 # 37.187.76.62
-0x3995e236 # 54.226.149.57
-0xd03977ae # 174.119.57.208
-0x953cf054 # 84.240.60.149
-0x3c654ed0 # 208.78.101.60
-0x74024c90 # 144.76.2.116
-0xa14f1155 # 85.17.79.161
-0x14ce0125 # 37.1.206.20
-0xc15ebb6a # 106.187.94.193
-0x2c08c452 # 82.196.8.44
-0xc7fd0652 # 82.6.253.199
-0x7604f8ce # 206.248.4.118
-0xffb38332 # 50.131.179.255
-0xa4c2efd5 # 213.239.194.164
-0xe9614018 # 24.64.97.233
-0xab49e557 # 87.229.73.171
-0x1648c052 # 82.192.72.22
-0x36024047 # 71.64.2.54
-0x0e8cffad # 173.255.140.14
-0x21918953 # 83.137.145.33
-0xb61f50ad # 173.80.31.182
-0x9b406b59 # 89.107.64.155
-0xaf282218 # 24.34.40.175
-0x7f1d164e # 78.22.29.127
-0x1f560da2 # 162.13.86.31
-0xe237be58 # 88.190.55.226
-0xbdeb1955 # 85.25.235.189
-0x6c0717d9 # 217.23.7.108
-0xdaf8ce62 # 98.206.248.218
-0x0f74246c # 108.36.116.15
-0xdee95243 # 67.82.233.222
-0xf23f1a56 # 86.26.63.242
-0x61bdf867 # 103.248.189.97
-0xd254c854 # 84.200.84.210
-0xc4422e4e # 78.46.66.196
-0xae0563c0 # 192.99.5.174
-0xbdb9a95f # 95.169.185.189
-0xa9eb32c6 # 198.50.235.169
-0xd9943950 # 80.57.148.217
-0x116add52 # 82.221.106.17
-0x73a54c90 # 144.76.165.115
-0xb36b525e # 94.82.107.179
-0xd734175e # 94.23.52.215
-0x333d7f76 # 118.127.61.51
-0x51431bc6 # 198.27.67.81
-0x084ae5cf # 207.229.74.8
-0xa60a236c # 108.35.10.166
-0x5c67692e # 46.105.103.92
-0x0177cf45 # 69.207.119.1
-0xa6683ac6 # 198.58.104.166
-0x7ff4ea47 # 71.234.244.127
-0x2192fab2 # 178.250.146.33
-0xa03a0f46 # 70.15.58.160
-0xfe3e39ae # 174.57.62.254
-0x2cce5fc1 # 193.95.206.44
-0xc8a6c148 # 72.193.166.200
-0x96fb7e4c # 76.126.251.150
-0x0a66c752 # 82.199.102.10
-0x6b4d2705 # 5.39.77.107
-0xeba0c118 # 24.193.160.235
-0x3ba0795b # 91.121.160.59
-0x1dccd23e # 62.210.204.29
-0x6912f3a2 # 162.243.18.105
-0x22f23c41 # 65.60.242.34
-0x65646b4a # 74.107.100.101
-0x8b9f8705 # 5.135.159.139
-0xeb9b9a95 # 149.154.155.235
-0x79fe6b4e # 78.107.254.121
-0x0536f447 # 71.244.54.5
-0x23224d61 # 97.77.34.35
-0x5d952ec6 # 198.46.149.93
-0x0cb4f736 # 54.247.180.12
-0xdc14be6d # 109.190.20.220
-0xb24609b0 # 176.9.70.178
-0xd3f79b62 # 98.155.247.211
-0x6518c836 # 54.200.24.101
-0x83a3cf42 # 66.207.163.131
-0x9b641fb0 # 176.31.100.155
-0x17fef1c0 # 192.241.254.23
-0xd508cc82 # 130.204.8.213
-0x91a4369b # 155.54.164.145
-0x39cb4a4c # 76.74.203.57
-0xbbc9536c # 108.83.201.187
-0xaf64c44a # 74.196.100.175
-0x605eca50 # 80.202.94.96
-0x0c6a6805 # 5.104.106.12
-0xd07e9d4e # 78.157.126.208
-0x78e6d3a2 # 162.211.230.120
-0x1b31eb6d # 109.235.49.27
-0xaa01feb2 # 178.254.1.170
-0x4603c236 # 54.194.3.70
-0x1ecba3b6 # 182.163.203.30
-0x0effe336 # 54.227.255.14
-0xc3fdcb36 # 54.203.253.195
-0xc290036f # 111.3.144.194
-0x4464692e # 46.105.100.68
-0x1aca7589 # 137.117.202.26
-0x59a9e52e # 46.229.169.89
-0x19aa7489 # 137.116.170.25
-0x2622c85e # 94.200.34.38
-0xa598d318 # 24.211.152.165
-0x438ec345 # 69.195.142.67
-0xc79619b9 # 185.25.150.199
-0xaf570360 # 96.3.87.175
-0x5098e289 # 137.226.152.80
-0x36add862 # 98.216.173.54
-0x83c1a2b2 # 178.162.193.131
-0x969d0905 # 5.9.157.150
-0xcf3d156c # 108.21.61.207
-0x49c1a445 # 69.164.193.73
-0xbd0b7562 # 98.117.11.189
-0x8fff1955 # 85.25.255.143
-0x1e51fe53 # 83.254.81.30
-0x28d6efd5 # 213.239.214.40
-0x2837cc62 # 98.204.55.40
-0x02f42d42 # 66.45.244.2
-0x070e3fb2 # 178.63.14.7
-0xbcb18705 # 5.135.177.188
-0x14a4e15b # 91.225.164.20
-0x82096844 # 68.104.9.130
-0xcfcb1c2e # 46.28.203.207
-0x37e27fc7 # 199.127.226.55
-0x07923748 # 72.55.146.7
-0x0c14bc2e # 46.188.20.12
-0x26100905 # 5.9.16.38
-0xcb7cd93e # 62.217.124.203
-0x3bc0d2c0 # 192.210.192.59
-0x97131b4c # 76.27.19.151
-0x6f1e5c17 # 23.92.30.111
-0xa7939f43 # 67.159.147.167
-0xb7a0bf58 # 88.191.160.183
-0xafa83a47 # 71.58.168.175
-0xcbb83f32 # 50.63.184.203
-0x5f321cb0 # 176.28.50.95
-0x52d6c3c7 # 199.195.214.82
-0xdeac5bc7 # 199.91.172.222
-0x2cf310cc # 204.16.243.44
-0x108a2bc3 # 195.43.138.16
-0x726fa14f # 79.161.111.114
-0x85bad2cc # 204.210.186.133
-0x459e4c90 # 144.76.158.69
-0x1a08b8d8 # 216.184.8.26
-0xcd7048c6 # 198.72.112.205
-0x6d5b4c90 # 144.76.91.109
-0xa66cfe7b # 123.254.108.166
-0xad730905 # 5.9.115.173
-0xdaac5bc7 # 199.91.172.218
-0x8417fd9f # 159.253.23.132
-0x41377432 # 50.116.55.65
-0x1f138632 # 50.134.19.31
-0x295a12b2 # 178.18.90.41
-0x7ac031b2 # 178.49.192.122
-0x3a87d295 # 149.210.135.58
-0xe219bc2e # 46.188.25.226
-0xf485d295 # 149.210.133.244
-0x137b6405 # 5.100.123.19
-0xcfffd9ad # 173.217.255.207
-0xafe20844 # 68.8.226.175
-0x32679a5f # 95.154.103.50
-0xa431c644 # 68.198.49.164
-0x0e5fce8c # 140.206.95.14
-0x305ef853 # 83.248.94.48
-0xad26ca32 # 50.202.38.173
-0xd9d21a54 # 84.26.210.217
-0xddd0d736 # 54.215.208.221
-0xc24ec0c7 # 199.192.78.194
-0x4aadcd5b # 91.205.173.74
-0x49109852 # 82.152.16.73
-0x9d6b3ac6 # 198.58.107.157
-0xf0aa1e8b # 139.30.170.240
-0xf1bfa343 # 67.163.191.241
-0x8a30c0ad # 173.192.48.138
-0x260f93d4 # 212.147.15.38
-0x2339e760 # 96.231.57.35
-0x8869959f # 159.149.105.136
-0xc207216c # 108.33.7.194
-0x29453448 # 72.52.69.41
-0xb651ec36 # 54.236.81.182
-0x45496259 # 89.98.73.69
-0xa23d1bcc # 204.27.61.162
-0xb39bcf43 # 67.207.155.179
-0xa1d29432 # 50.148.210.161
-0x3507c658 # 88.198.7.53
-0x4a88dd62 # 98.221.136.74
-0x27aff363 # 99.243.175.39
-0x7498ea6d # 109.234.152.116
-0x4a6785d5 # 213.133.103.74
-0x5e6d47c2 # 194.71.109.94
-0x3baba542 # 66.165.171.59
-0x045a37ae # 174.55.90.4
-0xa24dc0c7 # 199.192.77.162
-0xe981ea4d # 77.234.129.233
-0xed6ce217 # 23.226.108.237
-0x857214c6 # 198.20.114.133
-0x6b6c0464 # 100.4.108.107
-0x5a4945b8 # 184.69.73.90
-0x12f24742 # 66.71.242.18
-0xf35f42ad # 173.66.95.243
-0xfd0f5a4e # 78.90.15.253
-0xfb081556 # 86.21.8.251
-0xb24b5861 # 97.88.75.178
-0x2e114146 # 70.65.17.46
-0xb7780905 # 5.9.120.183
-0x33bb0e48 # 72.14.187.51
-0x39e26556 # 86.101.226.57
-0xa794484d # 77.72.148.167
-0x4225424d # 77.66.37.66
-0x3003795b # 91.121.3.48
-0x31c8cf44 # 68.207.200.49
-0xd65bad59 # 89.173.91.214
-0x127bc648 # 72.198.123.18
-0xf2bc4d4c # 76.77.188.242
-0x0273dc50 # 80.220.115.2
-0x4572d736 # 54.215.114.69
-0x064bf653 # 83.246.75.6
-0xcdcd126c # 108.18.205.205
-0x608281ae # 174.129.130.96
-0x4d130087 # 135.0.19.77
-0x1016f725 # 37.247.22.16
-0xba185fc0 # 192.95.24.186
-0x16c1a84f # 79.168.193.22
-0xfb697252 # 82.114.105.251
-0xa2942360 # 96.35.148.162
-0x53083b6c # 108.59.8.83
-0x0583f1c0 # 192.241.131.5
-0x2d5a2441 # 65.36.90.45
-0xc172aa43 # 67.170.114.193
-0xcd11cf36 # 54.207.17.205
-0x7b14ed62 # 98.237.20.123
-0x5c94f1c0 # 192.241.148.92
-0x7c23132e # 46.19.35.124
-0x39965a6f # 111.90.150.57
-0x7890e24e # 78.226.144.120
-0xa38ec447 # 71.196.142.163
-0xc187f1c0 # 192.241.135.193
-0xef80b647 # 71.182.128.239
-0xf20a7432 # 50.116.10.242
-0x7ad1d8d2 # 210.216.209.122
-0x869e2ec6 # 198.46.158.134
-0xccdb5c5d # 93.92.219.204
-0x9d11f636 # 54.246.17.157
-0x2161bb25 # 37.187.97.33
-0x7599f889 # 137.248.153.117
-0x2265ecad # 173.236.101.34
-0x0f4f0e55 # 85.14.79.15
-0x7d25854a # 74.133.37.125
-0xf857e360 # 96.227.87.248
-0xf83f3d6c # 108.61.63.248
-0x9cc93bb8 # 184.59.201.156
-0x02716857 # 87.104.113.2
-0x5dd8a177 # 119.161.216.93
-0x8adc6cd4 # 212.108.220.138
-0xe5613d46 # 70.61.97.229
-0x6a734f50 # 80.79.115.106
-0x2a5c3bae # 174.59.92.42
-0x4a04c3d1 # 209.195.4.74
-0xe4613d46 # 70.61.97.228
-0x8426f4bc # 188.244.38.132
-0x3e1b5fc0 # 192.95.27.62
-0x0d5a3c18 # 24.60.90.13
-0xd0f6d154 # 84.209.246.208
-0x21c7ff5e # 94.255.199.33
-0xeb3f3d6c # 108.61.63.235
-0x9da5edc0 # 192.237.165.157
-0x5d753b81 # 129.59.117.93
-0x0d8d53d4 # 212.83.141.13
-0x2613f018 # 24.240.19.38
-0x4443698d # 141.105.67.68
-0x8ca1edcd # 205.237.161.140
-0x10ed3f4e # 78.63.237.16
-0x789b403a # 58.64.155.120
-0x7b984a4b # 75.74.152.123
-0x964ebc25 # 37.188.78.150
-0x7520ee60 # 96.238.32.117
-0x4f4828bc # 188.40.72.79
-0x115c407d # 125.64.92.17
-0x32dd0667 # 103.6.221.50
-0xa741715e # 94.113.65.167
-0x1d3f3532 # 50.53.63.29
-0x817d1f56 # 86.31.125.129
-0x2f99a552 # 82.165.153.47
-0x6b2a5956 # 86.89.42.107
-0x8d4f4f05 # 5.79.79.141
-0xd23c1e17 # 23.30.60.210
-0x98993748 # 72.55.153.152
-0x2c92e536 # 54.229.146.44
-0x237ebdc3 # 195.189.126.35
-0xa762fb43 # 67.251.98.167
-0x32016b71 # 113.107.1.50
-0xd0e7cf79 # 121.207.231.208
-0x7d35bdd5 # 213.189.53.125
-0x53dac3d2 # 210.195.218.83
-0x31016b71 # 113.107.1.49
-0x7fb8f8ce # 206.248.184.127
-0x9a38c232 # 50.194.56.154
-0xefaa42ad # 173.66.170.239
-0x876b823d # 61.130.107.135
-0x18175347 # 71.83.23.24
-0xdb46597d # 125.89.70.219
-0xd2c168da # 218.104.193.210
-0xcd6fe9dc # 220.233.111.205
-0x45272e4e # 78.46.39.69
-0x8d4bca5b # 91.202.75.141
-0xa4043d47 # 71.61.4.164
-0xaab7aa47 # 71.170.183.170
-0x202881ae # 174.129.40.32
-0xa4aef160 # 96.241.174.164
-0xecd7e6bc # 188.230.215.236
-0x391359ad # 173.89.19.57
-0xd8cc9318 # 24.147.204.216
-0xbbeee52e # 46.229.238.187
-0x077067b0 # 176.103.112.7
-0xebd39d62 # 98.157.211.235
-0x0cedc547 # 71.197.237.12
-0x23d3e15e # 94.225.211.35
-0xa5a81318 # 24.19.168.165
-0x179a32c6 # 198.50.154.23
-0xe4d3483d # 61.72.211.228
-0x03680905 # 5.9.104.3
-0xe8018abc # 188.138.1.232
-0xdde9ef5b # 91.239.233.221
-0x438b8705 # 5.135.139.67
-0xb48224a0 # 160.36.130.180
-0xcbd69218 # 24.146.214.203
-0x9075795b # 91.121.117.144
-0xc6411c3e # 62.28.65.198
-0x03833f5c # 92.63.131.3
-0xf33f8b5e # 94.139.63.243
-0x495e464b # 75.70.94.73
-0x83c8e65b # 91.230.200.131
-0xac09cd25 # 37.205.9.172
-0xdaabc547 # 71.197.171.218
-0x7665a553 # 83.165.101.118
-0xc5263718 # 24.55.38.197
-0x2fd0c5cd # 205.197.208.47
-0x22224d61 # 97.77.34.34
-0x3e954048 # 72.64.149.62
-0xfaa37557 # 87.117.163.250
-0x36dbc658 # 88.198.219.54
-0xa81453d0 # 208.83.20.168
-0x5a941f5d # 93.31.148.90
-0xa598ea60 # 96.234.152.165
-0x65384ac6 # 198.74.56.101
-0x10aaa545 # 69.165.170.16
-0xaaab795b # 91.121.171.170
-0xdda7024c # 76.2.167.221
-0x0966f4c6 # 198.244.102.9
-0x68571c08 # 8.28.87.104
-0x8b40ee59 # 89.238.64.139
-0x33ac096c # 108.9.172.51
-0x844b4c4b # 75.76.75.132
-0xd392254d # 77.37.146.211
-0xba4d5a46 # 70.90.77.186
-0x63029653 # 83.150.2.99
-0xf655f636 # 54.246.85.246
-0xbe4c4bb1 # 177.75.76.190
-0x45dad036 # 54.208.218.69
-0x204bc052 # 82.192.75.32
-0x06c3a2b2 # 178.162.195.6
-0xf31fba6a # 106.186.31.243
-0xb21f09b0 # 176.9.31.178
-0x540d0751 # 81.7.13.84
-0xc7b46a57 # 87.106.180.199
-0x6a11795b # 91.121.17.106
-0x3d514045 # 69.64.81.61
-0x0318aa6d # 109.170.24.3
-0x30306ec3 # 195.110.48.48
-0x5c077432 # 50.116.7.92
-0x259ae46d # 109.228.154.37
-0x82bbd35f # 95.211.187.130
-0xae4222c0 # 192.34.66.174
-0x254415d4 # 212.21.68.37
-0xbd5f574b # 75.87.95.189
-0xd8fd175e # 94.23.253.216
-0x0a3f38c3 # 195.56.63.10
-0x2dce6bb8 # 184.107.206.45
-0xc201d058 # 88.208.1.194
-0x17fca5bc # 188.165.252.23
-0xe8453cca # 202.60.69.232
-0xd361f636 # 54.246.97.211
-0xa0d9edc0 # 192.237.217.160
-0x2f232e4e # 78.46.35.47
-0x134e116c # 108.17.78.19
-0x61ddc058 # 88.192.221.97
-0x05ba7283 # 131.114.186.5
-0xe1f7ed5b # 91.237.247.225
-0x040ec452 # 82.196.14.4
-0x4b672e4e # 78.46.103.75
-0xe4efa36d # 109.163.239.228
-0x47dca52e # 46.165.220.71
-0xe9332e4e # 78.46.51.233
-0xa3acb992 # 146.185.172.163
-0x24714c90 # 144.76.113.36
-0xa8cc8632 # 50.134.204.168
-0x26b1ce6d # 109.206.177.38
-0x264e53d4 # 212.83.78.38
-0xd3d2718c # 140.113.210.211
-0x225534ad # 173.52.85.34
-0xe289f3a2 # 162.243.137.226
-0x87341717 # 23.23.52.135
-0x9255ad4f # 79.173.85.146
-0x184bbb25 # 37.187.75.24
-0x885c7abc # 188.122.92.136
-0x3a6e9ac6 # 198.154.110.58
-0x1924185e # 94.24.36.25
-0xb73d4c90 # 144.76.61.183
-0x946d807a # 122.128.109.148
-0xa0d78e3f # 63.142.215.160
-0x5a16bb25 # 37.187.22.90
-0xcb09795b # 91.121.9.203
-0x8d0de657 # 87.230.13.141
-0x630b8b25 # 37.139.11.99
-0xe572c6cf # 207.198.114.229
-0x2b3f1118 # 24.17.63.43
-0x4242a91f # 31.169.66.66
-0x32990905 # 5.9.153.50
-0x058b0905 # 5.9.139.5
-0xe266fc60 # 96.252.102.226
-0xbe66c5b0 # 176.197.102.190
-0xcc98e46d # 109.228.152.204
-0x698c943e # 62.148.140.105
-0x44bd0cc3 # 195.12.189.68
-0x865c7abc # 188.122.92.134
-0x771764d3 # 211.100.23.119
-0x4675d655 # 85.214.117.70
-0x354e4826 # 38.72.78.53
-0xb67ac152 # 82.193.122.182
-0xaeccf285 # 133.242.204.174
-0xea625b4e # 78.91.98.234
-0xbcd6031f # 31.3.214.188
-0x5e81eb18 # 24.235.129.94
-0x74b347ce # 206.71.179.116
-0x3ca56ac1 # 193.106.165.60
-0x54ee4546 # 70.69.238.84
-0x38a8175e # 94.23.168.56
-0xa3c21155 # 85.17.194.163
-0x2f01576d # 109.87.1.47
-0x5d7ade50 # 80.222.122.93
-0xa003ae48 # 72.174.3.160
-0x2bc1d31f # 31.211.193.43
-0x13f5094c # 76.9.245.19
-0x7ab32648 # 72.38.179.122
-0x542e9fd5 # 213.159.46.84
-0x53136bc1 # 193.107.19.83
-0x7fdf51c0 # 192.81.223.127
-0x802197b2 # 178.151.33.128
-0xa2d2cc5b # 91.204.210.162
-0x6b5f4bc0 # 192.75.95.107
+# IPv4 nodes (generated using contrib/seeds/makeseeds.py)
+1.33.197.110
+1.34.180.245
+1.202.128.218
+2.35.195.25
+5.100.123.19
+5.175.145.169
+5.199.133.193
+5.199.151.10
+5.228.1.230
+14.200.200.145
+18.228.0.188
+18.228.0.200
+23.30.243.153
+23.88.232.49
+23.99.105.9
+23.226.137.208
+23.227.177.161
+23.227.191.50
+23.229.45.32
+23.236.144.69
+23.253.148.113
+23.253.241.22
+23.255.227.231
+24.20.205.222
+24.23.120.252
+24.94.98.96
+24.98.95.201
+24.111.90.55
+24.119.119.105
+24.138.25.149
+31.3.214.45
+31.186.87.46
+31.186.101.98
+31.186.250.186
+31.204.153.107
+37.44.16.231
+37.44.44.11
+37.120.168.204
+37.143.86.26
+37.187.75.24
+37.188.68.169
+37.192.95.150
+37.201.246.116
+37.205.10.140
+46.10.210.17
+46.19.138.154
+46.28.204.123
+46.28.205.67
+46.38.235.229
+46.163.76.230
+46.166.162.91
+46.173.190.50
+46.227.66.132
+46.229.238.187
+46.236.116.209
+47.55.14.65
+50.7.252.229
+50.46.159.91
+50.78.49.181
+50.78.231.57
+50.79.153.65
+50.116.34.44
+50.126.86.253
+50.142.41.23
+50.199.113.193
+50.200.78.107
+50.206.138.177
+50.252.52.49
+54.165.25.75
+54.169.107.40
+54.179.190.56
+54.187.82.121
+54.246.85.246
+58.74.7.205
+58.96.183.121
+61.62.58.38
+61.63.91.72
+61.63.91.112
+61.72.211.228
+62.43.40.154
+62.43.130.178
+62.80.185.213
+62.109.49.26
+62.173.139.58
+62.181.238.186
+62.210.114.127
+63.141.228.138
+63.153.213.78
+63.223.84.145
+63.251.88.112
+64.31.110.50
+64.34.121.45
+64.114.6.42
+64.140.125.98
+64.156.193.100
+65.30.47.116
+65.35.132.177
+65.96.193.165
+65.111.189.26
+66.68.10.30
+66.114.33.250
+66.130.46.63
+66.175.215.135
+66.190.253.165
+66.194.38.254
+66.244.98.111
+67.162.238.30
+67.169.255.17
+67.183.173.25
+67.219.233.140
+67.227.240.115
+67.247.222.71
+68.43.114.66
+68.52.33.36
+68.198.245.241
+69.12.226.165
+69.13.198.188
+69.15.179.62
+69.39.239.47
+69.47.45.87
+69.62.217.206
+69.64.42.31
+69.64.81.61
+69.67.219.200
+69.90.132.157
+69.94.30.177
+69.136.175.241
+70.61.97.228
+70.123.118.132
+71.59.152.182
+71.198.248.151
+71.200.242.89
+71.225.179.157
+72.14.187.51
+72.38.34.180
+72.52.72.187
+72.91.144.182
+72.167.49.217
+72.201.243.55
+72.223.60.249
+72.228.153.102
+73.26.101.228
+73.50.158.200
+73.181.204.170
+74.57.199.180
+74.63.222.226
+74.81.231.21
+74.193.126.82
+74.207.235.164
+75.83.197.114
+75.144.114.9
+76.112.5.247
+76.174.20.247
+77.37.240.142
+77.57.202.107
+77.172.123.53
+77.221.91.253
+77.235.48.48
+77.245.78.2
+78.8.58.249
+78.27.191.182
+78.129.236.141
+78.131.88.47
+78.157.205.6
+79.132.230.144
+79.143.188.155
+79.160.221.140
+79.161.111.114
+80.100.189.3
+80.147.140.121
+80.203.75.133
+80.220.99.227
+80.222.20.169
+80.241.1.7
+81.23.191.243
+81.38.11.202
+81.80.9.71
+81.110.213.165
+81.133.155.237
+81.171.34.37
+81.181.155.180
+82.39.156.137
+82.73.161.95
+82.130.45.40
+82.165.153.47
+82.168.128.133
+82.179.225.118
+82.194.245.158
+82.199.102.10
+82.211.30.243
+82.217.133.145
+82.221.128.35
+82.221.131.177
+82.233.225.205
+83.0.249.146
+83.89.31.249
+83.128.29.231
+83.128.253.142
+83.143.130.56
+83.150.2.99
+83.150.9.196
+83.161.64.45
+83.212.103.212
+83.212.111.114
+83.246.75.8
+83.254.81.31
+83.254.150.54
+84.2.34.104
+84.15.61.60
+84.17.25.135
+84.42.144.19
+84.212.210.135
+84.215.165.231
+84.238.140.176
+84.240.31.184
+85.25.214.137
+85.139.163.132
+85.199.4.228
+85.214.61.209
+85.214.108.77
+86.123.16.17
+87.48.42.199
+87.104.168.104
+87.229.73.171
+87.236.196.77
+88.97.56.98
+88.134.178.89
+88.150.233.19
+88.168.133.3
+88.208.18.246
+88.208.33.202
+89.18.28.21
+89.85.220.84
+89.163.227.28
+89.184.83.60
+89.231.96.83
+89.236.49.117
+91.90.66.209
+91.106.194.97
+91.134.75.115
+91.152.193.36
+91.152.219.35
+91.197.10.234
+91.209.77.101
+91.210.106.147
+91.214.200.205
+91.223.115.38
+91.234.48.232
+91.250.86.18
+92.27.7.209
+92.255.207.73
+93.74.163.234
+93.84.114.106
+93.152.166.29
+93.171.216.221
+93.185.177.71
+94.19.12.244
+94.42.115.50
+94.79.177.206
+94.136.147.119
+94.143.245.5
+94.188.50.39
+94.190.227.112
+94.198.135.29
+94.226.107.86
+94.242.219.90
+94.242.229.168
+94.244.160.84
+95.31.10.209
+95.85.25.41
+95.105.161.136
+95.154.165.45
+95.154.200.216
+95.167.109.125
+95.211.125.231
+95.211.216.235
+96.33.25.17
+96.43.130.178
+97.118.8.236
+98.102.6.125
+98.202.20.45
+98.217.125.225
+98.234.210.111
+98.237.20.123
+98.255.144.176
+99.113.64.43
+99.229.22.8
+103.1.212.19
+103.30.42.189
+103.224.165.48
+103.243.94.140
+104.131.107.107
+104.131.116.184
+104.143.0.156
+104.219.184.9
+106.185.38.174
+107.6.4.145
+107.150.8.27
+107.150.33.20
+107.170.228.129
+107.170.240.173
+108.51.20.86
+108.61.149.222
+108.61.151.172
+108.161.129.247
+108.170.140.21
+109.60.211.216
+109.73.42.36
+109.73.172.138
+109.163.235.239
+109.190.196.220
+109.201.135.216
+109.228.152.2
+109.228.154.81
+109.230.220.125
+109.234.156.218
+109.235.49.27
+109.235.69.84
+112.124.71.0
+113.146.68.251
+115.29.17.82
+115.70.176.17
+117.41.162.184
+118.27.8.170
+119.230.7.211
+119.246.71.52
+121.172.8.100
+122.128.109.148
+123.231.224.63
+128.175.195.31
+128.199.164.96
+128.199.254.244
+129.97.69.76
+129.123.7.7
+129.123.7.39
+129.186.17.17
+131.247.169.190
+133.242.209.63
+134.102.94.38
+134.119.17.145
+137.116.160.176
+137.226.34.42
+138.210.217.170
+141.255.166.194
+143.215.129.126
+144.76.244.19
+146.148.52.162
+146.148.80.57
+146.185.19.30
+146.185.142.86
+146.185.253.51
+148.251.6.214
+149.154.155.235
+149.210.133.244
+151.224.248.252
+153.121.75.229
+153.127.251.67
+154.20.2.139
+157.13.61.5
+158.58.173.48
+159.253.23.132
+162.209.110.218
+162.213.254.205
+162.239.254.100
+162.242.150.39
+162.243.81.138
+162.243.235.56
+162.244.79.16
+162.245.217.119
+162.248.102.117
+162.251.108.53
+162.254.149.139
+162.255.116.78
+166.70.94.106
+167.88.45.124
+167.88.120.210
+173.26.49.43
+173.30.14.6
+173.80.114.197
+173.167.214.243
+173.208.219.108
+173.220.67.156
+173.236.101.34
+173.246.107.34
+173.255.237.241
+174.2.213.209
+174.51.23.224
+174.51.123.159
+174.57.212.121
+174.109.33.28
+175.126.124.91
+175.126.124.92
+176.10.116.242
+176.36.35.126
+176.36.99.222
+176.124.110.47
+176.194.33.44
+176.223.201.198
+178.62.26.83
+178.62.36.48
+178.62.212.141
+178.62.254.59
+178.78.250.3
+178.155.86.226
+178.175.134.35
+178.248.111.4
+178.254.1.170
+178.254.34.161
+179.43.114.14
+182.213.208.28
+184.68.2.46
+184.72.238.42
+184.94.226.34
+184.94.227.58
+184.107.139.58
+184.107.206.45
+185.10.48.117
+185.21.216.156
+185.38.47.224
+185.45.192.129
+185.53.129.230
+185.53.131.114
+185.55.53.61
+185.55.53.63
+185.61.119.2
+185.61.148.203
+186.2.167.23
+188.92.75.178
+188.122.92.134
+188.138.9.208
+188.165.209.148
+188.226.206.239
+190.10.8.124
+190.10.10.147
+192.0.130.142
+192.3.89.159
+192.73.234.138
+192.75.95.107
+192.95.100.102
+192.155.84.181
+192.169.233.206
+192.198.93.86
+192.227.135.216
+193.0.109.3
+193.77.50.208
+193.109.68.62
+193.150.121.37
+193.224.69.98
+194.79.8.37
+194.141.86.10
+195.12.180.94
+195.56.63.10
+195.116.93.93
+195.154.174.226
+195.159.111.98
+195.169.138.2
+195.189.126.35
+195.197.175.190
+197.242.93.82
+198.11.214.147
+198.49.41.21
+199.33.124.186
+199.204.186.146
+199.233.238.115
+199.241.189.66
+202.60.68.242
+202.60.69.232
+203.183.151.39
+203.219.14.204
+204.44.123.109
+204.44.123.162
+204.45.120.178
+206.190.134.44
+206.248.184.127
+207.244.73.8
+208.66.30.27
+209.81.9.223
+209.105.243.229
+209.126.70.159
+209.140.30.169
+209.165.128.235
+209.190.2.242
+210.66.254.236
+210.73.27.33
+211.72.66.229
+212.25.37.124
+212.71.235.114
+212.71.252.109
+212.114.48.31
+212.174.151.118
+213.66.205.194
+213.129.248.139
+213.136.87.34
+213.165.82.133
+213.167.17.6
+213.179.158.253
+213.189.53.125
+213.222.208.93
+216.49.158.161
+216.55.143.154
+216.131.91.100
+216.245.206.181
+216.250.138.230
+217.11.225.189
+217.23.6.133
+217.75.88.178
+217.172.143.140
+217.195.169.209
+217.196.248.106
+219.138.161.162
+222.167.248.90
+223.18.254.55
# Onion nodes
bitcoinostk4e4re.onion:8333
# Make is not made aware of per-object dependencies to avoid limiting building parallelization
# But to build the less dependent modules first, we manually select their order here:
-noinst_LIBRARIES = \
+EXTRA_LIBRARIES = \
crypto/libbitcoin_crypto.a \
libbitcoin_util.a \
libbitcoin_common.a \
libbitcoin_cli.a
if ENABLE_WALLET
BITCOIN_INCLUDES += $(BDB_CPPFLAGS)
-noinst_LIBRARIES += libbitcoin_wallet.a
+EXTRA_LIBRARIES += libbitcoin_wallet.a
endif
if BUILD_BITCOIN_LIBS
alert.h \
allocators.h \
amount.h \
+ arith_uint256.h \
base58.h \
bloom.h \
chain.h \
- chainparams.h \
chainparamsbase.h \
+ chainparams.h \
chainparamsseeds.h \
checkpoints.h \
checkqueue.h \
coins.h \
compat.h \
compressor.h \
- core/block.h \
- core/transaction.h \
core_io.h \
crypter.h \
db.h \
leveldbwrapper.h \
limitedmap.h \
main.h \
+ merkleblock.h \
miner.h \
mruset.h \
netbase.h \
net.h \
noui.h \
pow.h \
+ primitives/block.h \
+ primitives/transaction.h \
protocol.h \
pubkey.h \
random.h \
rpcprotocol.h \
rpcserver.h \
script/interpreter.h \
+ script/script_error.h \
script/script.h \
script/sigcache.h \
script/sign.h \
script/standard.h \
- script/script_error.h \
serialize.h \
streams.h \
+ support/cleanse.h \
sync.h \
threadsafety.h \
timedata.h \
uint256.h \
undo.h \
util.h \
- utilstrencodings.h \
utilmoneystr.h \
+ utilstrencodings.h \
utiltime.h \
version.h \
+ walletdb.h \
wallet.h \
wallet_ismine.h \
- walletdb.h \
+ compat/byteswap.h \
+ compat/endian.h \
compat/sanity.h
JSON_H = \
init.cpp \
leveldbwrapper.cpp \
main.cpp \
+ merkleblock.cpp \
miner.cpp \
net.cpp \
noui.cpp \
crypto_libbitcoin_crypto_a_CPPFLAGS = $(BITCOIN_CONFIG_INCLUDES)
crypto_libbitcoin_crypto_a_SOURCES = \
crypto/sha1.cpp \
- crypto/sha2.cpp \
+ crypto/sha256.cpp \
+ crypto/sha512.cpp \
+ crypto/hmac_sha256.cpp \
+ crypto/hmac_sha512.cpp \
crypto/ripemd160.cpp \
crypto/common.h \
- crypto/sha2.h \
+ crypto/sha256.h \
+ crypto/sha512.h \
+ crypto/hmac_sha256.h \
+ crypto/hmac_sha512.h \
crypto/sha1.h \
crypto/ripemd160.h
libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_common_a_SOURCES = \
allocators.cpp \
+ arith_uint256.cpp \
amount.cpp \
base58.cpp \
chainparams.cpp \
coins.cpp \
compressor.cpp \
- core/block.cpp \
- core/transaction.cpp \
+ primitives/block.cpp \
+ primitives/transaction.cpp \
core_read.cpp \
core_write.cpp \
eccryptoverify.cpp \
# backward-compatibility objects and their sanity checks are linked.
libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_util_a_SOURCES = \
- compat/glibc_sanity.cpp \
- compat/glibcxx_sanity.cpp \
chainparamsbase.cpp \
clientversion.cpp \
+ compat/glibc_sanity.cpp \
+ compat/glibcxx_sanity.cpp \
+ compat/strnlen.cpp \
random.cpp \
rpcprotocol.cpp \
+ support/cleanse.cpp \
sync.cpp \
uint256.cpp \
util.cpp \
- utilstrencodings.cpp \
utilmoneystr.cpp \
+ utilstrencodings.cpp \
utiltime.cpp \
$(BITCOIN_CORE_H)
if GLIBC_BACK_COMPAT
libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
-libbitcoin_util_a_SOURCES += compat/glibcxx_compat.cpp
endif
# cli: shared between bitcoin-cli and bitcoin-qt
#
# bitcoind binary #
+bitcoind_SOURCES = bitcoind.cpp
+bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+
+if TARGET_WINDOWS
+bitcoind_SOURCES += bitcoind-res.rc
+endif
+
bitcoind_LDADD = \
$(LIBBITCOIN_SERVER) \
$(LIBBITCOIN_COMMON) \
if ENABLE_WALLET
bitcoind_LDADD += libbitcoin_wallet.a
endif
-bitcoind_SOURCES = bitcoind.cpp
+
+bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
#
+# bitcoin-cli binary #
+bitcoin_cli_SOURCES = bitcoin-cli.cpp
+bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+
if TARGET_WINDOWS
-bitcoind_SOURCES += bitcoind-res.rc
+bitcoin_cli_SOURCES += bitcoin-cli-res.rc
endif
-bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
-bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES)
-bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
-
-# bitcoin-cli binary #
bitcoin_cli_LDADD = \
$(LIBBITCOIN_CLI) \
$(LIBBITCOIN_UTIL) \
- $(BOOST_LIBS) \
- $(SSL_LIBS) \
- $(CRYPTO_LIBS)
-
-bitcoin_cli_SOURCES = \
- bitcoin-cli.cpp
+ $(LIBSECP256K1)
-bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS)
#
# bitcoin-tx binary #
+bitcoin_tx_SOURCES = bitcoin-tx.cpp
+bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
+
bitcoin_tx_LDADD = \
$(LIBBITCOIN_UNIVALUE) \
$(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO) \
- $(LIBSECP256K1) \
- $(BOOST_LIBS) \
- $(CRYPTO_LIBS)
+ $(LIBSECP256K1)
-bitcoin_tx_SOURCES = bitcoin-tx.cpp
-bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES)
+bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
#
-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) $(LIBTOOL_APP_LDFLAGS)
+# bitcoinconsensus library #
if BUILD_BITCOIN_LIBS
include_HEADERS = script/bitcoinconsensus.h
libbitcoinconsensus_la_SOURCES = \
- core/transaction.cpp \
- crypto/sha1.cpp \
- crypto/sha2.cpp \
+ crypto/hmac_sha512.cpp \
crypto/ripemd160.cpp \
+ crypto/sha1.cpp \
+ crypto/sha256.cpp \
+ crypto/sha512.cpp \
eccryptoverify.cpp \
ecwrapper.cpp \
hash.cpp \
+ primitives/transaction.cpp \
pubkey.cpp \
- script/script.cpp \
- script/interpreter.cpp \
script/bitcoinconsensus.cpp \
+ script/interpreter.cpp \
+ script/script.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
bin_PROGRAMS += qt/bitcoin-qt
-noinst_LIBRARIES += qt/libbitcoinqt.a
+EXTRA_LIBRARIES += qt/libbitcoinqt.a
# bitcoin qt core #
QT_TS = \
qt/receiverequestdialog.h \
qt/recentrequeststablemodel.h \
qt/rpcconsole.h \
+ qt/scicon.h \
qt/sendcoinsdialog.h \
qt/sendcoinsentry.h \
qt/signverifymessagedialog.h \
RES_ICONS = \
qt/res/icons/add.png \
qt/res/icons/address-book.png \
+ qt/res/icons/about.png \
+ qt/res/icons/about_qt.png \
qt/res/icons/bitcoin.ico \
qt/res/icons/bitcoin.png \
- qt/res/icons/bitcoin_testnet.ico \
- qt/res/icons/bitcoin_testnet.png \
qt/res/icons/clock1.png \
qt/res/icons/clock2.png \
qt/res/icons/clock3.png \
qt/res/icons/clock4.png \
qt/res/icons/clock5.png \
qt/res/icons/configure.png \
- qt/res/icons/connect0_16.png \
- qt/res/icons/connect1_16.png \
- qt/res/icons/connect2_16.png \
- qt/res/icons/connect3_16.png \
- qt/res/icons/connect4_16.png \
+ qt/res/icons/connect0.png \
+ qt/res/icons/connect1.png \
+ qt/res/icons/connect2.png \
+ qt/res/icons/connect3.png \
+ qt/res/icons/connect4.png \
qt/res/icons/debugwindow.png \
qt/res/icons/edit.png \
qt/res/icons/editcopy.png \
qt/res/icons/eye_plus.png \
qt/res/icons/filesave.png \
qt/res/icons/history.png \
+ qt/res/icons/info.png \
qt/res/icons/key.png \
qt/res/icons/lock_closed.png \
qt/res/icons/lock_open.png \
+ qt/res/icons/open.png \
qt/res/icons/overview.png \
- qt/res/icons/qrcode.png \
qt/res/icons/quit.png \
qt/res/icons/receive.png \
qt/res/icons/remove.png \
qt/res/icons/tx_input.png \
qt/res/icons/tx_output.png \
qt/res/icons/tx_mined.png \
- qt/res/icons/unit_btc.png \
- qt/res/icons/unit_mbtc.png \
- qt/res/icons/unit_ubtc.png
+ qt/res/icons/verify.png
BITCOIN_QT_CPP = \
qt/bitcoinaddressvalidator.cpp \
qt/qvalidatedlineedit.cpp \
qt/qvaluecombobox.cpp \
qt/rpcconsole.cpp \
+ qt/scicon.cpp \
qt/splashscreen.cpp \
qt/trafficgraphwidget.cpp \
- qt/utilitydialog.cpp \
- qt/winshutdownmonitor.cpp
+ qt/utilitydialog.cpp
+
+if TARGET_WINDOWS
+BITCOIN_QT_CPP += qt/winshutdownmonitor.cpp
+endif
if ENABLE_WALLET
BITCOIN_QT_CPP += \
qt/walletview.cpp
endif
-RES_IMAGES = \
- qt/res/images/about.png \
- qt/res/images/splash.png \
- qt/res/images/splash_testnet.png
+RES_IMAGES =
RES_MOVIES = $(wildcard qt/res/movies/spinner-*.png)
#locale/foo.ts -> locale/foo.qm
QT_QM=$(QT_TS:.ts=.qm)
-.SECONDARY: $(QT_QM)
+SECONDARY: $(QT_QM)
qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES)
@test -n $(XGETTEXT) || echo "xgettext is required for updating translations"
-TESTS += test/test_bitcoin test/bitcoin-util-test.py
+TESTS += test/test_bitcoin
bin_PROGRAMS += test/test_bitcoin
TEST_SRCDIR = test
TEST_BINARY=test/test_bitcoin$(EXEEXT)
test/data/tt-locktime317000-out.hex \
test/data/tx394b54bb.hex \
test/data/txcreate1.hex \
- test/data/txcreate2.hex
+ test/data/txcreate2.hex \
+ test/data/txcreatesign.hex
JSON_TEST_FILES = \
test/data/script_valid.json \
test/data/base58_keys_valid.json \
- test/data/sig_canonical.json \
- test/data/sig_noncanonical.json \
test/data/base58_encode_decode.json \
test/data/base58_keys_invalid.json \
test/data/script_invalid.json \
GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h)
BITCOIN_TESTS =\
+ test/arith_uint256_tests.cpp \
test/bignum.h \
test/alert_tests.cpp \
test/allocator_tests.cpp \
test/multisig_tests.cpp \
test/netbase_tests.cpp \
test/pmt_tests.cpp \
+ test/pow_tests.cpp \
test/rpc_tests.cpp \
+ test/sanity_tests.cpp \
test/script_P2SH_tests.cpp \
test/script_tests.cpp \
test/scriptnum_tests.cpp \
test/sigopcount_tests.cpp \
test/skiplist_tests.cpp \
test/test_bitcoin.cpp \
+ test/test_bitcoin.h \
test/timedata_tests.cpp \
test/transaction_tests.cpp \
test/uint256_tests.cpp \
rm -f $(CLEAN_BITCOIN_TEST) $(test_test_bitcoin_OBJECTS) $(TEST_BINARY)
check-local:
+ @echo "Running test/bitcoin-util-test.py..."
+ $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(srcdir)/test/bitcoin-util-test.py
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check
%.json.h: %.json
CDataStream ss1(SER_GETHASH, 0);
std::vector<unsigned char> vchKey = GetKey();
ss1 << nKey << vchKey;
- uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetLow64();
+ uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash();
CDataStream ss2(SER_GETHASH, 0);
std::vector<unsigned char> vchGroupKey = GetGroup();
ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP);
- uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetLow64();
+ uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash();
return hash2 % ADDRMAN_TRIED_BUCKET_COUNT;
}
std::vector<unsigned char> vchGroupKey = GetGroup();
std::vector<unsigned char> vchSourceGroupKey = src.GetGroup();
ss1 << nKey << vchGroupKey << vchSourceGroupKey;
- uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetLow64();
+ uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetCheapHash();
CDataStream ss2(SER_GETHASH, 0);
ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP);
- uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetLow64();
+ uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetCheapHash();
return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
}
// update info
info.nLastSuccess = nTime;
info.nLastTry = nTime;
- info.nTime = nTime;
info.nAttempts = 0;
+ // nTime is not updated here, to avoid leaking information about
+ // currently-connected peers.
// if it is already in the tried set, don't do anything else
if (info.fInTried)
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
{
CPubKey key(Params().AlertKey());
if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
- return error("CAlert::CheckSignature() : verify signature failed");
+ return error("CAlert::CheckSignature(): verify signature failed");
// Now unserialize the data
CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION);
// 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-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_ALERT_H
-// Copyright (c) 2009-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "allocators.h"
// 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-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_ALLOCATORS_H
#define BITCOIN_ALLOCATORS_H
+#include "support/cleanse.h"
+
#include <map>
#include <string>
#include <string.h>
#include <boost/thread/mutex.hpp>
#include <boost/thread/once.hpp>
-#include <openssl/crypto.h> // for OPENSSL_cleanse()
-
/**
* Thread-safe class to keep track of locked (ie, non-swappable) memory pages.
*
template <typename T>
void UnlockObject(const T& t)
{
- OPENSSL_cleanse((void*)(&t), sizeof(T));
+ memory_cleanse((void*)(&t), sizeof(T));
LockedPageManager::Instance().UnlockRange((void*)(&t), sizeof(T));
}
void deallocate(T* p, std::size_t n)
{
if (p != NULL) {
- OPENSSL_cleanse(p, sizeof(T) * n);
+ memory_cleanse(p, sizeof(T) * n);
LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n);
}
std::allocator<T>::deallocate(p, n);
void deallocate(T* p, std::size_t n)
{
if (p != NULL)
- OPENSSL_cleanse(p, sizeof(T) * n);
+ memory_cleanse(p, sizeof(T) * n);
std::allocator<T>::deallocate(p, n);
}
};
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
--- /dev/null
+// 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 "arith_uint256.h"
+
+#include "uint256.h"
+#include "utilstrencodings.h"
+#include "crypto/common.h"
+
+#include <stdio.h>
+#include <string.h>
+
+template <unsigned int BITS>
+base_uint<BITS>::base_uint(const std::string& str)
+{
+ SetHex(str);
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator<<=(unsigned int shift)
+{
+ base_uint<BITS> a(*this);
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] = 0;
+ int k = shift / 32;
+ shift = shift % 32;
+ for (int i = 0; i < WIDTH; i++) {
+ if (i + k + 1 < WIDTH && shift != 0)
+ pn[i + k + 1] |= (a.pn[i] >> (32 - shift));
+ if (i + k < WIDTH)
+ pn[i + k] |= (a.pn[i] << shift);
+ }
+ return *this;
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator>>=(unsigned int shift)
+{
+ base_uint<BITS> a(*this);
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] = 0;
+ int k = shift / 32;
+ shift = shift % 32;
+ for (int i = 0; i < WIDTH; i++) {
+ if (i - k - 1 >= 0 && shift != 0)
+ pn[i - k - 1] |= (a.pn[i] << (32 - shift));
+ if (i - k >= 0)
+ pn[i - k] |= (a.pn[i] >> shift);
+ }
+ return *this;
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator*=(uint32_t b32)
+{
+ uint64_t carry = 0;
+ for (int i = 0; i < WIDTH; i++) {
+ uint64_t n = carry + (uint64_t)b32 * pn[i];
+ pn[i] = n & 0xffffffff;
+ carry = n >> 32;
+ }
+ return *this;
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator*=(const base_uint& b)
+{
+ base_uint<BITS> a = *this;
+ *this = 0;
+ for (int j = 0; j < WIDTH; j++) {
+ uint64_t carry = 0;
+ for (int i = 0; i + j < WIDTH; i++) {
+ uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i];
+ pn[i + j] = n & 0xffffffff;
+ carry = n >> 32;
+ }
+ }
+ return *this;
+}
+
+template <unsigned int BITS>
+base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b)
+{
+ base_uint<BITS> div = b; // make a copy, so we can shift.
+ base_uint<BITS> num = *this; // make a copy, so we can subtract.
+ *this = 0; // the quotient.
+ int num_bits = num.bits();
+ int div_bits = div.bits();
+ if (div_bits == 0)
+ throw uint_error("Division by zero");
+ if (div_bits > num_bits) // the result is certainly 0.
+ return *this;
+ int shift = num_bits - div_bits;
+ div <<= shift; // shift so that div and num align.
+ while (shift >= 0) {
+ if (num >= div) {
+ num -= div;
+ pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result.
+ }
+ div >>= 1; // shift back.
+ shift--;
+ }
+ // num now contains the remainder of the division.
+ return *this;
+}
+
+template <unsigned int BITS>
+int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const
+{
+ for (int i = WIDTH - 1; i >= 0; i--) {
+ if (pn[i] < b.pn[i])
+ return -1;
+ if (pn[i] > b.pn[i])
+ return 1;
+ }
+ return 0;
+}
+
+template <unsigned int BITS>
+bool base_uint<BITS>::EqualTo(uint64_t b) const
+{
+ for (int i = WIDTH - 1; i >= 2; i--) {
+ if (pn[i])
+ return false;
+ }
+ if (pn[1] != (b >> 32))
+ return false;
+ if (pn[0] != (b & 0xfffffffful))
+ return false;
+ return true;
+}
+
+template <unsigned int BITS>
+double base_uint<BITS>::getdouble() const
+{
+ double ret = 0.0;
+ double fact = 1.0;
+ for (int i = 0; i < WIDTH; i++) {
+ ret += fact * pn[i];
+ fact *= 4294967296.0;
+ }
+ return ret;
+}
+
+template <unsigned int BITS>
+std::string base_uint<BITS>::GetHex() const
+{
+ return ArithToUint256(*this).GetHex();
+}
+
+template <unsigned int BITS>
+void base_uint<BITS>::SetHex(const char* psz)
+{
+ *this = UintToArith256(uint256S(psz));
+}
+
+template <unsigned int BITS>
+void base_uint<BITS>::SetHex(const std::string& str)
+{
+ SetHex(str.c_str());
+}
+
+template <unsigned int BITS>
+std::string base_uint<BITS>::ToString() const
+{
+ return (GetHex());
+}
+
+template <unsigned int BITS>
+unsigned int base_uint<BITS>::bits() const
+{
+ for (int pos = WIDTH - 1; pos >= 0; pos--) {
+ if (pn[pos]) {
+ for (int bits = 31; bits > 0; bits--) {
+ if (pn[pos] & 1 << bits)
+ return 32 * pos + bits + 1;
+ }
+ return 32 * pos + 1;
+ }
+ }
+ return 0;
+}
+
+// Explicit instantiations for base_uint<256>
+template base_uint<256>::base_uint(const std::string&);
+template base_uint<256>& base_uint<256>::operator<<=(unsigned int);
+template base_uint<256>& base_uint<256>::operator>>=(unsigned int);
+template base_uint<256>& base_uint<256>::operator*=(uint32_t b32);
+template base_uint<256>& base_uint<256>::operator*=(const base_uint<256>& b);
+template base_uint<256>& base_uint<256>::operator/=(const base_uint<256>& b);
+template int base_uint<256>::CompareTo(const base_uint<256>&) const;
+template bool base_uint<256>::EqualTo(uint64_t) const;
+template double base_uint<256>::getdouble() const;
+template std::string base_uint<256>::GetHex() const;
+template std::string base_uint<256>::ToString() const;
+template void base_uint<256>::SetHex(const char*);
+template void base_uint<256>::SetHex(const std::string&);
+template unsigned int base_uint<256>::bits() const;
+
+// This implementation directly uses shifts instead of going
+// through an intermediate MPI representation.
+arith_uint256& arith_uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow)
+{
+ int nSize = nCompact >> 24;
+ uint32_t nWord = nCompact & 0x007fffff;
+ if (nSize <= 3) {
+ nWord >>= 8 * (3 - nSize);
+ *this = nWord;
+ } else {
+ *this = nWord;
+ *this <<= 8 * (nSize - 3);
+ }
+ if (pfNegative)
+ *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
+ if (pfOverflow)
+ *pfOverflow = nWord != 0 && ((nSize > 34) ||
+ (nWord > 0xff && nSize > 33) ||
+ (nWord > 0xffff && nSize > 32));
+ return *this;
+}
+
+uint32_t arith_uint256::GetCompact(bool fNegative) const
+{
+ int nSize = (bits() + 7) / 8;
+ uint32_t nCompact = 0;
+ if (nSize <= 3) {
+ nCompact = GetLow64() << 8 * (3 - nSize);
+ } else {
+ arith_uint256 bn = *this >> 8 * (nSize - 3);
+ nCompact = bn.GetLow64();
+ }
+ // The 0x00800000 bit denotes the sign.
+ // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
+ if (nCompact & 0x00800000) {
+ nCompact >>= 8;
+ nSize++;
+ }
+ assert((nCompact & ~0x007fffff) == 0);
+ assert(nSize < 256);
+ nCompact |= nSize << 24;
+ nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
+ return nCompact;
+}
+
+uint256 ArithToUint256(const arith_uint256 &a)
+{
+ uint256 b;
+ for(int x=0; x<a.WIDTH; ++x)
+ WriteLE32(b.begin() + x*4, a.pn[x]);
+ return b;
+}
+arith_uint256 UintToArith256(const uint256 &a)
+{
+ arith_uint256 b;
+ for(int x=0; x<b.WIDTH; ++x)
+ b.pn[x] = ReadLE32(a.begin() + x*4);
+ return b;
+}
--- /dev/null
+// 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_ARITH_UINT256_H
+#define BITCOIN_ARITH_UINT256_H
+
+#include <assert.h>
+#include <cstring>
+#include <stdexcept>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+class uint256;
+
+class uint_error : public std::runtime_error {
+public:
+ explicit uint_error(const std::string& str) : std::runtime_error(str) {}
+};
+
+/** Template base class for unsigned big integers. */
+template<unsigned int BITS>
+class base_uint
+{
+protected:
+ enum { WIDTH=BITS/32 };
+ uint32_t pn[WIDTH];
+public:
+
+ base_uint()
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] = 0;
+ }
+
+ base_uint(const base_uint& b)
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] = b.pn[i];
+ }
+
+ base_uint& operator=(const base_uint& b)
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] = b.pn[i];
+ return *this;
+ }
+
+ base_uint(uint64_t b)
+ {
+ pn[0] = (unsigned int)b;
+ pn[1] = (unsigned int)(b >> 32);
+ for (int i = 2; i < WIDTH; i++)
+ pn[i] = 0;
+ }
+
+ explicit base_uint(const std::string& str);
+
+ bool operator!() const
+ {
+ for (int i = 0; i < WIDTH; i++)
+ if (pn[i] != 0)
+ return false;
+ return true;
+ }
+
+ const base_uint operator~() const
+ {
+ base_uint ret;
+ for (int i = 0; i < WIDTH; i++)
+ ret.pn[i] = ~pn[i];
+ return ret;
+ }
+
+ const base_uint operator-() const
+ {
+ base_uint ret;
+ for (int i = 0; i < WIDTH; i++)
+ ret.pn[i] = ~pn[i];
+ ret++;
+ return ret;
+ }
+
+ double getdouble() const;
+
+ base_uint& operator=(uint64_t b)
+ {
+ pn[0] = (unsigned int)b;
+ pn[1] = (unsigned int)(b >> 32);
+ for (int i = 2; i < WIDTH; i++)
+ pn[i] = 0;
+ return *this;
+ }
+
+ base_uint& operator^=(const base_uint& b)
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] ^= b.pn[i];
+ return *this;
+ }
+
+ base_uint& operator&=(const base_uint& b)
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] &= b.pn[i];
+ return *this;
+ }
+
+ base_uint& operator|=(const base_uint& b)
+ {
+ for (int i = 0; i < WIDTH; i++)
+ pn[i] |= b.pn[i];
+ return *this;
+ }
+
+ base_uint& operator^=(uint64_t b)
+ {
+ pn[0] ^= (unsigned int)b;
+ pn[1] ^= (unsigned int)(b >> 32);
+ return *this;
+ }
+
+ base_uint& operator|=(uint64_t b)
+ {
+ pn[0] |= (unsigned int)b;
+ pn[1] |= (unsigned int)(b >> 32);
+ return *this;
+ }
+
+ base_uint& operator<<=(unsigned int shift);
+ base_uint& operator>>=(unsigned int shift);
+
+ base_uint& operator+=(const base_uint& b)
+ {
+ uint64_t carry = 0;
+ for (int i = 0; i < WIDTH; i++)
+ {
+ uint64_t n = carry + pn[i] + b.pn[i];
+ pn[i] = n & 0xffffffff;
+ carry = n >> 32;
+ }
+ return *this;
+ }
+
+ base_uint& operator-=(const base_uint& b)
+ {
+ *this += -b;
+ return *this;
+ }
+
+ base_uint& operator+=(uint64_t b64)
+ {
+ base_uint b;
+ b = b64;
+ *this += b;
+ return *this;
+ }
+
+ base_uint& operator-=(uint64_t b64)
+ {
+ base_uint b;
+ b = b64;
+ *this += -b;
+ return *this;
+ }
+
+ base_uint& operator*=(uint32_t b32);
+ base_uint& operator*=(const base_uint& b);
+ base_uint& operator/=(const base_uint& b);
+
+ base_uint& operator++()
+ {
+ // prefix operator
+ int i = 0;
+ while (++pn[i] == 0 && i < WIDTH-1)
+ i++;
+ return *this;
+ }
+
+ const base_uint operator++(int)
+ {
+ // postfix operator
+ const base_uint ret = *this;
+ ++(*this);
+ return ret;
+ }
+
+ base_uint& operator--()
+ {
+ // prefix operator
+ int i = 0;
+ while (--pn[i] == (uint32_t)-1 && i < WIDTH-1)
+ i++;
+ return *this;
+ }
+
+ const base_uint operator--(int)
+ {
+ // postfix operator
+ const base_uint ret = *this;
+ --(*this);
+ return ret;
+ }
+
+ int CompareTo(const base_uint& b) const;
+ bool EqualTo(uint64_t b) const;
+
+ friend inline const base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; }
+ friend inline const base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; }
+ friend inline const base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; }
+ friend inline const base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; }
+ friend inline const base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; }
+ friend inline const base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; }
+ friend inline const base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; }
+ friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; }
+ friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; }
+ friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; }
+ friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; }
+ friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; }
+ friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; }
+ friend inline bool operator<(const base_uint& a, const base_uint& b) { return a.CompareTo(b) < 0; }
+ friend inline bool operator>=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) >= 0; }
+ friend inline bool operator<=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) <= 0; }
+ friend inline bool operator==(const base_uint& a, uint64_t b) { return a.EqualTo(b); }
+ friend inline bool operator!=(const base_uint& a, uint64_t b) { return !a.EqualTo(b); }
+
+ std::string GetHex() const;
+ void SetHex(const char* psz);
+ void SetHex(const std::string& str);
+ std::string ToString() const;
+
+ unsigned int size() const
+ {
+ return sizeof(pn);
+ }
+
+ /**
+ * 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
+ {
+ assert(WIDTH >= 2);
+ return pn[0] | (uint64_t)pn[1] << 32;
+ }
+};
+
+/** 256-bit unsigned big integer. */
+class arith_uint256 : public base_uint<256> {
+public:
+ arith_uint256() {}
+ arith_uint256(const base_uint<256>& b) : base_uint<256>(b) {}
+ arith_uint256(uint64_t b) : base_uint<256>(b) {}
+ explicit arith_uint256(const std::string& str) : base_uint<256>(str) {}
+
+ /**
+ * 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.
+ */
+ arith_uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL);
+ uint32_t GetCompact(bool fNegative = false) const;
+
+ friend uint256 ArithToUint256(const arith_uint256 &);
+ friend arith_uint256 UintToArith256(const uint256 &);
+};
+
+uint256 ArithToUint256(const arith_uint256 &);
+arith_uint256 UintToArith256(const uint256 &);
+
+#endif // BITCOIN_UINT256_H
-// Copyright (c) 2014 The Bitcoin developers
+// 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.
vchData.resize(vchTemp.size() - nVersionBytes);
if (!vchData.empty())
memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
- OPENSSL_cleanse(&vchTemp[0], vchData.size());
+ memory_cleanse(&vchTemp[0], vchData.size());
return true;
}
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", "bitcoin-cli"
VALUE "LegalCopyright", COPYRIGHT_STR
- VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
+ VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
VALUE "OriginalFilename", "bitcoin-cli.exe"
VALUE "ProductName", "Bitcoin-cli"
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
// 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-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "chainparamsbase.h"
#define _(x) std::string(x) /* Keep the _() around in case gettext or such will be used later to translate non-UI */
using namespace std;
-using namespace boost;
-using namespace boost::asio;
using namespace json_spirit;
std::string HelpMessageCli()
{
string strUsage;
- strUsage += _("Options:") + "\n";
- strUsage += " -? " + _("This help message") + "\n";
- strUsage += " -conf=<file> " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n";
- strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
- strUsage += " -testnet " + _("Use the test network") + "\n";
- strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be "
- "solved instantly. This is intended for regression testing tools and app development.") + "\n";
- strUsage += " -rpcconnect=<ip> " + strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1") + "\n";
- strUsage += " -rpcport=<port> " + strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n";
- strUsage += " -rpcwait " + _("Wait for RPC server to start") + "\n";
- strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
- strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
-
- strUsage += "\n" + _("SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
- strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
+ strUsage += HelpMessageGroup(_("Options:"));
+ strUsage += HelpMessageOpt("-?", _("This help message"));
+ strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
+ strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
+ strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
+ strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be "
+ "solved instantly. This is intended for regression testing tools and app development."));
+ strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1"));
+ strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8332, 18332));
+ strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start"));
+ strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
+
+ strUsage += HelpMessageGroup(_("SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
+ strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
return strUsage;
}
// Parameters
//
ParseParameters(argc, argv);
- if (!boost::filesystem::is_directory(GetDataDir(false))) {
- fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
- return false;
- }
- try {
- ReadConfigFile(mapArgs, mapMultiArgs);
- } catch(std::exception &e) {
- fprintf(stderr,"Error reading configuration file: %s\n", e.what());
- return false;
- }
- // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause)
- if (!SelectBaseParamsFromCommandLine()) {
- fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
- return false;
- }
if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version")) {
std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n";
if (!mapArgs.count("-version")) {
fprintf(stdout, "%s", strUsage.c_str());
return false;
}
+ if (!boost::filesystem::is_directory(GetDataDir(false))) {
+ fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
+ return false;
+ }
+ try {
+ ReadConfigFile(mapArgs, mapMultiArgs);
+ } catch (const std::exception& e) {
+ fprintf(stderr,"Error reading configuration file: %s\n", e.what());
+ return false;
+ }
+ // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause)
+ if (!SelectBaseParamsFromCommandLine()) {
+ fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
+ return false;
+ }
return true;
}
// Connect to localhost
bool fUseSSL = GetBoolArg("-rpcssl", false);
- asio::io_service io_service;
- ssl::context context(io_service, ssl::context::sslv23);
- context.set_options(ssl::context::no_sslv2);
- asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context);
- SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL);
- iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
+ boost::asio::io_service io_service;
+ boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23);
+ context.set_options(boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::no_sslv3);
+ boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sslStream(io_service, context);
+ SSLIOStreamDevice<boost::asio::ip::tcp> d(sslStream, fUseSSL);
+ boost::iostreams::stream< SSLIOStreamDevice<boost::asio::ip::tcp> > stream(d);
const bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort())));
if (!fConnected)
// Connection succeeded, no need to retry.
break;
}
- catch (const CConnectionFailed& e) {
+ catch (const CConnectionFailed&) {
if (fWait)
MilliSleep(1000);
else
}
} while (fWait);
}
- catch (boost::thread_interrupted) {
+ catch (const boost::thread_interrupted&) {
throw;
}
- catch (std::exception& e) {
+ catch (const std::exception& e) {
strPrint = string("error: ") + e.what();
nRet = EXIT_FAILURE;
}
if(!AppInitRPC(argc, argv))
return EXIT_FAILURE;
}
- catch (std::exception& e) {
+ catch (const std::exception& e) {
PrintExceptionContinue(&e, "AppInitRPC()");
return EXIT_FAILURE;
} catch (...) {
try {
ret = CommandLineRPC(argc, argv);
}
- catch (std::exception& e) {
+ catch (const std::exception& e) {
PrintExceptionContinue(&e, "CommandLineRPC()");
} catch (...) {
PrintExceptionContinue(NULL, "CommandLineRPC()");
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "base58.h"
#include "clientversion.h"
-#include "core/transaction.h"
+#include "primitives/block.h" // for MAX_BLOCK_SIZE
+#include "primitives/transaction.h"
#include "core_io.h"
+#include "coins.h"
#include "keystore.h"
-#include "main.h" // for MAX_BLOCK_SIZE
#include "script/script.h"
#include "script/sign.h"
#include "ui_interface.h" // for _(...)
#include "univalue/univalue.h"
#include "util.h"
+#include "utilstrencodings.h"
#include "utilmoneystr.h"
#include <stdio.h>
#include <boost/algorithm/string.hpp>
#include <boost/assign/list_of.hpp>
-using namespace boost::assign;
using namespace std;
static bool fCreateBlank;
fprintf(stdout, "%s", strUsage.c_str());
- strUsage = _("Options:") + "\n";
- strUsage += " -? " + _("This help message") + "\n";
- strUsage += " -create " + _("Create new, empty TX.") + "\n";
- strUsage += " -json " + _("Select JSON output") + "\n";
- strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n";
- strUsage += " -testnet " + _("Use the test network") + "\n";
- strUsage += "\n";
+ strUsage = HelpMessageGroup(_("Options:"));
+ strUsage += HelpMessageOpt("-?", _("This help message"));
+ strUsage += HelpMessageOpt("-create", _("Create new, empty TX."));
+ strUsage += HelpMessageOpt("-json", _("Select JSON output"));
+ strUsage += HelpMessageOpt("-txid", _("Output only the hex-encoded transaction id of the resultant transaction."));
+ strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly."));
+ strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
fprintf(stdout, "%s", strUsage.c_str());
-
- strUsage = _("Commands:") + "\n";
- strUsage += " delin=N " + _("Delete input N from TX") + "\n";
- strUsage += " delout=N " + _("Delete output N from TX") + "\n";
- strUsage += " in=TXID:VOUT " + _("Add input to TX") + "\n";
- strUsage += " locktime=N " + _("Set TX lock time to N") + "\n";
- strUsage += " nversion=N " + _("Set TX version to N") + "\n";
- strUsage += " outaddr=VALUE:ADDRESS " + _("Add address-based output to TX") + "\n";
- strUsage += " outscript=VALUE:SCRIPT " + _("Add raw script output to TX") + "\n";
- strUsage += " sign=SIGHASH-FLAGS " + _("Add zero or more signatures to transaction") + "\n";
- strUsage += " This command requires JSON registers:\n";
- strUsage += " prevtxs=JSON object\n";
- strUsage += " privatekeys=JSON object\n";
- strUsage += " See signrawtransaction docs for format of sighash flags, JSON objects.\n";
- strUsage += "\n";
+ strUsage = HelpMessageGroup(_("Commands:"));
+ strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX"));
+ strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX"));
+ strUsage += HelpMessageOpt("in=TXID:VOUT", _("Add input to TX"));
+ strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
+ strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
+ strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX"));
+ strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX"));
+ strUsage += HelpMessageOpt("sign=SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " +
+ _("This command requires JSON registers:") +
+ _("prevtxs=JSON object") + ", " +
+ _("privatekeys=JSON object") + ". " +
+ _("See signrawtransaction docs for format of sighash flags, JSON objects."));
fprintf(stdout, "%s", strUsage.c_str());
- strUsage = _("Register Commands:") + "\n";
- strUsage += " load=NAME:FILENAME " + _("Load JSON file FILENAME into register NAME") + "\n";
- strUsage += " set=NAME:JSON-STRING " + _("Set register NAME to given JSON-STRING") + "\n";
- strUsage += "\n";
+ strUsage = HelpMessageGroup(_("Register Commands:"));
+ strUsage += HelpMessageOpt("load=NAME:FILENAME", _("Load JSON file FILENAME into register NAME"));
+ strUsage += HelpMessageOpt("set=NAME:JSON-STRING", _("Set register NAME to given JSON-STRING"));
fprintf(stdout, "%s", strUsage.c_str());
return false;
string strTxid = strInput.substr(0, pos);
if ((strTxid.size() != 64) || !IsHex(strTxid))
throw runtime_error("invalid TX input txid");
- uint256 txid(strTxid);
+ uint256 txid(uint256S(strTxid));
static const unsigned int minTxOutSz = 9;
static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz;
uint256 ParseHashUO(map<string,UniValue>& o, string strKey)
{
if (!o.count(strKey))
- return 0;
+ return uint256();
return ParseHashUV(o[strKey], strKey);
}
// Add previous txouts given in the RPC call:
if (!registers.count("prevtxs"))
throw runtime_error("prevtxs register variable must be set.");
- UniValue prevtxsObj = registers["privatekeys"];
+ UniValue prevtxsObj = registers["prevtxs"];
{
for (unsigned int previdx = 0; previdx < prevtxsObj.count(); previdx++) {
UniValue prevOut = prevtxsObj[previdx];
if (!prevOut.isObject())
throw runtime_error("expected prevtxs internal object");
- map<string,UniValue::VType> types = map_list_of("txid", UniValue::VSTR)("vout",UniValue::VNUM)("scriptPubKey",UniValue::VSTR);
+ map<string,UniValue::VType> types = boost::assign::map_list_of("txid", UniValue::VSTR)("vout",UniValue::VNUM)("scriptPubKey",UniValue::VSTR);
if (!prevOut.checkObject(types))
throw runtime_error("prevtxs internal object typecheck fail");
- uint256 txid = ParseHashUV(prevOut, "txid");
+ uint256 txid = ParseHashUV(prevOut["txid"], "txid");
int nOut = atoi(prevOut["vout"].getValStr());
if (nOut < 0)
throw runtime_error("vout must be positive");
- vector<unsigned char> pkData(ParseHexUV(prevOut, "scriptPubKey"));
+ vector<unsigned char> pkData(ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey"));
CScript scriptPubKey(pkData.begin(), pkData.end());
{
BOOST_FOREACH(const CTransaction& txv, txVariants) {
txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
}
- if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i)))
+ if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i)))
fComplete = false;
}
static void OutputTxJSON(const CTransaction& tx)
{
UniValue entry(UniValue::VOBJ);
- TxToUniv(tx, 0, entry);
+ TxToUniv(tx, uint256(), entry);
string jsonOutput = entry.write(4);
fprintf(stdout, "%s\n", jsonOutput.c_str());
}
+static void OutputTxHash(const CTransaction& tx)
+{
+ string strHexHash = tx.GetHash().GetHex(); // the hex-encoded transaction hash (aka the transaction id)
+
+ fprintf(stdout, "%s\n", strHexHash.c_str());
+}
+
static void OutputTxHex(const CTransaction& tx)
{
string strHex = EncodeHexTx(tx);
{
if (GetBoolArg("-json", false))
OutputTxJSON(tx);
+ else if (GetBoolArg("-txid", false))
+ OutputTxHash(tx);
else
OutputTxHex(tx);
}
OutputTx(tx);
}
- catch (boost::thread_interrupted) {
+ catch (const boost::thread_interrupted&) {
throw;
}
- catch (std::exception& e) {
+ catch (const std::exception& e) {
strPrint = string("error: ") + e.what();
nRet = EXIT_FAILURE;
}
if(!AppInitRawTx(argc, argv))
return EXIT_FAILURE;
}
- catch (std::exception& e) {
+ catch (const std::exception& e) {
PrintExceptionContinue(&e, "AppInitRawTx()");
return EXIT_FAILURE;
} catch (...) {
try {
ret = CommandLineRawTx(argc, argv);
}
- catch (std::exception& e) {
+ catch (const std::exception& e) {
PrintExceptionContinue(&e, "CommandLineRawTx()");
} catch (...) {
PrintExceptionContinue(NULL, "CommandLineRawTx()");
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", "bitcoind"
VALUE "LegalCopyright", COPYRIGHT_STR
- VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
+ VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
VALUE "OriginalFilename", "bitcoind.exe"
VALUE "ProductName", "Bitcoind"
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
// 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-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "clientversion.h"
static bool fDaemon;
-void DetectShutdownThread(boost::thread_group* threadGroup)
+void WaitForShutdown(boost::thread_group* threadGroup)
{
bool fShutdown = ShutdownRequested();
// Tell the main threads to shutdown.
bool AppInit(int argc, char* argv[])
{
boost::thread_group threadGroup;
- boost::thread* detectShutdownThread = NULL;
bool fRet = false;
+
+ //
+ // Parameters
+ //
+ // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
+ ParseParameters(argc, argv);
+
+ // Process help and version before taking care about datadir
+ if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version"))
+ {
+ std::string strUsage = _("Bitcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n";
+
+ if (mapArgs.count("-version"))
+ {
+ strUsage += LicenseInfo();
+ }
+ else
+ {
+ strUsage += "\n" + _("Usage:") + "\n" +
+ " bitcoind [options] " + _("Start Bitcoin Core Daemon") + "\n";
+
+ strUsage += "\n" + HelpMessage(HMM_BITCOIND);
+ }
+
+ fprintf(stdout, "%s", strUsage.c_str());
+ return false;
+ }
+
try
{
- //
- // Parameters
- //
- // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
- ParseParameters(argc, argv);
if (!boost::filesystem::is_directory(GetDataDir(false)))
{
fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
try
{
ReadConfigFile(mapArgs, mapMultiArgs);
- } catch(std::exception &e) {
+ } catch (const std::exception& e) {
fprintf(stderr,"Error reading configuration file: %s\n", e.what());
return false;
}
return false;
}
- if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version"))
- {
- std::string strUsage = _("Bitcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n";
-
- if (mapArgs.count("-version"))
- {
- strUsage += LicenseInfo();
- }
- else
- {
- strUsage += "\n" + _("Usage:") + "\n" +
- " bitcoind [options] " + _("Start Bitcoin Core Daemon") + "\n";
-
- strUsage += "\n" + HelpMessage(HMM_BITCOIND);
- }
-
- fprintf(stdout, "%s", strUsage.c_str());
- return false;
- }
-
// Command-line RPC
bool fCommandLine = false;
for (int i = 1; i < argc; i++)
#endif
SoftSetBoolArg("-server", true);
- detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup));
fRet = AppInit2(threadGroup);
}
- catch (std::exception& e) {
+ catch (const std::exception& e) {
PrintExceptionContinue(&e, "AppInit()");
} catch (...) {
PrintExceptionContinue(NULL, "AppInit()");
if (!fRet)
{
- if (detectShutdownThread)
- detectShutdownThread->interrupt();
-
threadGroup.interrupt_all();
// threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of
// the startup-failure cases to make sure they don't result in a hang due to some
// thread-blocking-waiting-for-another-thread-during-startup case
- }
-
- if (detectShutdownThread)
- {
- detectShutdownThread->join();
- delete detectShutdownThread;
- detectShutdownThread = NULL;
+ } else {
+ WaitForShutdown(&threadGroup);
}
Shutdown();
-// Copyright (c) 2012-2014 The Bitcoin developers
+// Copyright (c) 2012-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "bloom.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "hash.h"
#include "script/script.h"
#include "script/standard.h"
-// Copyright (c) 2012-2014 The Bitcoin developers
+// Copyright (c) 2012-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.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
pindex = pindex->pprev;
return pindex;
}
+
+/** Turn the lowest '1' bit in the binary representation of a number into a '0'. */
+int static inline InvertLowestOne(int n) { return n & (n - 1); }
+
+/** Compute what height to jump back to with the CBlockIndex::pskip pointer. */
+int static inline GetSkipHeight(int height) {
+ if (height < 2)
+ return 0;
+
+ // Determine which height to jump back to. Any number strictly lower than height is acceptable,
+ // but the following expression seems to perform well in simulations (max 110 steps to go back
+ // up to 2**18 blocks).
+ return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 : InvertLowestOne(height);
+}
+
+CBlockIndex* CBlockIndex::GetAncestor(int height)
+{
+ if (height > nHeight || height < 0)
+ return NULL;
+
+ CBlockIndex* pindexWalk = this;
+ int heightWalk = nHeight;
+ while (heightWalk > height) {
+ int heightSkip = GetSkipHeight(heightWalk);
+ int heightSkipPrev = GetSkipHeight(heightWalk - 1);
+ if (heightSkip == height ||
+ (heightSkip > height && !(heightSkipPrev < heightSkip - 2 &&
+ heightSkipPrev >= height))) {
+ // Only follow pskip if pprev->pskip isn't better than pskip->pprev.
+ pindexWalk = pindexWalk->pskip;
+ heightWalk = heightSkip;
+ } else {
+ pindexWalk = pindexWalk->pprev;
+ heightWalk--;
+ }
+ }
+ return pindexWalk;
+}
+
+const CBlockIndex* CBlockIndex::GetAncestor(int height) const
+{
+ return const_cast<CBlockIndex*>(this)->GetAncestor(height);
+}
+
+void CBlockIndex::BuildSkip()
+{
+ if (pprev)
+ pskip = pprev->GetAncestor(GetSkipHeight(nHeight));
+}
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_CHAIN_H
#define BITCOIN_CHAIN_H
-#include "core/block.h"
+#include "arith_uint256.h"
+#include "primitives/block.h"
#include "pow.h"
#include "tinyformat.h"
#include "uint256.h"
void SetNull() { nFile = -1; nPos = 0; }
bool IsNull() const { return (nFile == -1); }
+
+ std::string ToString() const
+ {
+ return strprintf("CBlockDiskPos(nFile=%i, nPos=%i)", nFile, nPos);
+ }
+
};
enum BlockStatus {
class CBlockIndex
{
public:
- //! pointer to the hash of the block, if any. memory is owned by this CBlockIndex
+ //! pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
const uint256* phashBlock;
//! pointer to the index of the predecessor of this block
unsigned int nUndoPos;
//! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
- uint256 nChainWork;
+ arith_uint256 nChainWork;
//! Number of transactions in this block.
//! Note: in a potential headers-first mode, this number cannot be relied upon
nFile = 0;
nDataPos = 0;
nUndoPos = 0;
- nChainWork = 0;
+ nChainWork = arith_uint256();
nTx = 0;
nChainTx = 0;
nStatus = 0;
nSequenceId = 0;
nVersion = 0;
- hashMerkleRoot = 0;
+ hashMerkleRoot = uint256();
nTime = 0;
nBits = 0;
nNonce = 0;
return pbegin[(pend - pbegin)/2];
}
- /**
- * Returns true if there are nRequired or more blocks of minVersion or above
- * in the last Params().ToCheckBlockUpgradeMajority() blocks, starting at pstart
- * and going backwards.
- */
- static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart,
- unsigned int nRequired);
-
std::string ToString() const
{
return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
uint256 hashPrev;
CDiskBlockIndex() {
- hashPrev = 0;
+ hashPrev = uint256();
}
- explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) {
- hashPrev = (pprev ? pprev->GetBlockHash() : 0);
+ explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) {
+ hashPrev = (pprev ? pprev->GetBlockHash() : uint256());
}
ADD_SERIALIZE_METHODS;
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <boost/assign/list_of.hpp>
using namespace std;
-using namespace boost::assign;
struct SeedSpec6 {
uint8_t addr[16];
*/
static Checkpoints::MapCheckpoints mapCheckpoints =
boost::assign::map_list_of
- ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
- ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
- ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
- (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
- (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
- (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
- (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
- (210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
- (216116, uint256("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
- (225430, uint256("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
- (250000, uint256("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214"))
- (279000, uint256("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40"))
- (295000, uint256("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983"))
+ ( 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
+ ( 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
+ ( 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
+ (105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
+ (134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
+ (168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
+ (193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
+ (210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
+ (216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
+ (225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
+ (250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214"))
+ (279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40"))
+ (295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983"))
;
static const Checkpoints::CCheckpointData data = {
&mapCheckpoints,
static Checkpoints::MapCheckpoints mapCheckpointsTestnet =
boost::assign::map_list_of
- ( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
+ ( 546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
;
static const Checkpoints::CCheckpointData dataTestnet = {
&mapCheckpointsTestnet,
static Checkpoints::MapCheckpoints mapCheckpointsRegtest =
boost::assign::map_list_of
- ( 0, uint256("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"))
+ ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"))
;
static const Checkpoints::CCheckpointData dataRegtest = {
&mapCheckpointsRegtest,
class CMainParams : public CChainParams {
public:
CMainParams() {
- networkID = CBaseChainParams::MAIN;
strNetworkID = "main";
/**
* The message start string is designed to be unlikely to occur in normal data.
pchMessageStart[3] = 0xd9;
vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284");
nDefaultPort = 8333;
- bnProofOfWorkLimit = ~uint256(0) >> 32;
+ bnProofOfWorkLimit = ~arith_uint256(0) >> 32;
nSubsidyHalvingInterval = 210000;
nEnforceBlockUpgradeMajority = 750;
nRejectBlockOutdatedMajority = 950;
txNew.vout[0].nValue = 50 * COIN;
txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
genesis.vtx.push_back(txNew);
- genesis.hashPrevBlock = 0;
+ genesis.hashPrevBlock.SetNull();
genesis.hashMerkleRoot = genesis.BuildMerkleTree();
genesis.nVersion = 1;
genesis.nTime = 1231006505;
genesis.nNonce = 2083236893;
hashGenesisBlock = genesis.GetHash();
- assert(hashGenesisBlock == uint256("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
- assert(genesis.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
+ assert(hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
+ assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be"));
vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me"));
vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org"));
vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com"));
- vSeeds.push_back(CDNSSeedData("bitnodes.io", "seed.bitnodes.io"));
vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org"));
- base58Prefixes[PUBKEY_ADDRESS] = list_of(0);
- base58Prefixes[SCRIPT_ADDRESS] = list_of(5);
- base58Prefixes[SECRET_KEY] = list_of(128);
- base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x88)(0xB2)(0x1E);
- base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x88)(0xAD)(0xE4);
+ base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,0);
+ base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5);
+ base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,128);
+ base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container<std::vector<unsigned char> >();
+ base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container<std::vector<unsigned char> >();
convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));
fAllowMinDifficultyBlocks = false;
fRequireStandard = true;
fMineBlocksOnDemand = false;
- fSkipProofOfWorkCheck = false;
fTestnetToBeDeprecatedFieldRPC = false;
}
class CTestNetParams : public CMainParams {
public:
CTestNetParams() {
- networkID = CBaseChainParams::TESTNET;
strNetworkID = "test";
pchMessageStart[0] = 0x0b;
pchMessageStart[1] = 0x11;
genesis.nTime = 1296688602;
genesis.nNonce = 414098458;
hashGenesisBlock = genesis.GetHash();
- assert(hashGenesisBlock == uint256("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"));
+ assert(hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"));
vFixedSeeds.clear();
vSeeds.clear();
vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me"));
vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de"));
- base58Prefixes[PUBKEY_ADDRESS] = list_of(111);
- base58Prefixes[SCRIPT_ADDRESS] = list_of(196);
- base58Prefixes[SECRET_KEY] = list_of(239);
- base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x35)(0x87)(0xCF);
- base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x35)(0x83)(0x94);
+ base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
+ base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
+ base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
+ base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >();
+ base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >();
convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));
class CRegTestParams : public CTestNetParams {
public:
CRegTestParams() {
- networkID = CBaseChainParams::REGTEST;
strNetworkID = "regtest";
pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf;
nMinerThreads = 1;
nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks
nTargetSpacing = 10 * 60;
- bnProofOfWorkLimit = ~uint256(0) >> 1;
+ bnProofOfWorkLimit = ~arith_uint256(0) >> 1;
genesis.nTime = 1296688602;
genesis.nBits = 0x207fffff;
genesis.nNonce = 2;
hashGenesisBlock = genesis.GetHash();
nDefaultPort = 18444;
- assert(hashGenesisBlock == uint256("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
+ assert(hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds.
vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds.
};
static CRegTestParams regTestParams;
-/**
- * Unit test
- */
-class CUnitTestParams : public CMainParams, public CModifiableParams {
-public:
- CUnitTestParams() {
- networkID = CBaseChainParams::UNITTEST;
- strNetworkID = "unittest";
- nDefaultPort = 18445;
- vFixedSeeds.clear(); //! Unit test mode doesn't have any fixed seeds.
- vSeeds.clear(); //! Unit test mode doesn't have any DNS seeds.
-
- fRequireRPCPassword = false;
- fMiningRequiresPeers = false;
- fDefaultCheckMemPool = true;
- fAllowMinDifficultyBlocks = false;
- fMineBlocksOnDemand = true;
- }
-
- const Checkpoints::CCheckpointData& Checkpoints() const
- {
- // UnitTest share the same checkpoints as MAIN
- return data;
- }
-
- //! Published setters to allow changing values in unit test cases
- virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) { nSubsidyHalvingInterval=anSubsidyHalvingInterval; }
- virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) { nEnforceBlockUpgradeMajority=anEnforceBlockUpgradeMajority; }
- virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) { nRejectBlockOutdatedMajority=anRejectBlockOutdatedMajority; }
- virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) { nToCheckBlockUpgradeMajority=anToCheckBlockUpgradeMajority; }
- virtual void setDefaultCheckMemPool(bool afDefaultCheckMemPool) { fDefaultCheckMemPool=afDefaultCheckMemPool; }
- virtual void setAllowMinDifficultyBlocks(bool afAllowMinDifficultyBlocks) { fAllowMinDifficultyBlocks=afAllowMinDifficultyBlocks; }
- virtual void setSkipProofOfWorkCheck(bool afSkipProofOfWorkCheck) { fSkipProofOfWorkCheck = afSkipProofOfWorkCheck; }
-};
-static CUnitTestParams unitTestParams;
-
-
static CChainParams *pCurrentParams = 0;
-CModifiableParams *ModifiableParams()
-{
- assert(pCurrentParams);
- assert(pCurrentParams==&unitTestParams);
- return (CModifiableParams*)&unitTestParams;
-}
-
const CChainParams &Params() {
assert(pCurrentParams);
return *pCurrentParams;
return testNetParams;
case CBaseChainParams::REGTEST:
return regTestParams;
- case CBaseChainParams::UNITTEST:
- return unitTestParams;
default:
assert(false && "Unimplemented network");
return mainParams;
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "chainparamsbase.h"
#include "checkpoints.h"
-#include "core/block.h"
+#include "primitives/block.h"
#include "protocol.h"
-#include "uint256.h"
+#include "arith_uint256.h"
#include <vector>
-typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
-
struct CDNSSeedData {
std::string name, host;
CDNSSeedData(const std::string &strName, const std::string &strHost) : name(strName), host(strHost) {}
};
const uint256& HashGenesisBlock() const { return hashGenesisBlock; }
- const MessageStartChars& MessageStart() const { return pchMessageStart; }
+ const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; }
const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
int GetDefaultPort() const { return nDefaultPort; }
- const uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
+ const arith_uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; }
/** Used to check majorities for block version upgrade */
int EnforceBlockUpgradeMajority() const { return nEnforceBlockUpgradeMajority; }
bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; }
/** Allow mining of a min-difficulty block */
bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; }
- /** Skip proof-of-work check: allow mining of any difficulty block */
- bool SkipProofOfWorkCheck() const { return fSkipProofOfWorkCheck; }
/** Make standard checks */
bool RequireStandard() const { return fRequireStandard; }
int64_t TargetTimespan() const { return nTargetTimespan; }
int64_t TargetSpacing() const { return nTargetSpacing; }
- int64_t Interval() const { return nTargetTimespan / nTargetSpacing; }
+ int64_t DifficultyAdjustmentInterval() const { return nTargetTimespan / nTargetSpacing; }
/** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
/** In the future use NetworkIDString() for RPC fields */
CChainParams() {}
uint256 hashGenesisBlock;
- MessageStartChars pchMessageStart;
+ CMessageHeader::MessageStartChars pchMessageStart;
//! Raw pub key bytes for the broadcast alert signing key.
std::vector<unsigned char> vAlertPubKey;
int nDefaultPort;
- uint256 bnProofOfWorkLimit;
+ arith_uint256 bnProofOfWorkLimit;
int nSubsidyHalvingInterval;
int nEnforceBlockUpgradeMajority;
int nRejectBlockOutdatedMajority;
int nMinerThreads;
std::vector<CDNSSeedData> vSeeds;
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
- CBaseChainParams::Network networkID;
std::string strNetworkID;
CBlock genesis;
std::vector<CAddress> vFixedSeeds;
bool fAllowMinDifficultyBlocks;
bool fRequireStandard;
bool fMineBlocksOnDemand;
- bool fSkipProofOfWorkCheck;
bool fTestnetToBeDeprecatedFieldRPC;
};
-/**
- * Modifiable parameters interface is used by test cases to adapt the parameters in order
- * to test specific features more easily. Test cases should always restore the previous
- * values after finalization.
- */
-
-class CModifiableParams {
-public:
- //! Published setters to allow changing values in unit test cases
- virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) =0;
- virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority)=0;
- virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority)=0;
- virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority)=0;
- virtual void setDefaultCheckMemPool(bool aDefaultCheckMemPool)=0;
- virtual void setAllowMinDifficultyBlocks(bool aAllowMinDifficultyBlocks)=0;
- virtual void setSkipProofOfWorkCheck(bool aSkipProofOfWorkCheck)=0;
-};
-
-
/**
* Return the currently selected parameters. This won't change after app startup
* outside of the unit tests.
/** Return parameters for the given network. */
CChainParams &Params(CBaseChainParams::Network network);
-/** Get modifiable network parameters (UNITTEST only) */
-CModifiableParams *ModifiableParams();
-
/** Sets the params returned by Params() to those for the given network. */
void SelectParams(CBaseChainParams::Network network);
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <assert.h>
-#include <boost/assign/list_of.hpp>
-
-using namespace boost::assign;
-
/**
* Main network
*/
public:
CBaseMainParams()
{
- networkID = CBaseChainParams::MAIN;
nRPCPort = 8332;
}
};
public:
CBaseTestNetParams()
{
- networkID = CBaseChainParams::TESTNET;
nRPCPort = 18332;
strDataDir = "testnet3";
}
public:
CBaseRegTestParams()
{
- networkID = CBaseChainParams::REGTEST;
strDataDir = "regtest";
}
};
public:
CBaseUnitTestParams()
{
- networkID = CBaseChainParams::UNITTEST;
strDataDir = "unittest";
}
};
case CBaseChainParams::REGTEST:
pCurrentBaseParams = ®TestParams;
break;
- case CBaseChainParams::UNITTEST:
- pCurrentBaseParams = &unitTestParams;
- break;
default:
assert(false && "Unimplemented network");
return;
-// Copyright (c) 2014 The Bitcoin developers
+// 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.
MAIN,
TESTNET,
REGTEST,
- UNITTEST,
MAX_NETWORK_TYPES
};
int nRPCPort;
std::string strDataDir;
- Network networkID;
};
/**
* IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly.
*/
static SeedSpec6 pnSeed6_main[] = {
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x69,0x6a,0x7e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x04,0x7d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x0c,0x6c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x0a,0x33,0xdb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xc7,0x49,0xc6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x48,0x95,0x78}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x09,0x71,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa5,0x0c,0xb9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x80,0x30,0xd1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0x4e,0x07,0xbd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x8f,0x57}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x09,0x6e,0x28}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xaf,0xdc,0xd4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x6b,0x9b,0x52}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xc6,0x5c,0x63}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x89,0xde,0xed}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xd9,0x76,0xa9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0xa4,0x91,0xea}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4e,0xfa,0x03}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x00,0xa9,0x6c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc8,0x62,0xaf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xba,0xf3,0x93}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xef,0xc9,0xc2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xd5,0x0e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x28,0x70,0x48}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc2,0x97,0x72}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0xf0,0x8a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0x21,0xc5,0x6e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0x22,0xb4,0xf5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0xca,0x80,0xda}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x23,0xc3,0x19}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x64,0x7b,0x13}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xaf,0x91,0xa9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0x85,0xc1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0x97,0x0a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xe4,0x01,0xe6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0e,0xc8,0xc8,0x91}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xe4,0x00,0xbc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xe4,0x00,0xc8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x1e,0xf3,0x99}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x58,0xe8,0x31}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x63,0x69,0x09}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe2,0x89,0xd0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe3,0xb1,0xa1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe3,0xbf,0x32}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe5,0x2d,0x20}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xec,0x90,0x45}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xfd,0x94,0x71}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xfd,0xf1,0x16}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xff,0xe3,0xe7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x14,0xcd,0xde}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x17,0x78,0xfc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x5e,0x62,0x60}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x62,0x5f,0xc9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x6f,0x5a,0x37}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x77,0x77,0x69}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x8a,0x19,0x95}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x03,0xd6,0x2d}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xba,0x57,0x2e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x09,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x85,0xa8,0x46}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xdc,0x92,0xcc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0x6f,0xeb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xce,0x8c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x81,0x72,0x23}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x42,0x9d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x4f,0x4f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x51,0x01,0xc5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x90,0xba,0xb1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xd7,0xae}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe5,0x4d,0x20}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x32,0xb0,0x4b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x28,0x2b,0x93}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe6,0xcc,0x2d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x70,0xe2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xb8,0x08,0x1b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdc,0xa3,0x12}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x88,0x8a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0xa8,0x86,0xa3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x17,0xe4,0x18}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9a,0x70,0x2e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xe9,0x62,0xeb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x03,0x65,0x6f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x81,0xd0,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xc5,0x9a,0x8a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xd6,0x6f,0x94}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x49,0x57,0x3f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x29,0x4a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x45,0xad}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x34,0x15}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x3b,0x3f,0x4c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0xfe,0x01}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x59,0x20,0x56}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x3c,0x44}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc8,0x4a,0xf2,0x44}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x46,0x42,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0x58,0x66,0xc8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x3e,0x3f,0xed}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xbf,0x85,0xf5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0x41,0xd1,0x5d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xba,0x65,0x62}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xba,0xfa,0xba}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xcc,0x99,0x6b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x2c,0x10,0xe7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x2c,0x2c,0x0b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x78,0xa8,0xcc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x8f,0x56,0x1a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x4b,0x18}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbc,0x44,0xa9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc0,0x5f,0x96}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc9,0xf6,0x74}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xcd,0x0a,0x8c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x0a,0xd2,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x13,0x8a,0x9a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcc,0x7b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcd,0x43}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x26,0xeb,0xe5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa3,0x4c,0xe6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa6,0xa2,0x5b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xad,0xbe,0x32}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe3,0x42,0x84}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xee,0xbb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xec,0x74,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2f,0x37,0x0e,0x41}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x07,0xfc,0xe5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x2e,0x9f,0x5b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4e,0x31,0xb5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4e,0xe7,0x39}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4f,0x99,0x41}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x22,0x2c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x7e,0x56,0xfd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x8e,0x29,0x17}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xc7,0x71,0xc1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xc8,0x4e,0x6b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xce,0x8a,0xb1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xfc,0x34,0x31}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa5,0x19,0x4b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa9,0x6b,0x28}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xb3,0xbe,0x38}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xbb,0x52,0x79}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf6,0x55,0xf6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x4a,0x07,0xcd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x60,0xb7,0x79}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x3e,0x3a,0x26}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x3f,0x5b,0x48}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x3f,0x5b,0x70}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x48,0xd3,0xe4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x2b,0x28,0x9a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x2b,0x82,0xb2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x50,0xb9,0xd5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x6d,0x31,0x1a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xad,0x8b,0x3a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xb5,0xee,0xba}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0x72,0x7f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0x8d,0xe4,0x8a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0x99,0xd5,0x4e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0xdf,0x54,0x91}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0xfb,0x58,0x70}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x1f,0x6e,0x32}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x22,0x79,0x2d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x72,0x06,0x2a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x8c,0x7d,0x62}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x9c,0xc1,0x64}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x1e,0x2f,0x74}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x23,0x84,0xb1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x60,0xc1,0xa5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x6f,0xbd,0x1a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x44,0x0a,0x1e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x72,0x21,0xfa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x82,0x2e,0x3f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xaf,0xd7,0x87}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xbe,0xfd,0xa5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xc2,0x26,0xfe}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xf4,0x62,0x6f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa2,0xee,0x1e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa9,0xff,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xb7,0xad,0x19}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xdb,0xe9,0x8c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xe3,0xf0,0x73}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xf7,0xde,0x47}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x2b,0x72,0x42}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x34,0x21,0x24}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xc6,0xf5,0xf1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x0c,0xe2,0xa5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x0d,0xc6,0xbc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x0f,0xb3,0x3e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x27,0xef,0x2f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x2f,0x2d,0x57}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x3e,0xd9,0xce}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x2a,0x1f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x51,0x3d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x43,0xdb,0xc8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x5a,0x84,0x9d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x5e,0x1e,0xb1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x88,0xaf,0xf1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x3d,0x61,0xe4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x7b,0x76,0x84}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x3b,0x98,0xb6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc6,0xf8,0x97}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc8,0xf2,0x59}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xe1,0xb3,0x9d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x0e,0xbb,0x33}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x26,0x22,0xb4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x34,0x48,0xbb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x5b,0x90,0xb6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xa7,0x31,0xd9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xc9,0xf3,0x37}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xdf,0x3c,0xf9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xe4,0x99,0x66}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x1a,0x65,0xe4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x32,0x9e,0xc8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xb5,0xcc,0xaa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x39,0xc7,0xb4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x3f,0xde,0xe2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x51,0xe7,0x15}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xc1,0x7e,0x52}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xcf,0xeb,0xa4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x53,0xc5,0x72}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x90,0x72,0x09}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x70,0x05,0xf7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xae,0x14,0xf7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x25,0xf0,0x8e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x39,0xca,0x6b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xac,0x7b,0x35}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xdd,0x5b,0xfd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xeb,0x30,0x30}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xf5,0x4e,0x02}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x08,0x3a,0xf9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x64,0x12}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x11,0x07}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x7b,0x2e,0xf1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xb7,0x02,0x5b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x6d,0x52,0x7d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0xb0,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x11,0xbe,0x2a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x9f,0xa3,0x61}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x06,0x4a,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0x7d,0xaf,0xf3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xc9,0x94,0xb9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x50,0x1c,0x36}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x5d,0x73,0xca}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x43,0xa7,0xec}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x79,0xec}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x78,0xd3,0xc4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa2,0xc4,0xa1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x1b,0xbf,0xb6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x81,0xec,0x8d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x83,0x58,0x2f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x9d,0xcd,0x06}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x84,0xe6,0x90}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x8f,0xbc,0x9b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa0,0xdd,0x8c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa1,0x6f,0x72}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x64,0xbd,0x03}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x93,0x8c,0x79}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xcb,0x4b,0x85}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xdc,0x63,0xe3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xde,0x14,0xa9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xf1,0x01,0x07}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x17,0xbf,0xf3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x26,0x0b,0xca}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x50,0x09,0x47}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x6e,0xd5,0xa5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x85,0x9b,0xed}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xab,0x22,0x25}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xb5,0x9b,0xb4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x27,0x9c,0x89}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x49,0xa1,0x5f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x82,0x2d,0x28}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xa5,0x99,0x2f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xa8,0x80,0x85}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xb3,0xe1,0x76}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc2,0xf5,0x9e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc7,0x66,0x0a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xd3,0x1e,0xf3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xd9,0x85,0x91}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x80,0x23}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x83,0xb1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xe9,0xe1,0xcd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x00,0xf9,0x92}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x59,0x1f,0xf9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x80,0x1d,0xe7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x80,0xfd,0x8e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x8f,0x82,0x38}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x96,0x02,0x63}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x96,0x09,0xc4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa1,0x40,0x2d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xd4,0x67,0xd4}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xd4,0x6f,0x72}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xc6,0x5c,0x62}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x13,0x20,0x6c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0x0c,0xaa,0xb7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x98,0xed,0xc6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xcb,0xe4,0x47}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x75,0xac,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x93,0xe5,0xe2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x4a,0x78,0x4d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xec,0xa5,0x18}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc8,0x1c,0x48}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x2f,0x6c,0x7c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x60,0x4d,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x6c,0x4b,0x5b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x9b,0xd9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdc,0x87,0x39,0xe6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x17,0xb8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x1c,0x14}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x50,0x00,0x5f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x7f,0x98,0x0d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x49,0x2a,0x24}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x9b,0x51,0x3e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x45,0xb2,0x02}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3d,0xaf,0xdf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x28,0x81,0x88}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x65,0x11}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xca,0xfe,0xab}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x35,0xf6,0x2e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xc7,0x73,0x57}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x80,0x12}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xac,0xbc,0x8e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x39,0xc4,0x81}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xfa,0xfc,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x7d,0x17,0x62}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xed,0x75,0xc9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0xf4,0xcf,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa7,0xbd,0xda}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0xc2,0x1a,0xaa}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa2,0x55,0xe2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0xaa,0x88}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x07,0xe7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4b,0xe9,0xa9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x48,0x93,0x28}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x27,0x51,0x99}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x70,0x39,0xd6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x4f,0x99,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xa8,0x19,0xe5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x5f,0xe2,0x92}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xa9,0x84,0x8b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x0a,0xaa,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe5,0x4d,0xa7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xff,0x90,0xb0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x32,0xee,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0xa6,0x31,0xc3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xb7,0xd9,0xc1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xb9,0x6a,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x62,0x73}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xdd,0xfe,0x4c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xa0,0x09,0x1e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4c,0xc3,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xd9,0x77,0x37}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xf2,0xdc,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xb5,0xe2,0x3c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x03,0xac,0xd2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0x80,0x2f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x4c,0x3e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xe2,0x95,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x77,0x39,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xf0,0x3c,0x95}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x4e,0x65,0x3c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x02,0x74}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x11,0x4f,0xa1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x01,0xce,0x14}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xbb,0x5e,0xc1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc4,0x08,0x2c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x06,0xfd,0xc7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xf8,0x04,0x76}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x83,0xb3,0xff}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xef,0xc2,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x40,0x61,0xe9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xf6,0x4b,0x08}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xfe,0x51,0x1f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xfe,0x96,0x36}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x02,0x22,0x68}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x0f,0x3d,0x3c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x11,0x19,0x87}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2a,0x90,0x13}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd4,0xd2,0x87}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd7,0xa5,0xe7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xee,0x8c,0xb0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xf0,0x1f,0xb8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0xd6,0x89}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x8b,0xa3,0x84}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xc7,0x04,0xe4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x3d,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x6c,0x4d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x7b,0x10,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x30,0x2a,0xc7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x68,0xa8,0x68}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xe5,0x49,0xab}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc0,0x48,0x16}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x40,0x02,0x36}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xff,0x8c,0x0e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x89,0x91,0x21}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x50,0x1f,0xb6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x6b,0x40,0x9b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x22,0x28,0xaf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x16,0x1d,0x7f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0x0d,0x56,0x1f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xbe,0x37,0xe2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0xeb,0xbd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x07,0x6c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xce,0xf8,0xda}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x24,0x74,0x0f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0x52,0xe9,0xde}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x1a,0x3f,0xf2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xf8,0xbd,0x61}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xc8,0x54,0xd2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x42,0xc4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x63,0x05,0xae}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xa9,0xb9,0xbd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x32,0xeb,0xa9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x39,0x94,0xd9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x6a,0x11}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0xa5,0x73}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x52,0x6b,0xb3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0x34,0xd7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x7f,0x3d,0x33}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x1b,0x43,0x51}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xe5,0x4a,0x08}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x23,0x0a,0xa6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x69,0x67,0x5c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xcf,0x77,0x01}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3a,0x68,0xa6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xea,0xf4,0x7f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfa,0x92,0x21}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x0f,0x3a,0xa0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x39,0x3e,0xfe}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x5f,0xce,0x2c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xc1,0xa6,0xc8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x7e,0xfb,0x96}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc7,0x66,0x0a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x27,0x4d,0x6b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xc1,0xa0,0xeb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0xa0,0x3b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0xcc,0x1d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x12,0x69}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x3c,0xf2,0x22}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x6b,0x64,0x65}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x87,0x9f,0x8b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0x9a,0x9b,0xeb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x6b,0xfe,0x79}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xf4,0x36,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x4d,0x22,0x23}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x2e,0x95,0x5d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf7,0xb4,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xbe,0x14,0xdc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x09,0x46,0xb2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x9b,0xf7,0xd3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xc8,0x18,0x65}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xcf,0xa3,0x83}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x1f,0x64,0x9b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0xfe,0x17}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xcc,0x08,0xd5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9b,0x36,0xa4,0x91}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x4a,0xcb,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x53,0xc9,0xbb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xc4,0x64,0xaf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xca,0x5e,0x60}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x68,0x6a,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x9d,0x7e,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd3,0xe6,0x78}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xec,0xc4,0x4d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x61,0x38,0x62}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x86,0xb2,0x59}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x96,0xe9,0x13}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xa8,0x85,0x03}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x12,0xf6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x21,0xca}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x12,0x1c,0x15}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x55,0xdc,0x54}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xa3,0xe3,0x1c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xb8,0x53,0x3c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xe7,0x60,0x53}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xec,0x31,0x75}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x5a,0x42,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x6a,0xc2,0x61}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x86,0x4b,0x73}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x98,0xc1,0x24}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x98,0xdb,0x23}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc5,0x0a,0xea}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd1,0x4d,0x65}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd2,0x6a,0x93}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd6,0xc8,0xcd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdf,0x73,0x26}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xea,0x30,0xe8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xfa,0x56,0x12}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x1b,0x07,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xff,0xcf,0x49}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x4a,0xa3,0xea}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x54,0x72,0x6a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x98,0xa6,0x1d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xab,0xd8,0xdd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xb9,0xb1,0x47}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x13,0x0c,0xf4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x2a,0x73,0x32}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4f,0xb1,0xce}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x88,0x93,0x77}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x8f,0xf5,0x05}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xbc,0x32,0x27}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xbe,0xe3,0x70}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xc6,0x87,0x1d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xe2,0x6b,0x56}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf2,0xdb,0x5a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf2,0xe5,0xa8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf4,0xa0,0x54}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x1f,0x0a,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x55,0x19,0x29}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x69,0xa1,0x88}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x9a,0xa5,0x2d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x9a,0xc8,0xd8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xa7,0x6d,0x7d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0x7d,0xe7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0xd8,0xeb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x21,0x19,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x2b,0x82,0xb2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x76,0x08,0xec}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x66,0x06,0x7d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xca,0x14,0x2d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xd9,0x7d,0xe1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xea,0xd2,0x6f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xed,0x14,0x7b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xff,0x90,0xb0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0x71,0x40,0x2b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0xe5,0x16,0x08}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x01,0xd4,0x13}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x1e,0x2a,0xbd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xe0,0xa5,0x30}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xf3,0x5e,0x8c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x83,0x6b,0x6b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x83,0x74,0xb8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x8f,0x00,0x9c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xdb,0xb8,0x09}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xb9,0x26,0xae}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x06,0x04,0x91}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x08,0x1b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x21,0x14}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0xe4,0x81}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0xf0,0xad}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x33,0x14,0x56}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x95,0xde}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x97,0xac}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0xa1,0x81,0xf7}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0xaa,0x8c,0x15}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x3c,0xd3,0xd8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x49,0x2a,0x24}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x49,0xac,0x8a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xa3,0xeb,0xef}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xbe,0xc4,0xdc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xc9,0x87,0xd8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x98,0x02}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x9a,0x51}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe6,0xdc,0x7d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xea,0x9c,0xda}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xeb,0x31,0x1b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x01,0xaa}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xc2,0x03,0x46}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb6,0xa3,0xcb,0x1e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xe3,0xff,0x0e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xcb,0xfd,0xc3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6f,0x03,0x90,0xc2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x69,0x64,0x44}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0x75,0xca,0x1a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xa9,0x59}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0x74,0xaa,0x19}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xc8,0x22,0x26}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xd3,0x98,0xa5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xc3,0x8e,0x43}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x19,0x96,0xc7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x03,0x57,0xaf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0xe2,0x98,0x50}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xd8,0xad,0x36}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa2,0xc1,0x83}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x9d,0x96}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x15,0x3d,0xcf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xa4,0xc1,0x49}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x75,0x0b,0xbd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x19,0xff,0x8f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xfe,0x51,0x1e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xef,0xd6,0x28}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xcc,0x37,0x28}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x2d,0xf4,0x02}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3f,0x0e,0x07}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x87,0xb1,0xbc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe1,0xa4,0x14}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x68,0x09,0x82}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcb,0xcf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x7f,0xe2,0x37}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x37,0x92,0x07}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xbc,0x14,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x10,0x26}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd9,0x7c,0xcb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xd2,0xc0,0x3b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x1b,0x13,0x97}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x5c,0x1e,0x6f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0x9f,0x93,0xa7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xbf,0xa0,0xb7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x3a,0xa8,0xaf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x3f,0xb8,0xcb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x1c,0x32,0x5f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xc3,0xd6,0x52}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x5b,0xac,0xde}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x10,0xf3,0x2c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x2b,0x8a,0x10}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa1,0x6f,0x72}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0xd2,0xba,0x85}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x9e,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xb8,0x08,0x1a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x48,0x70,0xcd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x5b,0x6d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xfe,0x6c,0xa6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x73,0xad}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x5b,0xac,0xda}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0xfd,0x17,0x84}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x37,0x41}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x86,0x13,0x1f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x12,0x5a,0x29}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x31,0xc0,0x7a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0x87,0x3a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xbc,0x19,0xe2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xeb,0x45,0x54}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x70,0x7c,0x47,0x00}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x92,0x44,0xfb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x1d,0x11,0x52}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x46,0xb0,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x75,0x29,0xa2,0xb8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x1b,0x08,0xaa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xe6,0x07,0xd3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xf6,0x47,0x34}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0xac,0x08,0x64}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7a,0x80,0x6d,0x94}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xe7,0xe0,0x3f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xaf,0xc3,0x1f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0xa4,0x60}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0xfe,0xf4}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x61,0x45,0x4c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x7b,0x07,0x07}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x7b,0x07,0x27}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0xba,0x11,0x11}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0xf7,0xa9,0xbe}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x85,0xf2,0xd1,0x3f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0x66,0x5e,0x26}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0x77,0x11,0x91}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0x74,0xa0,0xb0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0xe2,0x22,0x2a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8a,0xd2,0xd9,0xaa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0xff,0xa6,0xc2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8f,0xd7,0x81,0x7e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0xf4,0x13}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0x94,0x34,0xa2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0x94,0x50,0x39}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0x13,0x1e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0x8e,0x56}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0xfd,0x33}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x94,0xfb,0x06,0xd6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0x9a,0x9b,0xeb}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0x85,0xf4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x64,0x7b,0x13}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd9,0xff,0xcf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x08,0xe2,0xaf}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x9a,0x67,0x32}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xc6,0x31,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8c,0xce,0x5f,0x0e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xf8,0x5e,0x30}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xca,0x26,0xad}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x1a,0xd2,0xd9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xd7,0xd0,0xdd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xc0,0x4e,0xc2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xcd,0xad,0x4a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x98,0x10,0x49}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3a,0x6b,0x9d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0x1e,0xaa,0xf0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa3,0xbf,0xf1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xc0,0x30,0x8a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x93,0x0f,0x26}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xe7,0x39,0x23}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0x95,0x69,0x88}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x21,0x07,0xc2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x34,0x45,0x29}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xec,0x51,0xb6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x62,0x49,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x1b,0x3d,0xa2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xcf,0x9b,0xb3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x94,0xd2,0xa1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x07,0x35}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xdd,0x88,0x4a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0xf3,0xaf,0x27}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xea,0x98,0x74}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x85,0x67,0x4a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x47,0x6d,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xa5,0xab,0x3b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x37,0x5a,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xc0,0x4d,0xa2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xea,0x81,0xe9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe2,0x6c,0xed}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x14,0x72,0x85}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x64,0x04,0x6c,0x6b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x45,0x49,0x5a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x47,0xf2,0x12}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x42,0x5f,0xf3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x5a,0x0f,0xfd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x15,0x08,0xfb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x58,0x4b,0xb2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x41,0x11,0x2e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x78,0xb7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x0e,0xbb,0x33}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x65,0xe2,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x48,0x94,0xa7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x42,0x25,0x42}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x03,0x30}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xcf,0xc8,0x31}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xad,0x5b,0xd6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xc6,0x7b,0x12}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x4d,0xbc,0xf2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xdc,0x73,0x02}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xd7,0x72,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xf6,0x4b,0x06}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x12,0xcd,0xcd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x81,0x82,0x60}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x87,0x00,0x13,0x4d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xf7,0x16,0x10}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x5f,0x18,0xba}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa8,0xc1,0x16}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x72,0x69,0xfb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x23,0x94,0xa2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3b,0x08,0x53}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x83,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x24,0x5a,0x2d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xaa,0x72,0xc1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xcf,0x11,0xcd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xed,0x14,0x7b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x94,0x5c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x13,0x23,0x7c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6f,0x5a,0x96,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0xe2,0x90,0x78}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc4,0x8e,0xa3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xf1,0x87,0xc1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xb6,0x80,0xef}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x0a,0xf2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0xd8,0xd1,0x7a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x2e,0x9e,0x86}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x5c,0xdb,0xcc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf6,0x11,0x9d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x61,0x21}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0xf8,0x99,0x75}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x97,0xe0,0xf8,0xfc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x79,0x4b,0xe5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x7f,0xfb,0x43}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9a,0x14,0x02,0x8b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9d,0x0d,0x3d,0x05}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9e,0x3a,0xad,0x30}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0xfd,0x17,0x84}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x6e,0xda}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd5,0xfe,0xcd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xef,0xfe,0x64}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf2,0x96,0x27}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x51,0x8a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0xeb,0x38}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf4,0x4f,0x10}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf5,0xd9,0x77}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf8,0x66,0x75}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xfb,0x6c,0x35}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xfe,0x95,0x8b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xff,0x74,0x4e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0x46,0x5e,0x6a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x58,0x2d,0x7c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0x58,0x78,0xd2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x1a,0x31,0x2b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x1e,0x0e,0x06}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x50,0x72,0xc5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xa7,0xd6,0xf3}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xd0,0xdb,0x6c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xdc,0x43,0x9c}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xec,0x65,0x22}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x0e,0x4f,0x0f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x85,0x25,0x7d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xe3,0x57,0xf8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x3f,0xf8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x3b,0xc9,0x9c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x68,0x71,0x02}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xa1,0xd8,0x5d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x6c,0xdc,0x8a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x3d,0x61,0xe5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x4f,0x73,0x6a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x3b,0x5c,0x2a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xc3,0x04,0x4a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x3d,0x61,0xe4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xf4,0x26,0x84}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x5f,0x1b,0x3e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x3c,0x5a,0x0d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd1,0xf6,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xff,0xc7,0x21}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3d,0x3f,0xeb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xed,0xa5,0x9d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x3b,0x75,0x5d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x53,0x8d,0x0d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xf0,0x13,0x26}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x69,0x43,0x44}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcd,0xed,0xa1,0x8c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x3f,0xed,0x10}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x40,0x9b,0x78}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x4a,0x98,0x7b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbc,0x4e,0x96}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xee,0x20,0x75}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x28,0x48,0x4f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7d,0x40,0x5c,0x11}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x06,0xdd,0x32}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x71,0x41,0xa7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x35,0x3f,0x1d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x1f,0x7d,0x81}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xa5,0x99,0x2f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x59,0x2a,0x6b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x4f,0x4f,0x8d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x1e,0x3c,0xd2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x37,0x99,0x98}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xe5,0x92,0x2c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xbd,0x7e,0x23}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xfb,0x62,0xa7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x6b,0x01,0x32}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0xcf,0xe7,0xd0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xbd,0x35,0x7d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0xc3,0xda,0x53}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x71,0x6b,0x01,0x31}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xf8,0xb8,0x7f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xc2,0x38,0x9a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x42,0xaa,0xef}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x82,0x6b,0x87}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x53,0x17,0x18}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7d,0x59,0x46,0xdb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0x68,0xc1,0xd2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdc,0xe9,0x6f,0xcd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x27,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xca,0x4b,0x8d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x3d,0x04,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xaa,0xb7,0xaa}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x81,0x28,0x20}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xf1,0xae,0xa4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xe6,0xd7,0xec}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x59,0x13,0x39}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x93,0xcc,0xd8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xee,0xbb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x67,0x70,0x07}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x9d,0xd3,0xeb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc5,0xed,0x0c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xe1,0xd3,0x23}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x13,0xa8,0xa5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x32,0x9a,0x17}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x48,0xd3,0xe4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x68,0x03}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x01,0xe8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xef,0xe9,0xdd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x87,0x8b,0x43}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa0,0x24,0x82,0xb4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x92,0xd6,0xcb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x75,0x90}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x1c,0x41,0xc6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x3f,0x83,0x03}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x8b,0x3f,0xf3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x46,0x5e,0x49}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe6,0xc8,0x83}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xcd,0x09,0xac}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc5,0xab,0xda}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa5,0x65,0x76}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x37,0x26,0xc5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcd,0xc5,0xd0,0x2f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x4d,0x22,0x22}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x40,0x95,0x3e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x75,0xa3,0xfa}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0xdb,0x36}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x53,0x14,0xa8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x1f,0x94,0x5a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xea,0x98,0xa5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x4a,0x38,0x65}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xa5,0xaa,0x10}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0xab,0xaa}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x02,0xa7,0xdd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xf4,0x66,0x09}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0x1c,0x57,0x68}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xee,0x40,0x8b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x09,0xac,0x33}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x4c,0x4b,0x84}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x25,0x92,0xd3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x5a,0x4d,0xba}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x96,0x02,0x63}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf6,0x55,0xf6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb1,0x4b,0x4c,0xbe}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xd0,0xda,0x45}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc0,0x4b,0x20}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa2,0xc3,0x06}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xba,0x1f,0xf3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x09,0x1f,0xb2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x07,0x0d,0x54}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x6a,0xb4,0xc7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x11,0x6a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x51,0x3d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xaa,0x18,0x03}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x6e,0x30,0x30}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x07,0x5c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x9a,0x25}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0xbb,0x82}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x22,0x42,0xae}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x15,0x44,0x25}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x57,0x5f,0xbd}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xfd,0xd8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x38,0x3f,0x0a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf6,0x6b,0x22}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xff,0xed,0xf1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x02,0xd5,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x33,0x17,0xe0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x33,0x7b,0x9f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x39,0xd4,0x79}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x6d,0x21,0x1c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x7e,0x7c,0x5b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x7e,0x7c,0x5c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x0a,0x74,0xf2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x23,0x7e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x63,0xde}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x7c,0x6e,0x2f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xc2,0x21,0x2c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xdf,0xc9,0xc6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x1a,0x53}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x24,0x30}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0xd4,0x8d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0xfe,0x3b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4e,0xfa,0x03}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x9b,0x56,0xe2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xaf,0x86,0x23}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xf8,0x6f,0x04}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x01,0xaa}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x22,0xa1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb3,0x2b,0x72,0x0e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb6,0xd5,0xd0,0x1c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x44,0x02,0x2e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x48,0xee,0x2a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x5e,0xe2,0x22}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x5e,0xe3,0x3a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x6b,0x8b,0x3a}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x6b,0xce,0x2d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x01,0xc2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa5,0xfc,0x17}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x45,0xe8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xf6,0x61,0xd3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xed,0xd9,0xa0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x23,0x2f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x11,0x4e,0x13}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc0,0xdd,0x61}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0x72,0xba,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xed,0xf7,0xe1}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc4,0x0e,0x04}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x67,0x4b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xa3,0xef,0xe4}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa5,0xdc,0x47}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x33,0xe9}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0xb9,0xac,0xa3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x71,0x24}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x86,0xcc,0xa8}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xce,0xb1,0x26}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x53,0x4e,0x26}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8c,0x71,0xd2,0xd3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x34,0x55,0x22}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x89,0xe2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x17,0x34,0x87}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xad,0x55,0x92}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x4b,0x18}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x7a,0x5c,0x88}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x9a,0x6e,0x3a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x18,0x24,0x19}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x4c,0x3d,0xb7}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7a,0x80,0x6d,0x94}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3f,0x8e,0xd7,0xa0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xbb,0x16,0x5a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x09,0xcb}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xe6,0x0d,0x8d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x8b,0x0b,0x63}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xc6,0x72,0xe5}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x11,0x3f,0x2b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xa9,0x42,0x42}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x99,0x32}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x8b,0x05}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0xfc,0x66,0xe2}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0xc5,0x66,0xbe}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe4,0x98,0xcc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x94,0x8c,0x69}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x0c,0xbd,0x44}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x0a,0x30,0x75}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x15,0xd8,0x9c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x26,0x2f,0xe0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x2d,0xc0,0x81}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x35,0x81,0xe6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x35,0x83,0x72}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x37,0x35,0x3d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x37,0x35,0x3f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x3d,0x77,0x02}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x3d,0x94,0xcb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xba,0x02,0xa7,0x17}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x5c,0x4b,0xb2}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x7a,0x5c,0x86}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd3,0x64,0x17,0x77}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x75,0x46}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x26,0x48,0x4e,0x35}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc1,0x7a,0xb6}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x85,0xf2,0xcc,0xae}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x5b,0x62,0xea}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x03,0xd6,0xbc}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xeb,0x81,0x5e}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0x47,0xb3,0x74}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x6a,0xa5,0x3c}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x45,0xee,0x54}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x17,0xa8,0x38}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x11,0xc2,0xa3}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x57,0x01,0x2f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xde,0x7a,0x5d}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xae,0x03,0xa0}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xd3,0xc1,0x2b}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x09,0xf5,0x13}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x26,0xb3,0x7a}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x9f,0x2e,0x54}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x6b,0x13,0x53}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x51,0xdf,0x7f}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x97,0x21,0x80}, 8333},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xcc,0xd2,0xa2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x09,0xd0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa5,0xd1,0x94}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xe2,0xce,0xef}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x08,0x7c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x0a,0x93}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x00,0x82,0x8e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x03,0x59,0x9f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x49,0xea,0x8a}, 8333},
{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x4b,0x5f,0x6b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x5f,0x64,0x66}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x9b,0x54,0xb5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xa9,0xe9,0xce}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xc6,0x5d,0x56}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xe3,0x87,0xd8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x00,0x6d,0x03}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x4d,0x32,0xd0}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x6d,0x44,0x3e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x96,0x79,0x25}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xe0,0x45,0x62}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x4f,0x08,0x25}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x8d,0x56,0x0a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x0c,0xb4,0x5e}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x38,0x3f,0x0a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x74,0x5d,0x5d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9a,0xae,0xe2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9f,0x6f,0x62}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xa9,0x8a,0x02}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xbd,0x7e,0x23}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xc5,0xaf,0xbe}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc5,0xf2,0x5d,0x52}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x0b,0xd6,0x93}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x31,0x29,0x15}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x21,0x7c,0xba}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xcc,0xba,0x92}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xe9,0xee,0x73}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xf1,0xbd,0x42}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x44,0xf2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x45,0xe8}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0xb7,0x97,0x27}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0xdb,0x0e,0xcc}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x2c,0x7b,0x6d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x2c,0x7b,0xa2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x2d,0x78,0xb2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xbe,0x86,0x2c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xce,0xf8,0xb8,0x7f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xf4,0x49,0x08}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x42,0x1e,0x1b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x51,0x09,0xdf}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x69,0xf3,0xe5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x7e,0x46,0x9f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x8c,0x1e,0xa9}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xa5,0x80,0xeb}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xbe,0x02,0xf2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0x42,0xfe,0xec}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0x49,0x1b,0x21}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd3,0x48,0x42,0xe5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x19,0x25,0x7c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x47,0xeb,0x72}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x47,0xfc,0x6d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x72,0x30,0x1f}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0xae,0x97,0x76}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x42,0xcd,0xc2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x81,0xf8,0x8b}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x88,0x57,0x22}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa5,0x52,0x85}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa7,0x11,0x06}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xb3,0x9e,0xfd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xbd,0x35,0x7d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xde,0xd0,0x5d}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x31,0x9e,0xa1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x37,0x8f,0x9a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x83,0x5b,0x64}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xf5,0xce,0xb5}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xfa,0x8a,0xe6}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x0b,0xe1,0xbd}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x06,0x85}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x4b,0x58,0xb2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xac,0x8f,0x8c}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xc3,0xa9,0xd1}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xc4,0xf8,0x6a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdb,0x8a,0xa1,0xa2}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xde,0xa7,0xf8,0x5a}, 8333},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0x12,0xfe,0x37}, 8333},
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0x26,0x27,0x21,0xae,0x94,0xd5,0xc2,0x72,0x24}, 8333},
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xea,0xb9,0x5b,0x63,0x1d,0x94,0xe2,0xed,0xec,0xa1}, 8333},
{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xce,0x36,0xa1,0xc1,0xd6,0x64,0x43,0xfb,0xb3,0xe7}, 8333},
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-// Copyright (c) 2012-2014 The Bitcoin developers
+// Copyright (c) 2012-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.
fAllOk &= fOk;
nTodo -= nNow;
if (nTodo == 0 && !fMaster)
- // We processed the last element; inform the master he can exit and return the result
+ // We processed the last element; inform the master he or she can exit and return the result
condMaster.notify_one();
} else {
// first iteration
{
}
- friend class CCheckQueueControl<T>;
+ bool IsIdle()
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ return (nTotal == nIdle && nTodo == 0 && fAllOk == true);
+ }
+
};
/**
{
// passed queue is supposed to be unused, or NULL
if (pqueue != NULL) {
- assert(pqueue->nTotal == pqueue->nIdle);
- assert(pqueue->nTodo == 0);
- assert(pqueue->fAllOk == true);
+ bool isIdle = pqueue->IsIdle();
+ assert(isIdle);
}
}
-// Copyright (c) 2012-2014 The Bitcoin developers
+// Copyright (c) 2012-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.
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it
#define CLIENT_VERSION_MAJOR 0
-#define CLIENT_VERSION_MINOR 9
+#define CLIENT_VERSION_MINOR 10
#define CLIENT_VERSION_REVISION 99
#define CLIENT_VERSION_BUILD 0
* Copyright year (2009-this)
* Todo: update this when changing our copyright comments in the source
*/
-#define COPYRIGHT_YEAR 2014
+#define COPYRIGHT_YEAR 2015
#endif //HAVE_CONFIG_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_COINCONTROL_H
#define BITCOIN_COINCONTROL_H
-#include "core/transaction.h"
+#include "primitives/transaction.h"
/** Coin Control Features. */
class CCoinControl
-// Copyright (c) 2012-2014 The Bitcoin developers
+// Copyright (c) 2012-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.
nBytes += nLastUsedByte;
}
-bool CCoins::Spend(const COutPoint &out, CTxInUndo &undo) {
- if (out.n >= vout.size())
- return false;
- if (vout[out.n].IsNull())
+bool CCoins::Spend(uint32_t nPos)
+{
+ if (nPos >= vout.size() || vout[nPos].IsNull())
return false;
- undo = CTxInUndo(vout[out.n]);
- vout[out.n].SetNull();
+ vout[nPos].SetNull();
Cleanup();
- if (vout.size() == 0) {
- undo.nHeight = nHeight;
- undo.fCoinBase = fCoinBase;
- undo.nVersion = this->nVersion;
- }
return true;
}
-bool CCoins::Spend(int nPos) {
- CTxInUndo undo;
- COutPoint out(0, nPos);
- return Spend(out, undo);
-}
-
-
bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; }
bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; }
-uint256 CCoinsView::GetBestBlock() const { return uint256(0); }
+uint256 CCoinsView::GetBestBlock() const { return uint256(); }
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; }
CCoinsKeyHasher::CCoinsKeyHasher() : salt(GetRandHash()) {}
-CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), hashBlock(0) { }
+CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false) { }
CCoinsViewCache::~CCoinsViewCache()
{
CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
assert(!hasModifier);
- hasModifier = true;
std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
if (ret.second) {
if (!base->GetCoins(txid, ret.first->second.coins)) {
}
uint256 CCoinsViewCache::GetBestBlock() const {
- if (hashBlock == uint256(0))
+ if (hashBlock.IsNull())
hashBlock = base->GetBestBlock();
return hashBlock;
}
return tx.ComputePriority(dResult);
}
-CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_) {}
+CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_) {
+ assert(!cache.hasModifier);
+ cache.hasModifier = true;
+}
CCoinsModifier::~CCoinsModifier()
{
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "compressor.h"
#include "serialize.h"
#include "uint256.h"
-#include "undo.h"
#include <assert.h>
#include <stdint.h>
Cleanup();
}
- //! mark an outpoint spent, and construct undo information
- bool Spend(const COutPoint &out, CTxInUndo &undo);
-
//! mark a vout spent
- bool Spend(int nPos);
+ bool Spend(uint32_t nPos);
//! check whether a particular output is still available
bool IsAvailable(unsigned int nPos) const {
uint256 hashSerialized;
CAmount nTotalAmount;
- CCoinsStats() : nHeight(0), hashBlock(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), hashSerialized(0), nTotalAmount(0) {}
+ CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {}
};
private:
CCoinsMap::iterator FetchCoins(const uint256 &txid);
CCoinsMap::const_iterator FetchCoins(const uint256 &txid) const;
+
+ /**
+ * By making the copy constructor private, we prevent accidentally using it when one intends to create a cache on top of a base cache.
+ */
+ CCoinsViewCache(const CCoinsViewCache &);
};
#endif // BITCOIN_COINS_H
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_COMPAT_H
#define BITCOIN_COMPAT_H
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
#ifdef WIN32
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#define THREAD_PRIORITY_ABOVE_NORMAL (-2)
#endif
+#if HAVE_DECL_STRNLEN == 0
+size_t strnlen( const char *start, size_t max_len);
+#endif // HAVE_DECL_STRNLEN
+
#endif // BITCOIN_COMPAT_H
--- /dev/null
+// Copyright (c) 2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_COMPAT_BYTESWAP_H
+#define BITCOIN_COMPAT_BYTESWAP_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <stdint.h>
+
+#if defined(HAVE_BYTESWAP_H)
+#include <byteswap.h>
+#endif
+
+#if HAVE_DECL_BSWAP_16 == 0
+inline uint16_t bswap_16(uint16_t x)
+{
+ return (x >> 8) | ((x & 0x00ff) << 8);
+}
+#endif // HAVE_DECL_BSWAP16
+
+#if HAVE_DECL_BSWAP_32 == 0
+inline uint32_t bswap_32(uint32_t x)
+{
+ return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >> 8) |
+ ((x & 0x0000ff00U) << 8) | ((x & 0x000000ffU) << 24));
+}
+#endif // HAVE_DECL_BSWAP32
+
+#if HAVE_DECL_BSWAP_64 == 0
+inline uint64_t bswap_64(uint64_t x)
+{
+ return (((x & 0xff00000000000000ull) >> 56)
+ | ((x & 0x00ff000000000000ull) >> 40)
+ | ((x & 0x0000ff0000000000ull) >> 24)
+ | ((x & 0x000000ff00000000ull) >> 8)
+ | ((x & 0x00000000ff000000ull) << 8)
+ | ((x & 0x0000000000ff0000ull) << 24)
+ | ((x & 0x000000000000ff00ull) << 40)
+ | ((x & 0x00000000000000ffull) << 56));
+}
+#endif // HAVE_DECL_BSWAP64
+
+#endif // BITCOIN_COMPAT_BYTESWAP_H
--- /dev/null
+// Copyright (c) 2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_COMPAT_ENDIAN_H
+#define BITCOIN_COMPAT_ENDIAN_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <stdint.h>
+
+#include "compat/byteswap.h"
+
+#if defined(HAVE_ENDIAN_H)
+#include <endian.h>
+#endif
+
+#if defined(WORDS_BIGENDIAN)
+
+#if HAVE_DECL_HTOBE16 == 0
+inline uint16_t htobe16(uint16_t host_16bits)
+{
+ return host_16bits;
+}
+#endif // HAVE_DECL_HTOBE16
+
+#if HAVE_DECL_HTOLE16 == 0
+inline uint16_t htole16(uint16_t host_16bits)
+{
+ return bswap_16(host_16bits);
+}
+#endif // HAVE_DECL_HTOLE16
+
+#if HAVE_DECL_BE16TOH == 0
+inline uint16_t be16toh(uint16_t big_endian_16bits)
+{
+ return big_endian_16bits;
+}
+#endif // HAVE_DECL_BE16TOH
+
+#if HAVE_DECL_LE16TOH == 0
+inline uint16_t le16toh(uint16_t little_endian_16bits)
+{
+ return bswap_16(little_endian_16bits);
+}
+#endif // HAVE_DECL_LE16TOH
+
+#if HAVE_DECL_HTOBE32 == 0
+inline uint32_t htobe32(uint32_t host_32bits)
+{
+ return host_32bits;
+}
+#endif // HAVE_DECL_HTOBE32
+
+#if HAVE_DECL_HTOLE32 == 0
+inline uint32_t htole32(uint32_t host_32bits)
+{
+ return bswap_32(host_32bits);
+}
+#endif // HAVE_DECL_HTOLE32
+
+#if HAVE_DECL_BE32TOH == 0
+inline uint32_t be32toh(uint32_t big_endian_32bits)
+{
+ return big_endian_32bits;
+}
+#endif // HAVE_DECL_BE32TOH
+
+#if HAVE_DECL_LE32TOH == 0
+inline uint32_t le32toh(uint32_t little_endian_32bits)
+{
+ return bswap_32(little_endian_32bits);
+}
+#endif // HAVE_DECL_LE32TOH
+
+#if HAVE_DECL_HTOBE64 == 0
+inline uint64_t htobe64(uint64_t host_64bits)
+{
+ return host_64bits;
+}
+#endif // HAVE_DECL_HTOBE64
+
+#if HAVE_DECL_HTOLE64 == 0
+inline uint64_t htole64(uint64_t host_64bits)
+{
+ return bswap_64(host_64bits);
+}
+#endif // HAVE_DECL_HTOLE64
+
+#if HAVE_DECL_BE64TOH == 0
+inline uint64_t be64toh(uint64_t big_endian_64bits)
+{
+ return big_endian_64bits;
+}
+#endif // HAVE_DECL_BE64TOH
+
+#if HAVE_DECL_LE64TOH == 0
+inline uint64_t le64toh(uint64_t little_endian_64bits)
+{
+ return bswap_64(little_endian_64bits);
+}
+#endif // HAVE_DECL_LE64TOH
+
+#else // WORDS_BIGENDIAN
+
+#if HAVE_DECL_HTOBE16 == 0
+inline uint16_t htobe16(uint16_t host_16bits)
+{
+ return bswap_16(host_16bits);
+}
+#endif // HAVE_DECL_HTOBE16
+
+#if HAVE_DECL_HTOLE16 == 0
+inline uint16_t htole16(uint16_t host_16bits)
+{
+ return host_16bits;
+}
+#endif // HAVE_DECL_HTOLE16
+
+#if HAVE_DECL_BE16TOH == 0
+inline uint16_t be16toh(uint16_t big_endian_16bits)
+{
+ return bswap_16(big_endian_16bits);
+}
+#endif // HAVE_DECL_BE16TOH
+
+#if HAVE_DECL_LE16TOH == 0
+inline uint16_t le16toh(uint16_t little_endian_16bits)
+{
+ return little_endian_16bits;
+}
+#endif // HAVE_DECL_LE16TOH
+
+#if HAVE_DECL_HTOBE32 == 0
+inline uint32_t htobe32(uint32_t host_32bits)
+{
+ return bswap_32(host_32bits);
+}
+#endif // HAVE_DECL_HTOBE32
+
+#if HAVE_DECL_HTOLE32 == 0
+inline uint32_t htole32(uint32_t host_32bits)
+{
+ return host_32bits;
+}
+#endif // HAVE_DECL_HTOLE32
+
+#if HAVE_DECL_BE32TOH == 0
+inline uint32_t be32toh(uint32_t big_endian_32bits)
+{
+ return bswap_32(big_endian_32bits);
+}
+#endif // HAVE_DECL_BE32TOH
+
+#if HAVE_DECL_LE32TOH == 0
+inline uint32_t le32toh(uint32_t little_endian_32bits)
+{
+ return little_endian_32bits;
+}
+#endif // HAVE_DECL_LE32TOH
+
+#if HAVE_DECL_HTOBE64 == 0
+inline uint64_t htobe64(uint64_t host_64bits)
+{
+ return bswap_64(host_64bits);
+}
+#endif // HAVE_DECL_HTOBE64
+
+#if HAVE_DECL_HTOLE64 == 0
+inline uint64_t htole64(uint64_t host_64bits)
+{
+ return host_64bits;
+}
+#endif // HAVE_DECL_HTOLE64
+
+#if HAVE_DECL_BE64TOH == 0
+inline uint64_t be64toh(uint64_t big_endian_64bits)
+{
+ return bswap_64(big_endian_64bits);
+}
+#endif // HAVE_DECL_BE64TOH
+
+#if HAVE_DECL_LE64TOH == 0
+inline uint64_t le64toh(uint64_t little_endian_64bits)
+{
+ return little_endian_64bits;
+}
+#endif // HAVE_DECL_LE64TOH
+
+#endif // WORDS_BIGENDIAN
+
+#endif // BITCOIN_COMPAT_ENDIAN_H
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+++ /dev/null
-// 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 <cstddef>
-#include <istream>
-#include <stdexcept>
-#include <typeinfo>
-
-#ifndef _GLIBCXX_USE_NOEXCEPT
-#define _GLIBCXX_USE_NOEXCEPT throw()
-#endif
-
-namespace std
-{
-const char* bad_exception::what() const throw()
-{
- return "std::bad_exception";
-}
-
-const char* bad_cast::what() const throw()
-{
- return "std::bad_cast";
-}
-
-const char* bad_alloc::what() const throw()
-{
- return "std::bad_alloc";
-}
-
-namespace __detail
-{
-struct _List_node_base {
- void _M_hook(std::__detail::_List_node_base* const __position) throw() __attribute__((used))
- {
- _M_next = __position;
- _M_prev = __position->_M_prev;
- __position->_M_prev->_M_next = this;
- __position->_M_prev = this;
- }
-
- void _M_unhook() __attribute__((used))
- {
- _List_node_base* const __next_node = _M_next;
- _List_node_base* const __prev_node = _M_prev;
- __prev_node->_M_next = __next_node;
- __next_node->_M_prev = __prev_node;
- }
-
- _List_node_base* _M_next;
- _List_node_base* _M_prev;
-};
-} // namespace detail
-
-template ostream& ostream::_M_insert(bool);
-template ostream& ostream::_M_insert(long);
-template ostream& ostream::_M_insert(double);
-template ostream& ostream::_M_insert(unsigned long);
-template ostream& ostream::_M_insert(const void*);
-template ostream& __ostream_insert(ostream&, const char*, streamsize);
-template istream& istream::_M_extract(long&);
-template istream& istream::_M_extract(unsigned short&);
-
-out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT {}
-
-length_error::~length_error() _GLIBCXX_USE_NOEXCEPT {}
-
-// Used with permission.
-// See: https://github.com/madlib/madlib/commit/c3db418c0d34d6813608f2137fef1012ce03043d
-
-void ctype<char>::_M_widen_init() const
-{
- char __tmp[sizeof(_M_widen)];
- for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i)
- __tmp[__i] = __i;
- do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen);
-
- _M_widen_ok = 1;
- // Set _M_widen_ok to 2 if memcpy can't be used.
- for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i)
- if (__tmp[__i] != _M_widen[__i]) {
- _M_widen_ok = 2;
- break;
- }
-}
-
-void __throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__));
-void __throw_out_of_range_fmt(const char* err, ...)
-{
- // Safe and over-simplified version. Ignore the format and print it as-is.
- __throw_out_of_range(err);
-}
-
-} // namespace std
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
--- /dev/null
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <cstring>
+
+#if HAVE_DECL_STRNLEN == 0
+size_t strnlen( const char *start, size_t max_len)
+{
+ const char *end = (const char *)memchr(start, '\0', max_len);
+
+ return end ? (size_t)(end - start) : max_len;
+}
+#endif // HAVE_DECL_STRNLEN
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_COMPRESSOR_H
#define BITCOIN_COMPRESSOR_H
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "script/script.h"
#include "serialize.h"
+++ /dev/null
-// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#include "core/block.h"
-
-#include "hash.h"
-#include "tinyformat.h"
-#include "utilstrencodings.h"
-
-uint256 CBlockHeader::GetHash() const
-{
- return Hash(BEGIN(nVersion), END(nNonce));
-}
-
-uint256 CBlock::BuildMerkleTree(bool* fMutated) const
-{
- /* WARNING! If you're reading this because you're learning about crypto
- and/or designing a new system that will use merkle trees, keep in mind
- that the following merkle tree algorithm has a serious flaw related to
- duplicate txids, resulting in a vulnerability (CVE-2012-2459).
-
- The reason is that if the number of hashes in the list at a given time
- is odd, the last one is duplicated before computing the next level (which
- is unusual in Merkle trees). This results in certain sequences of
- transactions leading to the same merkle root. For example, these two
- trees:
-
- A A
- / \ / \
- B C B C
- / \ | / \ / \
- D E F D E F F
- / \ / \ / \ / \ / \ / \ / \
- 1 2 3 4 5 6 1 2 3 4 5 6 5 6
-
- for transaction lists [1,2,3,4,5,6] and [1,2,3,4,5,6,5,6] (where 5 and
- 6 are repeated) result in the same root hash A (because the hash of both
- of (F) and (F,F) is C).
-
- The vulnerability results from being able to send a block with such a
- transaction list, with the same merkle root, and the same block hash as
- the original without duplication, resulting in failed validation. If the
- receiving node proceeds to mark that block as permanently invalid
- however, it will fail to accept further unmodified (and thus potentially
- valid) versions of the same block. We defend against this by detecting
- the case where we would hash two identical hashes at the end of the list
- together, and treating that identically to the block having an invalid
- merkle root. Assuming no double-SHA256 collisions, this will detect all
- known ways of changing the transactions without affecting the merkle
- root.
- */
- vMerkleTree.clear();
- vMerkleTree.reserve(vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes.
- for (std::vector<CTransaction>::const_iterator it(vtx.begin()); it != vtx.end(); ++it)
- vMerkleTree.push_back(it->GetHash());
- int j = 0;
- bool mutated = false;
- for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
- {
- for (int i = 0; i < nSize; i += 2)
- {
- int i2 = std::min(i+1, nSize-1);
- if (i2 == i + 1 && i2 + 1 == nSize && vMerkleTree[j+i] == vMerkleTree[j+i2]) {
- // Two identical hashes at the end of the list at a particular level.
- mutated = true;
- }
- vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]),
- BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
- }
- j += nSize;
- }
- if (fMutated) {
- *fMutated = mutated;
- }
- return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
-}
-
-std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
-{
- if (vMerkleTree.empty())
- BuildMerkleTree();
- std::vector<uint256> vMerkleBranch;
- int j = 0;
- for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
- {
- int i = std::min(nIndex^1, nSize-1);
- vMerkleBranch.push_back(vMerkleTree[j+i]);
- nIndex >>= 1;
- j += nSize;
- }
- return vMerkleBranch;
-}
-
-uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
-{
- if (nIndex == -1)
- return 0;
- for (std::vector<uint256>::const_iterator it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it)
- {
- if (nIndex & 1)
- hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash));
- else
- hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it));
- nIndex >>= 1;
- }
- return hash;
-}
-
-std::string CBlock::ToString() const
-{
- std::stringstream s;
- s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
- GetHash().ToString(),
- nVersion,
- hashPrevBlock.ToString(),
- hashMerkleRoot.ToString(),
- nTime, nBits, nNonce,
- vtx.size());
- for (unsigned int i = 0; i < vtx.size(); i++)
- {
- s << " " << vtx[i].ToString() << "\n";
- }
- s << " vMerkleTree: ";
- for (unsigned int i = 0; i < vMerkleTree.size(); i++)
- s << " " << vMerkleTree[i].ToString();
- s << "\n";
- return s.str();
-}
+++ /dev/null
-// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef BITCOIN_CORE_BLOCK_H
-#define BITCOIN_CORE_BLOCK_H
-
-#include "core/transaction.h"
-#include "serialize.h"
-#include "uint256.h"
-
-/** Nodes collect new transactions into a block, hash them into a hash tree,
- * and scan through nonce values to make the block's hash satisfy proof-of-work
- * requirements. When they solve the proof-of-work, they broadcast the block
- * to everyone and the block is added to the block chain. The first transaction
- * in the block is a special one that creates a new coin owned by the creator
- * of the block.
- */
-class CBlockHeader
-{
-public:
- // header
- static const int32_t CURRENT_VERSION=2;
- int32_t nVersion;
- uint256 hashPrevBlock;
- uint256 hashMerkleRoot;
- uint32_t nTime;
- uint32_t nBits;
- uint32_t nNonce;
-
- CBlockHeader()
- {
- SetNull();
- }
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(this->nVersion);
- nVersion = this->nVersion;
- READWRITE(hashPrevBlock);
- READWRITE(hashMerkleRoot);
- READWRITE(nTime);
- READWRITE(nBits);
- READWRITE(nNonce);
- }
-
- void SetNull()
- {
- nVersion = CBlockHeader::CURRENT_VERSION;
- hashPrevBlock = 0;
- hashMerkleRoot = 0;
- nTime = 0;
- nBits = 0;
- nNonce = 0;
- }
-
- bool IsNull() const
- {
- return (nBits == 0);
- }
-
- uint256 GetHash() const;
-
- int64_t GetBlockTime() const
- {
- return (int64_t)nTime;
- }
-};
-
-
-class CBlock : public CBlockHeader
-{
-public:
- // network and disk
- std::vector<CTransaction> vtx;
-
- // memory only
- mutable std::vector<uint256> vMerkleTree;
-
- CBlock()
- {
- SetNull();
- }
-
- CBlock(const CBlockHeader &header)
- {
- SetNull();
- *((CBlockHeader*)this) = header;
- }
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(*(CBlockHeader*)this);
- READWRITE(vtx);
- }
-
- void SetNull()
- {
- CBlockHeader::SetNull();
- vtx.clear();
- vMerkleTree.clear();
- }
-
- CBlockHeader GetBlockHeader() const
- {
- CBlockHeader block;
- block.nVersion = nVersion;
- block.hashPrevBlock = hashPrevBlock;
- block.hashMerkleRoot = hashMerkleRoot;
- block.nTime = nTime;
- block.nBits = nBits;
- block.nNonce = nNonce;
- return block;
- }
-
- // Build the in-memory merkle tree for this block and return the merkle root.
- // If non-NULL, *mutated is set to whether mutation was detected in the merkle
- // tree (a duplication of transactions in the block leading to an identical
- // merkle root).
- uint256 BuildMerkleTree(bool* mutated = NULL) const;
-
- std::vector<uint256> GetMerkleBranch(int nIndex) const;
- static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex);
- std::string ToString() const;
-};
-
-
-/** Describes a place in the block chain to another node such that if the
- * other node doesn't have the same branch, it can find a recent common trunk.
- * The further back it is, the further before the fork it may be.
- */
-struct CBlockLocator
-{
- std::vector<uint256> vHave;
-
- CBlockLocator() {}
-
- CBlockLocator(const std::vector<uint256>& vHaveIn)
- {
- vHave = vHaveIn;
- }
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- if (!(nType & SER_GETHASH))
- READWRITE(nVersion);
- READWRITE(vHave);
- }
-
- void SetNull()
- {
- vHave.clear();
- }
-
- bool IsNull()
- {
- return vHave.empty();
- }
-};
-
-#endif // BITCOIN_CORE_BLOCK_H
+++ /dev/null
-// 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 "core/transaction.h"
-
-#include "hash.h"
-#include "tinyformat.h"
-#include "utilstrencodings.h"
-
-std::string COutPoint::ToString() const
-{
- return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n);
-}
-
-CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn)
-{
- prevout = prevoutIn;
- scriptSig = scriptSigIn;
- nSequence = nSequenceIn;
-}
-
-CTxIn::CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn)
-{
- prevout = COutPoint(hashPrevTx, nOut);
- scriptSig = scriptSigIn;
- nSequence = nSequenceIn;
-}
-
-std::string CTxIn::ToString() const
-{
- std::string str;
- str += "CTxIn(";
- str += prevout.ToString();
- if (prevout.IsNull())
- str += strprintf(", coinbase %s", HexStr(scriptSig));
- else
- str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24));
- if (nSequence != std::numeric_limits<unsigned int>::max())
- str += strprintf(", nSequence=%u", nSequence);
- str += ")";
- return str;
-}
-
-CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn)
-{
- nValue = nValueIn;
- scriptPubKey = scriptPubKeyIn;
-}
-
-uint256 CTxOut::GetHash() const
-{
- return SerializeHash(*this);
-}
-
-std::string CTxOut::ToString() const
-{
- return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30));
-}
-
-CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}
-CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {}
-
-uint256 CMutableTransaction::GetHash() const
-{
- return SerializeHash(*this);
-}
-
-void CTransaction::UpdateHash() const
-{
- *const_cast<uint256*>(&hash) = SerializeHash(*this);
-}
-
-CTransaction::CTransaction() : hash(0), nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { }
-
-CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {
- UpdateHash();
-}
-
-CTransaction& CTransaction::operator=(const CTransaction &tx) {
- *const_cast<int*>(&nVersion) = tx.nVersion;
- *const_cast<std::vector<CTxIn>*>(&vin) = tx.vin;
- *const_cast<std::vector<CTxOut>*>(&vout) = tx.vout;
- *const_cast<unsigned int*>(&nLockTime) = tx.nLockTime;
- *const_cast<uint256*>(&hash) = tx.hash;
- return *this;
-}
-
-CAmount CTransaction::GetValueOut() const
-{
- CAmount nValueOut = 0;
- for (std::vector<CTxOut>::const_iterator it(vout.begin()); it != vout.end(); ++it)
- {
- nValueOut += it->nValue;
- if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut))
- throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
- }
- return nValueOut;
-}
-
-double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const
-{
- nTxSize = CalculateModifiedSize(nTxSize);
- if (nTxSize == 0) return 0.0;
-
- return dPriorityInputs / nTxSize;
-}
-
-unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const
-{
- // In order to avoid disincentivizing cleaning up the UTXO set we don't count
- // the constant overhead for each txin and up to 110 bytes of scriptSig (which
- // is enough to cover a compressed pubkey p2sh redemption) for priority.
- // Providing any more cleanup incentive than making additional inputs free would
- // risk encouraging people to create junk outputs to redeem later.
- if (nTxSize == 0)
- nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
- for (std::vector<CTxIn>::const_iterator it(vin.begin()); it != vin.end(); ++it)
- {
- unsigned int offset = 41U + std::min(110U, (unsigned int)it->scriptSig.size());
- if (nTxSize > offset)
- nTxSize -= offset;
- }
- return nTxSize;
-}
-
-std::string CTransaction::ToString() const
-{
- std::string str;
- str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
- GetHash().ToString().substr(0,10),
- nVersion,
- vin.size(),
- vout.size(),
- nLockTime);
- for (unsigned int i = 0; i < vin.size(); i++)
- str += " " + vin[i].ToString() + "\n";
- for (unsigned int i = 0; i < vout.size(); i++)
- str += " " + vout[i].ToString() + "\n";
- return str;
-}
+++ /dev/null
-// 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_CORE_TRANSACTION_H
-#define BITCOIN_CORE_TRANSACTION_H
-
-#include "amount.h"
-#include "script/script.h"
-#include "serialize.h"
-#include "uint256.h"
-
-/** An outpoint - a combination of a transaction hash and an index n into its vout */
-class COutPoint
-{
-public:
- uint256 hash;
- uint32_t n;
-
- COutPoint() { SetNull(); }
- COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; }
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(FLATDATA(*this));
- }
-
- void SetNull() { hash = 0; n = (uint32_t) -1; }
- bool IsNull() const { return (hash == 0 && n == (uint32_t) -1); }
-
- friend bool operator<(const COutPoint& a, const COutPoint& b)
- {
- return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
- }
-
- friend bool operator==(const COutPoint& a, const COutPoint& b)
- {
- return (a.hash == b.hash && a.n == b.n);
- }
-
- friend bool operator!=(const COutPoint& a, const COutPoint& b)
- {
- return !(a == b);
- }
-
- std::string ToString() const;
-};
-
-/** An input of a transaction. It contains the location of the previous
- * transaction's output that it claims and a signature that matches the
- * output's public key.
- */
-class CTxIn
-{
-public:
- COutPoint prevout;
- CScript scriptSig;
- uint32_t nSequence;
-
- CTxIn()
- {
- nSequence = std::numeric_limits<unsigned int>::max();
- }
-
- explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max());
- CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<uint32_t>::max());
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(prevout);
- READWRITE(scriptSig);
- READWRITE(nSequence);
- }
-
- bool IsFinal() const
- {
- return (nSequence == std::numeric_limits<uint32_t>::max());
- }
-
- friend bool operator==(const CTxIn& a, const CTxIn& b)
- {
- return (a.prevout == b.prevout &&
- a.scriptSig == b.scriptSig &&
- a.nSequence == b.nSequence);
- }
-
- friend bool operator!=(const CTxIn& a, const CTxIn& b)
- {
- return !(a == b);
- }
-
- std::string ToString() const;
-};
-
-/** An output of a transaction. It contains the public key that the next input
- * must be able to sign with to claim it.
- */
-class CTxOut
-{
-public:
- CAmount nValue;
- CScript scriptPubKey;
-
- CTxOut()
- {
- SetNull();
- }
-
- CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(nValue);
- READWRITE(scriptPubKey);
- }
-
- void SetNull()
- {
- nValue = -1;
- scriptPubKey.clear();
- }
-
- bool IsNull() const
- {
- return (nValue == -1);
- }
-
- uint256 GetHash() const;
-
- bool IsDust(CFeeRate minRelayTxFee) const
- {
- // "Dust" is defined in terms of CTransaction::minRelayTxFee,
- // which has units satoshis-per-kilobyte.
- // If you'd pay more than 1/3 in fees
- // to spend something, then we consider it dust.
- // A typical txout is 34 bytes big, and will
- // need a CTxIn of at least 148 bytes to spend:
- // so dust is a txout less than 546 satoshis
- // with default minRelayTxFee.
- size_t nSize = GetSerializeSize(SER_DISK,0)+148u;
- return (nValue < 3*minRelayTxFee.GetFee(nSize));
- }
-
- friend bool operator==(const CTxOut& a, const CTxOut& b)
- {
- return (a.nValue == b.nValue &&
- a.scriptPubKey == b.scriptPubKey);
- }
-
- friend bool operator!=(const CTxOut& a, const CTxOut& b)
- {
- return !(a == b);
- }
-
- std::string ToString() const;
-};
-
-struct CMutableTransaction;
-
-/** The basic transaction that is broadcasted on the network and contained in
- * blocks. A transaction can contain multiple inputs and outputs.
- */
-class CTransaction
-{
-private:
- /** Memory only. */
- const uint256 hash;
- void UpdateHash() const;
-
-public:
- static const int32_t CURRENT_VERSION=1;
-
- // The local variables are made const to prevent unintended modification
- // without updating the cached hash value. However, CTransaction is not
- // actually immutable; deserialization and assignment are implemented,
- // and bypass the constness. This is safe, as they update the entire
- // structure, including the hash.
- const int32_t nVersion;
- const std::vector<CTxIn> vin;
- const std::vector<CTxOut> vout;
- const uint32_t nLockTime;
-
- /** Construct a CTransaction that qualifies as IsNull() */
- CTransaction();
-
- /** Convert a CMutableTransaction into a CTransaction. */
- CTransaction(const CMutableTransaction &tx);
-
- CTransaction& operator=(const CTransaction& tx);
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(*const_cast<int32_t*>(&this->nVersion));
- nVersion = this->nVersion;
- READWRITE(*const_cast<std::vector<CTxIn>*>(&vin));
- READWRITE(*const_cast<std::vector<CTxOut>*>(&vout));
- READWRITE(*const_cast<uint32_t*>(&nLockTime));
- if (ser_action.ForRead())
- UpdateHash();
- }
-
- bool IsNull() const {
- return vin.empty() && vout.empty();
- }
-
- const uint256& GetHash() const {
- return hash;
- }
-
- // Return sum of txouts.
- CAmount GetValueOut() const;
- // GetValueIn() is a method on CCoinsViewCache, because
- // inputs must be known to compute value in.
-
- // Compute priority, given priority of inputs and (optionally) tx size
- double ComputePriority(double dPriorityInputs, unsigned int nTxSize=0) const;
-
- // Compute modified tx size for priority calculation (optionally given tx size)
- unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;
-
- bool IsCoinBase() const
- {
- return (vin.size() == 1 && vin[0].prevout.IsNull());
- }
-
- friend bool operator==(const CTransaction& a, const CTransaction& b)
- {
- return a.hash == b.hash;
- }
-
- friend bool operator!=(const CTransaction& a, const CTransaction& b)
- {
- return a.hash != b.hash;
- }
-
- std::string ToString() const;
-};
-
-/** A mutable version of CTransaction. */
-struct CMutableTransaction
-{
- int32_t nVersion;
- std::vector<CTxIn> vin;
- std::vector<CTxOut> vout;
- uint32_t nLockTime;
-
- CMutableTransaction();
- CMutableTransaction(const CTransaction& tx);
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(this->nVersion);
- nVersion = this->nVersion;
- READWRITE(vin);
- READWRITE(vout);
- READWRITE(nLockTime);
- }
-
- /** Compute the hash of this CMutableTransaction. This is computed on the
- * fly, as opposed to GetHash() in CTransaction, which uses a cached result.
- */
- uint256 GetHash() const;
-};
-
-#endif // BITCOIN_CORE_TRANSACTION_H
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_CORE_IO_H
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 uint256 ParseHashStr(const std::string&, const std::string& strName);
extern std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
// core_write.cpp
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "core_io.h"
-#include "core/block.h"
-#include "core/transaction.h"
+#include "primitives/block.h"
+#include "primitives/transaction.h"
#include "script/script.h"
#include "serialize.h"
#include "streams.h"
#include <boost/algorithm/string/split.hpp>
#include <boost/assign/list_of.hpp>
-using namespace boost;
-using namespace boost::algorithm;
using namespace std;
CScript ParseScript(std::string s)
string strName(name);
mapOpNames[strName] = (opcodetype)op;
// Convenience: OP_ADD and just ADD are both recognized:
- replace_first(strName, "OP_", "");
+ boost::algorithm::replace_first(strName, "OP_", "");
mapOpNames[strName] = (opcodetype)op;
}
}
vector<string> words;
- split(words, s, is_any_of(" \t\n"), token_compress_on);
+ boost::algorithm::split(words, s, boost::algorithm::is_any_of(" \t\n"), boost::algorithm::token_compress_on);
for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w)
{
{
// Empty string, ignore. (boost::split given '' will return one word)
}
- else if (all(*w, is_digit()) ||
- (starts_with(*w, "-") && all(string(w->begin()+1, w->end()), is_digit())))
+ else if (all(*w, boost::algorithm::is_digit()) ||
+ (boost::algorithm::starts_with(*w, "-") && all(string(w->begin()+1, w->end()), boost::algorithm::is_digit())))
{
// Number
int64_t n = atoi64(*w);
result << n;
}
- else if (starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end())))
+ else if (boost::algorithm::starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end())))
{
// Raw hex data, inserted NOT pushed onto stack:
std::vector<unsigned char> raw = ParseHex(string(w->begin()+2, w->end()));
result.insert(result.end(), raw.begin(), raw.end());
}
- else if (w->size() >= 2 && starts_with(*w, "'") && ends_with(*w, "'"))
+ else if (w->size() >= 2 && boost::algorithm::starts_with(*w, "'") && boost::algorithm::ends_with(*w, "'"))
{
// Single-quoted string, pushed as data. NOTE: this is poor-man's
// parsing, spaces/tabs/newlines in single-quoted strings won't work.
try {
ssData >> tx;
}
- catch (const std::exception &) {
+ catch (const std::exception&) {
return false;
}
try {
ssBlock >> block;
}
- catch (const std::exception &) {
+ catch (const std::exception&) {
return false;
}
string strHex;
if (v.isStr())
strHex = v.getValStr();
+ return ParseHashStr(strHex, strName); // Note: ParseHashStr("") throws a runtime_error
+}
+
+uint256 ParseHashStr(const std::string& strHex, const std::string& strName)
+{
if (!IsHex(strHex)) // Note: IsHex("") is false
throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "core_io.h"
#include "base58.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "script/script.h"
#include "script/standard.h"
#include "serialize.h"
}
entry.pushKV("vout", vout);
- if (hashBlock != 0)
+ if (!hashBlock.IsNull())
entry.pushKV("blockhash", hashBlock.GetHex());
+
+ entry.pushKV("hex", EncodeHexTx(tx)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction".
}
-// Copyright (c) 2009-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "crypter.h"
if (i != (int)WALLET_CRYPTO_KEY_SIZE)
{
- OPENSSL_cleanse(chKey, sizeof(chKey));
- OPENSSL_cleanse(chIV, sizeof(chIV));
+ memory_cleanse(chKey, sizeof(chKey));
+ memory_cleanse(chIV, sizeof(chIV));
return false;
}
}
-bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext)
+static bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext)
{
CCrypter cKeyCrypter;
std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
return cKeyCrypter.Encrypt(*((const CKeyingMaterial*)&vchPlaintext), vchCiphertext);
}
-bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext)
+static bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext)
{
CCrypter cKeyCrypter;
std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext));
}
+static bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCryptedSecret, const CPubKey& vchPubKey, CKey& key)
+{
+ CKeyingMaterial vchSecret;
+ if(!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
+ return false;
+
+ if (vchSecret.size() != 32)
+ return false;
+
+ key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
+ return key.VerifyPubKey(vchPubKey);
+}
+
bool CCryptoKeyStore::SetCrypted()
{
LOCK(cs_KeyStore);
{
const CPubKey &vchPubKey = (*mi).second.first;
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
- CKeyingMaterial vchSecret;
- if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
- {
- keyFail = true;
- break;
- }
- if (vchSecret.size() != 32)
- {
- keyFail = true;
- break;
- }
CKey key;
- key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
- if (key.GetPubKey() != vchPubKey)
+ if (!DecryptKey(vMasterKeyIn, vchCryptedSecret, vchPubKey, key))
{
keyFail = true;
break;
{
const CPubKey &vchPubKey = (*mi).second.first;
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
- CKeyingMaterial vchSecret;
- if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
- return false;
- if (vchSecret.size() != 32)
- return false;
- keyOut.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
- return true;
+ return DecryptKey(vMasterKey, vchCryptedSecret, vchPubKey, keyOut);
}
}
return false;
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
void CleanKey()
{
- OPENSSL_cleanse(chKey, sizeof(chKey));
- OPENSSL_cleanse(chIV, sizeof(chIV));
+ memory_cleanse(chKey, sizeof(chKey));
+ memory_cleanse(chIV, sizeof(chIV));
fKeySet = false;
}
}
};
-bool EncryptSecret(const CKeyingMaterial& vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext);
-bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CKeyingMaterial& vchPlaintext);
-
/** Keystore which keeps the private keys encrypted.
* It derives from the basic key store, which is used if no encryption is active.
*/
-// Copyright (c) 2014 The Bitcoin developers
+// 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.
#include <stdint.h>
-#if defined(HAVE_ENDIAN_H)
-#include <endian.h>
-#endif
+#include "compat/endian.h"
+
+uint16_t static inline ReadLE16(const unsigned char* ptr)
+{
+ return le16toh(*((uint16_t*)ptr));
+}
uint32_t static inline ReadLE32(const unsigned char* ptr)
{
-#if HAVE_DECL_LE32TOH == 1
return le32toh(*((uint32_t*)ptr));
-#elif !defined(WORDS_BIGENDIAN)
- return *((uint32_t*)ptr);
-#else
- return ((uint32_t)ptr[3] << 24 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[0]);
-#endif
}
uint64_t static inline ReadLE64(const unsigned char* ptr)
{
-#if HAVE_DECL_LE64TOH == 1
return le64toh(*((uint64_t*)ptr));
-#elif !defined(WORDS_BIGENDIAN)
- return *((uint64_t*)ptr);
-#else
- return ((uint64_t)ptr[7] << 56 | (uint64_t)ptr[6] << 48 | (uint64_t)ptr[5] << 40 | (uint64_t)ptr[4] << 32 |
- (uint64_t)ptr[3] << 24 | (uint64_t)ptr[2] << 16 | (uint64_t)ptr[1] << 8 | (uint64_t)ptr[0]);
-#endif
+}
+
+void static inline WriteLE16(unsigned char* ptr, uint16_t x)
+{
+ *((uint16_t*)ptr) = htole16(x);
}
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
{
-#if HAVE_DECL_HTOLE32 == 1
*((uint32_t*)ptr) = htole32(x);
-#elif !defined(WORDS_BIGENDIAN)
- *((uint32_t*)ptr) = x;
-#else
- ptr[3] = x >> 24;
- ptr[2] = x >> 16;
- ptr[1] = x >> 8;
- ptr[0] = x;
-#endif
}
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
{
-#if HAVE_DECL_HTOLE64 == 1
*((uint64_t*)ptr) = htole64(x);
-#elif !defined(WORDS_BIGENDIAN)
- *((uint64_t*)ptr) = x;
-#else
- ptr[7] = x >> 56;
- ptr[6] = x >> 48;
- ptr[5] = x >> 40;
- ptr[4] = x >> 32;
- ptr[3] = x >> 24;
- ptr[2] = x >> 16;
- ptr[1] = x >> 8;
- ptr[0] = x;
-#endif
}
uint32_t static inline ReadBE32(const unsigned char* ptr)
{
-#if HAVE_DECL_BE32TOH == 1
return be32toh(*((uint32_t*)ptr));
-#else
- return ((uint32_t)ptr[0] << 24 | (uint32_t)ptr[1] << 16 | (uint32_t)ptr[2] << 8 | (uint32_t)ptr[3]);
-#endif
}
uint64_t static inline ReadBE64(const unsigned char* ptr)
{
-#if HAVE_DECL_BE64TOH == 1
return be64toh(*((uint64_t*)ptr));
-#else
- return ((uint64_t)ptr[0] << 56 | (uint64_t)ptr[1] << 48 | (uint64_t)ptr[2] << 40 | (uint64_t)ptr[3] << 32 |
- (uint64_t)ptr[4] << 24 | (uint64_t)ptr[5] << 16 | (uint64_t)ptr[6] << 8 | (uint64_t)ptr[7]);
-#endif
}
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
{
-#if HAVE_DECL_HTOBE32 == 1
*((uint32_t*)ptr) = htobe32(x);
-#else
- ptr[0] = x >> 24;
- ptr[1] = x >> 16;
- ptr[2] = x >> 8;
- ptr[3] = x;
-#endif
}
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
{
-#if HAVE_DECL_HTOBE64 == 1
*((uint64_t*)ptr) = htobe64(x);
-#else
- ptr[0] = x >> 56;
- ptr[1] = x >> 48;
- ptr[2] = x >> 40;
- ptr[3] = x >> 32;
- ptr[4] = x >> 24;
- ptr[5] = x >> 16;
- ptr[6] = x >> 8;
- ptr[7] = x;
-#endif
}
#endif // BITCOIN_CRYPTO_COMMON_H
--- /dev/null
+// 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.
+
+#include "crypto/hmac_sha256.h"
+
+#include <string.h>
+
+CHMAC_SHA256::CHMAC_SHA256(const unsigned char* key, size_t keylen)
+{
+ unsigned char rkey[64];
+ if (keylen <= 64) {
+ memcpy(rkey, key, keylen);
+ memset(rkey + keylen, 0, 64 - keylen);
+ } else {
+ CSHA256().Write(key, keylen).Finalize(rkey);
+ memset(rkey + 32, 0, 32);
+ }
+
+ for (int n = 0; n < 64; n++)
+ rkey[n] ^= 0x5c;
+ outer.Write(rkey, 64);
+
+ for (int n = 0; n < 64; n++)
+ rkey[n] ^= 0x5c ^ 0x36;
+ inner.Write(rkey, 64);
+}
+
+void CHMAC_SHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
+{
+ unsigned char temp[32];
+ inner.Finalize(temp);
+ outer.Write(temp, 32).Finalize(hash);
+}
--- /dev/null
+// 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.
+
+#ifndef BITCOIN_CRYPTO_HMAC_SHA256_H
+#define BITCOIN_CRYPTO_HMAC_SHA256_H
+
+#include "crypto/sha256.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/** A hasher class for HMAC-SHA-512. */
+class CHMAC_SHA256
+{
+private:
+ CSHA256 outer;
+ CSHA256 inner;
+
+public:
+ static const size_t OUTPUT_SIZE = 32;
+
+ CHMAC_SHA256(const unsigned char* key, size_t keylen);
+ CHMAC_SHA256& Write(const unsigned char* data, size_t len)
+ {
+ inner.Write(data, len);
+ return *this;
+ }
+ void Finalize(unsigned char hash[OUTPUT_SIZE]);
+};
+
+#endif // BITCOIN_CRYPTO_HMAC_SHA256_H
--- /dev/null
+// 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.
+
+#include "crypto/hmac_sha512.h"
+
+#include <string.h>
+
+CHMAC_SHA512::CHMAC_SHA512(const unsigned char* key, size_t keylen)
+{
+ unsigned char rkey[128];
+ if (keylen <= 128) {
+ memcpy(rkey, key, keylen);
+ memset(rkey + keylen, 0, 128 - keylen);
+ } else {
+ CSHA512().Write(key, keylen).Finalize(rkey);
+ memset(rkey + 64, 0, 64);
+ }
+
+ for (int n = 0; n < 128; n++)
+ rkey[n] ^= 0x5c;
+ outer.Write(rkey, 128);
+
+ for (int n = 0; n < 128; n++)
+ rkey[n] ^= 0x5c ^ 0x36;
+ inner.Write(rkey, 128);
+}
+
+void CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE])
+{
+ unsigned char temp[64];
+ inner.Finalize(temp);
+ outer.Write(temp, 64).Finalize(hash);
+}
--- /dev/null
+// 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.
+
+#ifndef BITCOIN_CRYPTO_HMAC_SHA512_H
+#define BITCOIN_CRYPTO_HMAC_SHA512_H
+
+#include "crypto/sha512.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/** A hasher class for HMAC-SHA-512. */
+class CHMAC_SHA512
+{
+private:
+ CSHA512 outer;
+ CSHA512 inner;
+
+public:
+ static const size_t OUTPUT_SIZE = 64;
+
+ CHMAC_SHA512(const unsigned char* key, size_t keylen);
+ CHMAC_SHA512& Write(const unsigned char* data, size_t len)
+ {
+ inner.Write(data, len);
+ return *this;
+ }
+ void Finalize(unsigned char hash[OUTPUT_SIZE]);
+};
+
+#endif // BITCOIN_CRYPTO_HMAC_SHA512_H
-// Copyright (c) 2014 The Bitcoin developers
+// 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.
-// Copyright (c) 2014 The Bitcoin developers
+// 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.
-// Copyright (c) 2014 The Bitcoin developers
+// 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.
-// Copyright (c) 2014 The Bitcoin developers
+// 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.
+++ /dev/null
-// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#include "crypto/sha2.h"
-
-#include "crypto/common.h"
-
-#include <string.h>
-
-// Internal implementation code.
-namespace
-{
-/// Internal SHA-256 implementation.
-namespace sha256
-{
-uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }
-uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }
-uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
-uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
-uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
-uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
-
-/** One round of SHA-256. */
-void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, uint32_t f, uint32_t g, uint32_t& h, uint32_t k, uint32_t w)
-{
- uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
- uint32_t t2 = Sigma0(a) + Maj(a, b, c);
- d += t1;
- h = t1 + t2;
-}
-
-/** Initialize SHA-256 state. */
-void inline Initialize(uint32_t* s)
-{
- s[0] = 0x6a09e667ul;
- s[1] = 0xbb67ae85ul;
- s[2] = 0x3c6ef372ul;
- s[3] = 0xa54ff53aul;
- s[4] = 0x510e527ful;
- s[5] = 0x9b05688cul;
- s[6] = 0x1f83d9abul;
- s[7] = 0x5be0cd19ul;
-}
-
-/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
-void Transform(uint32_t* s, const unsigned char* chunk)
-{
- uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
- uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
-
- Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0));
- Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4));
- Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8));
- Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12));
- Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16));
- Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20));
- Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24));
- Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28));
- Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32));
- Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36));
- Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40));
- Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44));
- Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48));
- Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52));
- Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56));
- Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60));
-
- Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));
- Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));
- Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));
- Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));
- Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));
- Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));
- Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));
- Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));
- Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));
- Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));
- Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));
- Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));
- Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
- Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
- Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
- Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));
-
- Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));
- Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));
- Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));
- Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));
- Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));
- Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));
- Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));
- Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));
- Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));
- Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));
- Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));
- Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));
- Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));
- Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));
- Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));
- Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));
-
- Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));
- Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));
- Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));
- Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));
- Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));
- Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));
- Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));
- Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));
- Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));
- Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));
- Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));
- Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));
- Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));
- Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));
- Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
- Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));
-
- s[0] += a;
- s[1] += b;
- s[2] += c;
- s[3] += d;
- s[4] += e;
- s[5] += f;
- s[6] += g;
- s[7] += h;
-}
-
-} // namespace sha256
-
-/// Internal SHA-512 implementation.
-namespace sha512
-{
-uint64_t inline Ch(uint64_t x, uint64_t y, uint64_t z) { return z ^ (x & (y ^ z)); }
-uint64_t inline Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) | (z & (x | y)); }
-uint64_t inline Sigma0(uint64_t x) { return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25); }
-uint64_t inline Sigma1(uint64_t x) { return (x >> 14 | x << 50) ^ (x >> 18 | x << 46) ^ (x >> 41 | x << 23); }
-uint64_t inline sigma0(uint64_t x) { return (x >> 1 | x << 63) ^ (x >> 8 | x << 56) ^ (x >> 7); }
-uint64_t inline sigma1(uint64_t x) { return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6); }
-
-/** One round of SHA-512. */
-void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t& d, uint64_t e, uint64_t f, uint64_t g, uint64_t& h, uint64_t k, uint64_t w)
-{
- uint64_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
- uint64_t t2 = Sigma0(a) + Maj(a, b, c);
- d += t1;
- h = t1 + t2;
-}
-
-/** Initialize SHA-256 state. */
-void inline Initialize(uint64_t* s)
-{
- s[0] = 0x6a09e667f3bcc908ull;
- s[1] = 0xbb67ae8584caa73bull;
- s[2] = 0x3c6ef372fe94f82bull;
- s[3] = 0xa54ff53a5f1d36f1ull;
- s[4] = 0x510e527fade682d1ull;
- s[5] = 0x9b05688c2b3e6c1full;
- s[6] = 0x1f83d9abfb41bd6bull;
- s[7] = 0x5be0cd19137e2179ull;
-}
-
-/** Perform one SHA-512 transformation, processing a 128-byte chunk. */
-void Transform(uint64_t* s, const unsigned char* chunk)
-{
- uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
- uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
-
- Round(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22ull, w0 = ReadBE64(chunk + 0));
- Round(h, a, b, c, d, e, f, g, 0x7137449123ef65cdull, w1 = ReadBE64(chunk + 8));
- Round(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2full, w2 = ReadBE64(chunk + 16));
- Round(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbcull, w3 = ReadBE64(chunk + 24));
- Round(e, f, g, h, a, b, c, d, 0x3956c25bf348b538ull, w4 = ReadBE64(chunk + 32));
- Round(d, e, f, g, h, a, b, c, 0x59f111f1b605d019ull, w5 = ReadBE64(chunk + 40));
- Round(c, d, e, f, g, h, a, b, 0x923f82a4af194f9bull, w6 = ReadBE64(chunk + 48));
- Round(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118ull, w7 = ReadBE64(chunk + 56));
- Round(a, b, c, d, e, f, g, h, 0xd807aa98a3030242ull, w8 = ReadBE64(chunk + 64));
- Round(h, a, b, c, d, e, f, g, 0x12835b0145706fbeull, w9 = ReadBE64(chunk + 72));
- Round(g, h, a, b, c, d, e, f, 0x243185be4ee4b28cull, w10 = ReadBE64(chunk + 80));
- Round(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2ull, w11 = ReadBE64(chunk + 88));
- Round(e, f, g, h, a, b, c, d, 0x72be5d74f27b896full, w12 = ReadBE64(chunk + 96));
- Round(d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1ull, w13 = ReadBE64(chunk + 104));
- Round(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235ull, w14 = ReadBE64(chunk + 112));
- Round(b, c, d, e, f, g, h, a, 0xc19bf174cf692694ull, w15 = ReadBE64(chunk + 120));
-
- Round(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0(w1));
- Round(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0(w2));
- Round(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1(w0) + w11 + sigma0(w3));
- Round(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65ull, w3 += sigma1(w1) + w12 + sigma0(w4));
- Round(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275ull, w4 += sigma1(w2) + w13 + sigma0(w5));
- Round(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483ull, w5 += sigma1(w3) + w14 + sigma0(w6));
- Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1(w4) + w15 + sigma0(w7));
- Round(b, c, d, e, f, g, h, a, 0x76f988da831153b5ull, w7 += sigma1(w5) + w0 + sigma0(w8));
- Round(a, b, c, d, e, f, g, h, 0x983e5152ee66dfabull, w8 += sigma1(w6) + w1 + sigma0(w9));
- Round(h, a, b, c, d, e, f, g, 0xa831c66d2db43210ull, w9 += sigma1(w7) + w2 + sigma0(w10));
- Round(g, h, a, b, c, d, e, f, 0xb00327c898fb213full, w10 += sigma1(w8) + w3 + sigma0(w11));
- Round(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4ull, w11 += sigma1(w9) + w4 + sigma0(w12));
- Round(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13));
- Round(d, e, f, g, h, a, b, c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14));
- Round(c, d, e, f, g, h, a, b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15));
- Round(b, c, d, e, f, g, h, a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0(w0));
-
- Round(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0(w1));
- Round(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0(w2));
- Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aedull, w2 += sigma1(w0) + w11 + sigma0(w3));
- Round(f, g, h, a, b, c, d, e, 0x53380d139d95b3dfull, w3 += sigma1(w1) + w12 + sigma0(w4));
- Round(e, f, g, h, a, b, c, d, 0x650a73548baf63deull, w4 += sigma1(w2) + w13 + sigma0(w5));
- Round(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8ull, w5 += sigma1(w3) + w14 + sigma0(w6));
- Round(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6ull, w6 += sigma1(w4) + w15 + sigma0(w7));
- Round(b, c, d, e, f, g, h, a, 0x92722c851482353bull, w7 += sigma1(w5) + w0 + sigma0(w8));
- Round(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364ull, w8 += sigma1(w6) + w1 + sigma0(w9));
- Round(h, a, b, c, d, e, f, g, 0xa81a664bbc423001ull, w9 += sigma1(w7) + w2 + sigma0(w10));
- Round(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791ull, w10 += sigma1(w8) + w3 + sigma0(w11));
- Round(f, g, h, a, b, c, d, e, 0xc76c51a30654be30ull, w11 += sigma1(w9) + w4 + sigma0(w12));
- Round(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13));
- Round(d, e, f, g, h, a, b, c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14));
- Round(c, d, e, f, g, h, a, b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15));
- Round(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0(w0));
-
- Round(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0(w1));
- Round(h, a, b, c, d, e, f, g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0(w2));
- Round(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99ull, w2 += sigma1(w0) + w11 + sigma0(w3));
- Round(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8ull, w3 += sigma1(w1) + w12 + sigma0(w4));
- Round(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63ull, w4 += sigma1(w2) + w13 + sigma0(w5));
- Round(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acbull, w5 += sigma1(w3) + w14 + sigma0(w6));
- Round(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373ull, w6 += sigma1(w4) + w15 + sigma0(w7));
- Round(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1(w5) + w0 + sigma0(w8));
- Round(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fcull, w8 += sigma1(w6) + w1 + sigma0(w9));
- Round(h, a, b, c, d, e, f, g, 0x78a5636f43172f60ull, w9 += sigma1(w7) + w2 + sigma0(w10));
- Round(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72ull, w10 += sigma1(w8) + w3 + sigma0(w11));
- Round(f, g, h, a, b, c, d, e, 0x8cc702081a6439ecull, w11 += sigma1(w9) + w4 + sigma0(w12));
- Round(e, f, g, h, a, b, c, d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13));
- Round(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14));
- Round(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15));
- Round(b, c, d, e, f, g, h, a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0(w0));
-
- Round(a, b, c, d, e, f, g, h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0(w1));
- Round(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0(w2));
- Round(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1eull, w2 += sigma1(w0) + w11 + sigma0(w3));
- Round(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178ull, w3 += sigma1(w1) + w12 + sigma0(w4));
- Round(e, f, g, h, a, b, c, d, 0x06f067aa72176fbaull, w4 += sigma1(w2) + w13 + sigma0(w5));
- Round(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6ull, w5 += sigma1(w3) + w14 + sigma0(w6));
- Round(c, d, e, f, g, h, a, b, 0x113f9804bef90daeull, w6 += sigma1(w4) + w15 + sigma0(w7));
- Round(b, c, d, e, f, g, h, a, 0x1b710b35131c471bull, w7 += sigma1(w5) + w0 + sigma0(w8));
- Round(a, b, c, d, e, f, g, h, 0x28db77f523047d84ull, w8 += sigma1(w6) + w1 + sigma0(w9));
- Round(h, a, b, c, d, e, f, g, 0x32caab7b40c72493ull, w9 += sigma1(w7) + w2 + sigma0(w10));
- Round(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebcull, w10 += sigma1(w8) + w3 + sigma0(w11));
- Round(f, g, h, a, b, c, d, e, 0x431d67c49c100d4cull, w11 += sigma1(w9) + w4 + sigma0(w12));
- Round(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13));
- Round(d, e, f, g, h, a, b, c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14));
- Round(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faecull, w14 += sigma1(w12) + w7 + sigma0(w15));
- Round(b, c, d, e, f, g, h, a, 0x6c44198c4a475817ull, w15 += sigma1(w13) + w8 + sigma0(w0));
-
- s[0] += a;
- s[1] += b;
- s[2] += c;
- s[3] += d;
- s[4] += e;
- s[5] += f;
- s[6] += g;
- s[7] += h;
-}
-
-} // namespace sha512
-
-} // namespace
-
-
-////// SHA-256
-
-CSHA256::CSHA256() : bytes(0)
-{
- sha256::Initialize(s);
-}
-
-CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
-{
- const unsigned char* end = data + len;
- size_t bufsize = bytes % 64;
- if (bufsize && bufsize + len >= 64) {
- // Fill the buffer, and process it.
- memcpy(buf + bufsize, data, 64 - bufsize);
- bytes += 64 - bufsize;
- data += 64 - bufsize;
- sha256::Transform(s, buf);
- bufsize = 0;
- }
- while (end >= data + 64) {
- // Process full chunks directly from the source.
- sha256::Transform(s, data);
- bytes += 64;
- data += 64;
- }
- if (end > data) {
- // Fill the buffer with what remains.
- memcpy(buf + bufsize, data, end - data);
- bytes += end - data;
- }
- return *this;
-}
-
-void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
-{
- static const unsigned char pad[64] = {0x80};
- unsigned char sizedesc[8];
- WriteBE64(sizedesc, bytes << 3);
- Write(pad, 1 + ((119 - (bytes % 64)) % 64));
- Write(sizedesc, 8);
- WriteBE32(hash, s[0]);
- WriteBE32(hash + 4, s[1]);
- WriteBE32(hash + 8, s[2]);
- WriteBE32(hash + 12, s[3]);
- WriteBE32(hash + 16, s[4]);
- WriteBE32(hash + 20, s[5]);
- WriteBE32(hash + 24, s[6]);
- WriteBE32(hash + 28, s[7]);
-}
-
-CSHA256& CSHA256::Reset()
-{
- bytes = 0;
- sha256::Initialize(s);
- return *this;
-}
-
-////// SHA-512
-
-CSHA512::CSHA512() : bytes(0)
-{
- sha512::Initialize(s);
-}
-
-CSHA512& CSHA512::Write(const unsigned char* data, size_t len)
-{
- const unsigned char* end = data + len;
- size_t bufsize = bytes % 128;
- if (bufsize && bufsize + len >= 128) {
- // Fill the buffer, and process it.
- memcpy(buf + bufsize, data, 128 - bufsize);
- bytes += 128 - bufsize;
- data += 128 - bufsize;
- sha512::Transform(s, buf);
- bufsize = 0;
- }
- while (end >= data + 128) {
- // Process full chunks directly from the source.
- sha512::Transform(s, data);
- data += 128;
- bytes += 128;
- }
- if (end > data) {
- // Fill the buffer with what remains.
- memcpy(buf + bufsize, data, end - data);
- bytes += end - data;
- }
- return *this;
-}
-
-void CSHA512::Finalize(unsigned char hash[OUTPUT_SIZE])
-{
- static const unsigned char pad[128] = {0x80};
- unsigned char sizedesc[16] = {0x00};
- WriteBE64(sizedesc + 8, bytes << 3);
- Write(pad, 1 + ((239 - (bytes % 128)) % 128));
- Write(sizedesc, 16);
- WriteBE64(hash, s[0]);
- WriteBE64(hash + 8, s[1]);
- WriteBE64(hash + 16, s[2]);
- WriteBE64(hash + 24, s[3]);
- WriteBE64(hash + 32, s[4]);
- WriteBE64(hash + 40, s[5]);
- WriteBE64(hash + 48, s[6]);
- WriteBE64(hash + 56, s[7]);
-}
-
-CSHA512& CSHA512::Reset()
-{
- bytes = 0;
- sha512::Initialize(s);
- return *this;
-}
-
-////// HMAC-SHA-512
-
-CHMAC_SHA512::CHMAC_SHA512(const unsigned char* key, size_t keylen)
-{
- unsigned char rkey[128];
- if (keylen <= 128) {
- memcpy(rkey, key, keylen);
- memset(rkey + keylen, 0, 128 - keylen);
- } else {
- CSHA512().Write(key, keylen).Finalize(rkey);
- memset(rkey + 64, 0, 64);
- }
-
- for (int n = 0; n < 128; n++)
- rkey[n] ^= 0x5c;
- outer.Write(rkey, 128);
-
- for (int n = 0; n < 128; n++)
- rkey[n] ^= 0x5c ^ 0x36;
- inner.Write(rkey, 128);
-}
-
-void CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE])
-{
- unsigned char temp[64];
- inner.Finalize(temp);
- outer.Write(temp, 64).Finalize(hash);
-}
+++ /dev/null
-// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#ifndef BITCOIN_CRYPTO_SHA2_H
-#define BITCOIN_CRYPTO_SHA2_H
-
-#include <stdint.h>
-#include <stdlib.h>
-
-/** A hasher class for SHA-256. */
-class CSHA256
-{
-private:
- uint32_t s[8];
- unsigned char buf[64];
- size_t bytes;
-
-public:
- static const size_t OUTPUT_SIZE = 32;
-
- CSHA256();
- CSHA256& Write(const unsigned char* data, size_t len);
- void Finalize(unsigned char hash[OUTPUT_SIZE]);
- CSHA256& Reset();
-};
-
-/** A hasher class for SHA-512. */
-class CSHA512
-{
-private:
- uint64_t s[8];
- unsigned char buf[128];
- size_t bytes;
-
-public:
- static const size_t OUTPUT_SIZE = 64;
-
- CSHA512();
- CSHA512& Write(const unsigned char* data, size_t len);
- void Finalize(unsigned char hash[OUTPUT_SIZE]);
- CSHA512& Reset();
-};
-
-/** A hasher class for HMAC-SHA-512. */
-class CHMAC_SHA512
-{
-private:
- CSHA512 outer;
- CSHA512 inner;
-
-public:
- static const size_t OUTPUT_SIZE = 64;
-
- CHMAC_SHA512(const unsigned char* key, size_t keylen);
- CHMAC_SHA512& Write(const unsigned char* data, size_t len)
- {
- inner.Write(data, len);
- return *this;
- }
- void Finalize(unsigned char hash[OUTPUT_SIZE]);
-};
-
-#endif // BITCOIN_CRYPTO_SHA2_H
--- /dev/null
+// 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.
+
+#include "crypto/sha256.h"
+
+#include "crypto/common.h"
+
+#include <string.h>
+
+// Internal implementation code.
+namespace
+{
+/// Internal SHA-256 implementation.
+namespace sha256
+{
+uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }
+uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }
+uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
+uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
+uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
+uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
+
+/** One round of SHA-256. */
+void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, uint32_t f, uint32_t g, uint32_t& h, uint32_t k, uint32_t w)
+{
+ uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
+ uint32_t t2 = Sigma0(a) + Maj(a, b, c);
+ d += t1;
+ h = t1 + t2;
+}
+
+/** Initialize SHA-256 state. */
+void inline Initialize(uint32_t* s)
+{
+ s[0] = 0x6a09e667ul;
+ s[1] = 0xbb67ae85ul;
+ s[2] = 0x3c6ef372ul;
+ s[3] = 0xa54ff53aul;
+ s[4] = 0x510e527ful;
+ s[5] = 0x9b05688cul;
+ s[6] = 0x1f83d9abul;
+ s[7] = 0x5be0cd19ul;
+}
+
+/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
+void Transform(uint32_t* s, const unsigned char* chunk)
+{
+ uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
+ uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
+
+ Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0));
+ Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4));
+ Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8));
+ Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12));
+ Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16));
+ Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20));
+ Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24));
+ Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28));
+ Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32));
+ Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36));
+ Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40));
+ Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44));
+ Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48));
+ Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52));
+ Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56));
+ Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60));
+
+ Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));
+
+ s[0] += a;
+ s[1] += b;
+ s[2] += c;
+ s[3] += d;
+ s[4] += e;
+ s[5] += f;
+ s[6] += g;
+ s[7] += h;
+}
+
+} // namespace sha256
+} // namespace
+
+
+////// SHA-256
+
+CSHA256::CSHA256() : bytes(0)
+{
+ sha256::Initialize(s);
+}
+
+CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
+{
+ const unsigned char* end = data + len;
+ size_t bufsize = bytes % 64;
+ if (bufsize && bufsize + len >= 64) {
+ // Fill the buffer, and process it.
+ memcpy(buf + bufsize, data, 64 - bufsize);
+ bytes += 64 - bufsize;
+ data += 64 - bufsize;
+ sha256::Transform(s, buf);
+ bufsize = 0;
+ }
+ while (end >= data + 64) {
+ // Process full chunks directly from the source.
+ sha256::Transform(s, data);
+ bytes += 64;
+ data += 64;
+ }
+ if (end > data) {
+ // Fill the buffer with what remains.
+ memcpy(buf + bufsize, data, end - data);
+ bytes += end - data;
+ }
+ return *this;
+}
+
+void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
+{
+ static const unsigned char pad[64] = {0x80};
+ unsigned char sizedesc[8];
+ WriteBE64(sizedesc, bytes << 3);
+ Write(pad, 1 + ((119 - (bytes % 64)) % 64));
+ Write(sizedesc, 8);
+ WriteBE32(hash, s[0]);
+ WriteBE32(hash + 4, s[1]);
+ WriteBE32(hash + 8, s[2]);
+ WriteBE32(hash + 12, s[3]);
+ WriteBE32(hash + 16, s[4]);
+ WriteBE32(hash + 20, s[5]);
+ WriteBE32(hash + 24, s[6]);
+ WriteBE32(hash + 28, s[7]);
+}
+
+CSHA256& CSHA256::Reset()
+{
+ bytes = 0;
+ sha256::Initialize(s);
+ return *this;
+}
--- /dev/null
+// 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.
+
+#ifndef BITCOIN_CRYPTO_SHA256_H
+#define BITCOIN_CRYPTO_SHA256_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/** A hasher class for SHA-256. */
+class CSHA256
+{
+private:
+ uint32_t s[8];
+ unsigned char buf[64];
+ size_t bytes;
+
+public:
+ static const size_t OUTPUT_SIZE = 32;
+
+ CSHA256();
+ CSHA256& Write(const unsigned char* data, size_t len);
+ void Finalize(unsigned char hash[OUTPUT_SIZE]);
+ CSHA256& Reset();
+};
+
+#endif // BITCOIN_CRYPTO_SHA256_H
--- /dev/null
+// 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.
+
+#include "crypto/sha512.h"
+
+#include "crypto/common.h"
+
+#include <string.h>
+
+// Internal implementation code.
+namespace
+{
+/// Internal SHA-512 implementation.
+namespace sha512
+{
+uint64_t inline Ch(uint64_t x, uint64_t y, uint64_t z) { return z ^ (x & (y ^ z)); }
+uint64_t inline Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) | (z & (x | y)); }
+uint64_t inline Sigma0(uint64_t x) { return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25); }
+uint64_t inline Sigma1(uint64_t x) { return (x >> 14 | x << 50) ^ (x >> 18 | x << 46) ^ (x >> 41 | x << 23); }
+uint64_t inline sigma0(uint64_t x) { return (x >> 1 | x << 63) ^ (x >> 8 | x << 56) ^ (x >> 7); }
+uint64_t inline sigma1(uint64_t x) { return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6); }
+
+/** One round of SHA-512. */
+void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t& d, uint64_t e, uint64_t f, uint64_t g, uint64_t& h, uint64_t k, uint64_t w)
+{
+ uint64_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
+ uint64_t t2 = Sigma0(a) + Maj(a, b, c);
+ d += t1;
+ h = t1 + t2;
+}
+
+/** Initialize SHA-256 state. */
+void inline Initialize(uint64_t* s)
+{
+ s[0] = 0x6a09e667f3bcc908ull;
+ s[1] = 0xbb67ae8584caa73bull;
+ s[2] = 0x3c6ef372fe94f82bull;
+ s[3] = 0xa54ff53a5f1d36f1ull;
+ s[4] = 0x510e527fade682d1ull;
+ s[5] = 0x9b05688c2b3e6c1full;
+ s[6] = 0x1f83d9abfb41bd6bull;
+ s[7] = 0x5be0cd19137e2179ull;
+}
+
+/** Perform one SHA-512 transformation, processing a 128-byte chunk. */
+void Transform(uint64_t* s, const unsigned char* chunk)
+{
+ uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
+ uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
+
+ Round(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22ull, w0 = ReadBE64(chunk + 0));
+ Round(h, a, b, c, d, e, f, g, 0x7137449123ef65cdull, w1 = ReadBE64(chunk + 8));
+ Round(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2full, w2 = ReadBE64(chunk + 16));
+ Round(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbcull, w3 = ReadBE64(chunk + 24));
+ Round(e, f, g, h, a, b, c, d, 0x3956c25bf348b538ull, w4 = ReadBE64(chunk + 32));
+ Round(d, e, f, g, h, a, b, c, 0x59f111f1b605d019ull, w5 = ReadBE64(chunk + 40));
+ Round(c, d, e, f, g, h, a, b, 0x923f82a4af194f9bull, w6 = ReadBE64(chunk + 48));
+ Round(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118ull, w7 = ReadBE64(chunk + 56));
+ Round(a, b, c, d, e, f, g, h, 0xd807aa98a3030242ull, w8 = ReadBE64(chunk + 64));
+ Round(h, a, b, c, d, e, f, g, 0x12835b0145706fbeull, w9 = ReadBE64(chunk + 72));
+ Round(g, h, a, b, c, d, e, f, 0x243185be4ee4b28cull, w10 = ReadBE64(chunk + 80));
+ Round(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2ull, w11 = ReadBE64(chunk + 88));
+ Round(e, f, g, h, a, b, c, d, 0x72be5d74f27b896full, w12 = ReadBE64(chunk + 96));
+ Round(d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1ull, w13 = ReadBE64(chunk + 104));
+ Round(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235ull, w14 = ReadBE64(chunk + 112));
+ Round(b, c, d, e, f, g, h, a, 0xc19bf174cf692694ull, w15 = ReadBE64(chunk + 120));
+
+ Round(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65ull, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275ull, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483ull, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x76f988da831153b5ull, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x983e5152ee66dfabull, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa831c66d2db43210ull, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xb00327c898fb213full, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4ull, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aedull, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x53380d139d95b3dfull, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x650a73548baf63deull, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8ull, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6ull, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x92722c851482353bull, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364ull, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa81a664bbc423001ull, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791ull, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xc76c51a30654be30ull, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99ull, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8ull, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63ull, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acbull, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373ull, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fcull, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0x78a5636f43172f60ull, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72ull, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0x8cc702081a6439ecull, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1eull, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178ull, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x06f067aa72176fbaull, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6ull, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x113f9804bef90daeull, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x1b710b35131c471bull, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x28db77f523047d84ull, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0x32caab7b40c72493ull, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebcull, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0x431d67c49c100d4cull, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faecull, w14 + sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x6c44198c4a475817ull, w15 + sigma1(w13) + w8 + sigma0(w0));
+
+ s[0] += a;
+ s[1] += b;
+ s[2] += c;
+ s[3] += d;
+ s[4] += e;
+ s[5] += f;
+ s[6] += g;
+ s[7] += h;
+}
+
+} // namespace sha512
+
+} // namespace
+
+
+////// SHA-512
+
+CSHA512::CSHA512() : bytes(0)
+{
+ sha512::Initialize(s);
+}
+
+CSHA512& CSHA512::Write(const unsigned char* data, size_t len)
+{
+ const unsigned char* end = data + len;
+ size_t bufsize = bytes % 128;
+ if (bufsize && bufsize + len >= 128) {
+ // Fill the buffer, and process it.
+ memcpy(buf + bufsize, data, 128 - bufsize);
+ bytes += 128 - bufsize;
+ data += 128 - bufsize;
+ sha512::Transform(s, buf);
+ bufsize = 0;
+ }
+ while (end >= data + 128) {
+ // Process full chunks directly from the source.
+ sha512::Transform(s, data);
+ data += 128;
+ bytes += 128;
+ }
+ if (end > data) {
+ // Fill the buffer with what remains.
+ memcpy(buf + bufsize, data, end - data);
+ bytes += end - data;
+ }
+ return *this;
+}
+
+void CSHA512::Finalize(unsigned char hash[OUTPUT_SIZE])
+{
+ static const unsigned char pad[128] = {0x80};
+ unsigned char sizedesc[16] = {0x00};
+ WriteBE64(sizedesc + 8, bytes << 3);
+ Write(pad, 1 + ((239 - (bytes % 128)) % 128));
+ Write(sizedesc, 16);
+ WriteBE64(hash, s[0]);
+ WriteBE64(hash + 8, s[1]);
+ WriteBE64(hash + 16, s[2]);
+ WriteBE64(hash + 24, s[3]);
+ WriteBE64(hash + 32, s[4]);
+ WriteBE64(hash + 40, s[5]);
+ WriteBE64(hash + 48, s[6]);
+ WriteBE64(hash + 56, s[7]);
+}
+
+CSHA512& CSHA512::Reset()
+{
+ bytes = 0;
+ sha512::Initialize(s);
+ return *this;
+}
--- /dev/null
+// 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.
+
+#ifndef BITCOIN_CRYPTO_SHA512_H
+#define BITCOIN_CRYPTO_SHA512_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/** A hasher class for SHA-512. */
+class CSHA512
+{
+private:
+ uint64_t s[8];
+ unsigned char buf[128];
+ size_t bytes;
+
+public:
+ static const size_t OUTPUT_SIZE = 64;
+
+ CSHA512();
+ CSHA512& Write(const unsigned char* data, size_t len);
+ void Finalize(unsigned char hash[OUTPUT_SIZE]);
+ CSHA512& Reset();
+};
+
+#endif // BITCOIN_CRYPTO_SHA512_H
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "db.h"
#include <boost/thread.hpp>
#include <boost/version.hpp>
-#include <openssl/rand.h>
-
using namespace std;
-using namespace boost;
unsigned int nWalletDBUpdated;
return;
fDbEnvInit = false;
- int ret = dbenv.close(0);
+ int ret = dbenv->close(0);
if (ret != 0)
- LogPrintf("CDBEnv::EnvShutdown : Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret));
+ LogPrintf("CDBEnv::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret));
if (!fMockDb)
DbEnv(0).remove(path.string().c_str(), 0);
}
-CDBEnv::CDBEnv() : dbenv(DB_CXX_NO_EXCEPTIONS)
+void CDBEnv::Reset()
{
+ delete dbenv;
+ dbenv = new DbEnv(DB_CXX_NO_EXCEPTIONS);
fDbEnvInit = false;
fMockDb = false;
}
+CDBEnv::CDBEnv() : dbenv(NULL)
+{
+ Reset();
+}
+
CDBEnv::~CDBEnv()
{
EnvShutdown();
+ delete dbenv;
+ dbenv = NULL;
}
void CDBEnv::Close()
boost::this_thread::interruption_point();
path = pathIn;
- filesystem::path pathLogDir = path / "database";
+ boost::filesystem::path pathLogDir = path / "database";
TryCreateDirectory(pathLogDir);
- filesystem::path pathErrorFile = path / "db.log";
- LogPrintf("CDBEnv::Open : LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string());
+ boost::filesystem::path pathErrorFile = path / "db.log";
+ LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string());
unsigned int nEnvFlags = 0;
if (GetBoolArg("-privdb", true))
nEnvFlags |= DB_PRIVATE;
- dbenv.set_lg_dir(pathLogDir.string().c_str());
- dbenv.set_cachesize(0, 0x100000, 1); // 1 MiB should be enough for just the wallet
- dbenv.set_lg_bsize(0x10000);
- dbenv.set_lg_max(1048576);
- dbenv.set_lk_max_locks(40000);
- dbenv.set_lk_max_objects(40000);
- dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug
- dbenv.set_flags(DB_AUTO_COMMIT, 1);
- dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1);
- dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1);
- int ret = dbenv.open(path.string().c_str(),
+ dbenv->set_lg_dir(pathLogDir.string().c_str());
+ dbenv->set_cachesize(0, 0x100000, 1); // 1 MiB should be enough for just the wallet
+ dbenv->set_lg_bsize(0x10000);
+ dbenv->set_lg_max(1048576);
+ dbenv->set_lk_max_locks(40000);
+ dbenv->set_lk_max_objects(40000);
+ dbenv->set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug
+ dbenv->set_flags(DB_AUTO_COMMIT, 1);
+ dbenv->set_flags(DB_TXN_WRITE_NOSYNC, 1);
+ dbenv->log_set_config(DB_LOG_AUTO_REMOVE, 1);
+ int ret = dbenv->open(path.string().c_str(),
DB_CREATE |
DB_INIT_LOCK |
DB_INIT_LOG |
nEnvFlags,
S_IRUSR | S_IWUSR);
if (ret != 0)
- return error("CDBEnv::Open : Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret));
+ return error("CDBEnv::Open: Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret));
fDbEnvInit = true;
fMockDb = false;
void CDBEnv::MakeMock()
{
if (fDbEnvInit)
- throw runtime_error("CDBEnv::MakeMock : Already initialized");
+ throw runtime_error("CDBEnv::MakeMock: Already initialized");
boost::this_thread::interruption_point();
LogPrint("db", "CDBEnv::MakeMock\n");
- dbenv.set_cachesize(1, 0, 1);
- dbenv.set_lg_bsize(10485760 * 4);
- dbenv.set_lg_max(10485760);
- dbenv.set_lk_max_locks(10000);
- dbenv.set_lk_max_objects(10000);
- dbenv.set_flags(DB_AUTO_COMMIT, 1);
- dbenv.log_set_config(DB_LOG_IN_MEMORY, 1);
- int ret = dbenv.open(NULL,
+ dbenv->set_cachesize(1, 0, 1);
+ dbenv->set_lg_bsize(10485760 * 4);
+ dbenv->set_lg_max(10485760);
+ dbenv->set_lk_max_locks(10000);
+ dbenv->set_lk_max_objects(10000);
+ dbenv->set_flags(DB_AUTO_COMMIT, 1);
+ dbenv->log_set_config(DB_LOG_IN_MEMORY, 1);
+ int ret = dbenv->open(NULL,
DB_CREATE |
DB_INIT_LOCK |
DB_INIT_LOG |
DB_PRIVATE,
S_IRUSR | S_IWUSR);
if (ret > 0)
- throw runtime_error(strprintf("CDBEnv::MakeMock : Error %d opening database environment.", ret));
+ throw runtime_error(strprintf("CDBEnv::MakeMock: Error %d opening database environment.", ret));
fDbEnvInit = true;
fMockDb = true;
LOCK(cs_db);
assert(mapFileUseCount.count(strFile) == 0);
- Db db(&dbenv, 0);
+ Db db(dbenv, 0);
int result = db.verify(strFile.c_str(), NULL, NULL, 0);
if (result == 0)
return VERIFY_OK;
stringstream strDump;
- Db db(&dbenv, 0);
+ Db db(dbenv, 0);
int result = db.verify(strFile.c_str(), NULL, &strDump, flags);
if (result == DB_VERIFY_BAD) {
- LogPrintf("CDBEnv::Salvage : Database salvage found errors, all data may not be recoverable.\n");
+ LogPrintf("CDBEnv::Salvage: Database salvage found errors, all data may not be recoverable.\n");
if (!fAggressive) {
- LogPrintf("CDBEnv::Salvage : Rerun with aggressive mode to ignore errors and continue.\n");
+ LogPrintf("CDBEnv::Salvage: Rerun with aggressive mode to ignore errors and continue.\n");
return false;
}
}
if (result != 0 && result != DB_VERIFY_BAD) {
- LogPrintf("CDBEnv::Salvage : Database salvage failed with result %d.\n", result);
+ LogPrintf("CDBEnv::Salvage: Database salvage failed with result %d.\n", result);
return false;
}
void CDBEnv::CheckpointLSN(const std::string& strFile)
{
- dbenv.txn_checkpoint(0, 0, 0);
+ dbenv->txn_checkpoint(0, 0, 0);
if (fMockDb)
return;
- dbenv.lsn_reset(strFile.c_str(), 0);
+ dbenv->lsn_reset(strFile.c_str(), 0);
}
-CDB::CDB(const std::string& strFilename, const char* pszMode) : pdb(NULL), activeTxn(NULL)
+CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnCloseIn) : pdb(NULL), activeTxn(NULL)
{
int ret;
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
+ fFlushOnClose = fFlushOnCloseIn;
if (strFilename.empty())
return;
{
LOCK(bitdb.cs_db);
if (!bitdb.Open(GetDataDir()))
- throw runtime_error("CDB : Failed to open database environment.");
+ throw runtime_error("CDB: Failed to open database environment.");
strFile = strFilename;
++bitdb.mapFileUseCount[strFile];
pdb = bitdb.mapDb[strFile];
if (pdb == NULL) {
- pdb = new Db(&bitdb.dbenv, 0);
+ pdb = new Db(bitdb.dbenv, 0);
bool fMockDb = bitdb.IsMock();
if (fMockDb) {
DbMpoolFile* mpf = pdb->get_mpf();
ret = mpf->set_flags(DB_MPOOL_NOFILE, 1);
if (ret != 0)
- throw runtime_error(strprintf("CDB : Failed to configure for no temp file backing for database %s", strFile));
+ throw runtime_error(strprintf("CDB: Failed to configure for no temp file backing for database %s", strFile));
}
ret = pdb->open(NULL, // Txn pointer
pdb = NULL;
--bitdb.mapFileUseCount[strFile];
strFile = "";
- throw runtime_error(strprintf("CDB : Error %d, can't open database %s", ret, strFile));
+ throw runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFile));
}
if (fCreate && !Exists(string("version"))) {
if (fReadOnly)
nMinutes = 1;
- bitdb.dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100) * 1024 : 0, nMinutes, 0);
+ bitdb.dbenv->txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100) * 1024 : 0, nMinutes, 0);
}
void CDB::Close()
activeTxn = NULL;
pdb = NULL;
- Flush();
+ if (fFlushOnClose)
+ Flush();
{
LOCK(bitdb.cs_db);
this->CloseDb(strFile);
LOCK(cs_db);
- int rc = dbenv.dbremove(NULL, strFile.c_str(), NULL, DB_AUTO_COMMIT);
+ int rc = dbenv->dbremove(NULL, strFile.c_str(), NULL, DB_AUTO_COMMIT);
return (rc == 0);
}
bitdb.mapFileUseCount.erase(strFile);
bool fSuccess = true;
- LogPrintf("CDB::Rewrite : Rewriting %s...\n", strFile);
+ LogPrintf("CDB::Rewrite: Rewriting %s...\n", strFile);
string strFileRes = strFile + ".rewrite";
{ // surround usage of db with extra {}
CDB db(strFile.c_str(), "r");
- Db* pdbCopy = new Db(&bitdb.dbenv, 0);
+ Db* pdbCopy = new Db(bitdb.dbenv, 0);
int ret = pdbCopy->open(NULL, // Txn pointer
strFileRes.c_str(), // Filename
DB_CREATE, // Flags
0);
if (ret > 0) {
- LogPrintf("CDB::Rewrite : Can't create database file %s\n", strFileRes);
+ LogPrintf("CDB::Rewrite: Can't create database file %s\n", strFileRes);
fSuccess = false;
}
}
}
if (fSuccess) {
- Db dbA(&bitdb.dbenv, 0);
+ Db dbA(bitdb.dbenv, 0);
if (dbA.remove(strFile.c_str(), NULL, 0))
fSuccess = false;
- Db dbB(&bitdb.dbenv, 0);
+ Db dbB(bitdb.dbenv, 0);
if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0))
fSuccess = false;
}
if (!fSuccess)
- LogPrintf("CDB::Rewrite : Failed to rewrite database file %s\n", strFileRes);
+ LogPrintf("CDB::Rewrite: Failed to rewrite database file %s\n", strFileRes);
return fSuccess;
}
}
{
int64_t nStart = GetTimeMillis();
// Flush log data to the actual data file on all files that are not in use
- LogPrint("db", "CDBEnv::Flush : Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started");
+ LogPrint("db", "CDBEnv::Flush: Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started");
if (!fDbEnvInit)
return;
{
while (mi != mapFileUseCount.end()) {
string strFile = (*mi).first;
int nRefCount = (*mi).second;
- LogPrint("db", "CDBEnv::Flush : Flushing %s (refcount = %d)...\n", strFile, nRefCount);
+ LogPrint("db", "CDBEnv::Flush: Flushing %s (refcount = %d)...\n", strFile, nRefCount);
if (nRefCount == 0) {
// Move log data to the dat file
CloseDb(strFile);
- LogPrint("db", "CDBEnv::Flush : %s checkpoint\n", strFile);
- dbenv.txn_checkpoint(0, 0, 0);
- LogPrint("db", "CDBEnv::Flush : %s detach\n", strFile);
+ LogPrint("db", "CDBEnv::Flush: %s checkpoint\n", strFile);
+ dbenv->txn_checkpoint(0, 0, 0);
+ LogPrint("db", "CDBEnv::Flush: %s detach\n", strFile);
if (!fMockDb)
- dbenv.lsn_reset(strFile.c_str(), 0);
- LogPrint("db", "CDBEnv::Flush : %s closed\n", strFile);
+ dbenv->lsn_reset(strFile.c_str(), 0);
+ LogPrint("db", "CDBEnv::Flush: %s closed\n", strFile);
mapFileUseCount.erase(mi++);
} else
mi++;
}
- LogPrint("db", "CDBEnv::Flush : Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart);
+ LogPrint("db", "CDBEnv::Flush: Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart);
if (fShutdown) {
char** listp;
if (mapFileUseCount.empty()) {
- dbenv.log_archive(&listp, DB_ARCH_REMOVE);
+ dbenv->log_archive(&listp, DB_ARCH_REMOVE);
Close();
if (!fMockDb)
boost::filesystem::remove_all(path / "database");
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
class CDiskBlockIndex;
class COutPoint;
-struct CBlockLocator;
-
extern unsigned int nWalletDBUpdated;
void ThreadFlushWalletDB(const std::string& strWalletFile);
public:
mutable CCriticalSection cs_db;
- DbEnv dbenv;
+ DbEnv *dbenv;
std::map<std::string, int> mapFileUseCount;
std::map<std::string, Db*> mapDb;
CDBEnv();
~CDBEnv();
+ void Reset();
+
void MakeMock();
bool IsMock() { return fMockDb; }
DbTxn* TxnBegin(int flags = DB_TXN_WRITE_NOSYNC)
{
DbTxn* ptxn = NULL;
- int ret = dbenv.txn_begin(NULL, &ptxn, flags);
+ int ret = dbenv->txn_begin(NULL, &ptxn, flags);
if (!ptxn || ret != 0)
return NULL;
return ptxn;
std::string strFile;
DbTxn* activeTxn;
bool fReadOnly;
+ bool fFlushOnClose;
- explicit CDB(const std::string& strFilename, const char* pszMode = "r+");
+ explicit CDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnCloseIn=true);
~CDB() { Close(); }
public:
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
}
bool CECKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
- // -1 = error, 0 = bad sig, 1 = good
- if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
+ if (vchSig.empty())
return false;
- return true;
+
+ // New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first.
+ unsigned char *norm_der = NULL;
+ ECDSA_SIG *norm_sig = ECDSA_SIG_new();
+ const unsigned char* sigptr = &vchSig[0];
+ assert(norm_sig);
+ if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL)
+ {
+ /* As of OpenSSL 1.0.0p d2i_ECDSA_SIG frees and nulls the pointer on
+ * error. But OpenSSL's own use of this function redundantly frees the
+ * result. As ECDSA_SIG_free(NULL) is a no-op, and in the absence of a
+ * clear contract for the function behaving the same way is more
+ * conservative.
+ */
+ ECDSA_SIG_free(norm_sig);
+ return false;
+ }
+ int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
+ ECDSA_SIG_free(norm_sig);
+ if (derlen <= 0)
+ return false;
+
+ // -1 = error, 0 = bad sig, 1 = good
+ bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1;
+ OPENSSL_free(norm_der);
+ return ret;
}
bool CECKey::Recover(const uint256 &hash, const unsigned char *p64, int rec)
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-// Copyright (c) 2013-2014 The Bitcoin developers
+// 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.
#include "hash.h"
+#include "crypto/common.h"
+#include "crypto/hmac_sha512.h"
+
inline uint32_t ROTL32(uint32_t x, int8_t r)
{
//----------
// body
- const uint32_t* blocks = (const uint32_t*)(&vDataToHash[0] + nblocks * 4);
+ const uint8_t* blocks = &vDataToHash[0] + nblocks * 4;
for (int i = -nblocks; i; i++) {
- uint32_t k1 = blocks[i];
+ uint32_t k1 = ReadLE32(blocks + i*4);
k1 *= c1;
k1 = ROTL32(k1, 15);
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2013 The Bitcoin developers
+// Copyright (c) 2009-2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#define BITCOIN_HASH_H
#include "crypto/ripemd160.h"
-#include "crypto/sha2.h"
+#include "crypto/sha256.h"
#include "serialize.h"
#include "uint256.h"
#include "version.h"
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include <boost/thread.hpp>
#include <openssl/crypto.h>
-using namespace boost;
using namespace std;
#ifdef ENABLE_WALLET
#define MIN_CORE_FILEDESCRIPTORS 150
#endif
-// Used to pass flags to the Bind() function
+/** Used to pass flags to the Bind() function */
enum BindFlags {
BF_NONE = 0,
BF_EXPLICIT = (1U << 0),
return fRequestShutdown;
}
+class CCoinsViewErrorCatcher : public CCoinsViewBacked
+{
+public:
+ CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {}
+ bool GetCoins(const uint256 &txid, CCoins &coins) const {
+ try {
+ return CCoinsViewBacked::GetCoins(txid, coins);
+ } catch(const std::runtime_error& e) {
+ uiInterface.ThreadSafeMessageBox(_("Error reading from database, shutting down."), "", CClientUIInterface::MSG_ERROR);
+ LogPrintf("Error reading from database: %s\n", e.what());
+ // Starting the shutdown sequence and returning false to the caller would be
+ // interpreted as 'entry not found' (as opposed to unable to read data), and
+ // could lead to invalid interpration. Just exit immediately, as we can't
+ // continue anyway, and all writes should be atomic.
+ abort();
+ }
+ }
+ // Writes do not need similar protection, as failure to write is handled by the caller.
+};
+
static CCoinsViewDB *pcoinsdbview = NULL;
+static CCoinsViewErrorCatcher *pcoinscatcher = NULL;
void Shutdown()
{
{
LOCK(cs_main);
-#ifdef ENABLE_WALLET
- if (pwalletMain)
- pwalletMain->SetBestChain(chainActive.GetLocator());
-#endif
- if (pblocktree)
- pblocktree->Flush();
- if (pcoinsTip)
- pcoinsTip->Flush();
+ if (pcoinsTip != NULL) {
+ FlushStateToDisk();
+ }
delete pcoinsTip;
pcoinsTip = NULL;
+ delete pcoinscatcher;
+ pcoinscatcher = NULL;
delete pcoinsdbview;
pcoinsdbview = NULL;
delete pblocktree;
LogPrintf("%s: done\n", __func__);
}
-//
-// Signal handlers are very limited in what they are allowed to do, so:
-//
+/**
+ * Signal handlers are very limited in what they are allowed to do, so:
+ */
void HandleSIGTERM(int)
{
fRequestShutdown = true;
return true;
}
+void OnRPCStopped()
+{
+ cvBlockChange.notify_all();
+ LogPrint("rpc", "RPC stopped.\n");
+}
+
+void OnRPCPreCommand(const CRPCCommand& cmd)
+{
+#ifdef ENABLE_WALLET
+ if (cmd.reqWallet && !pwalletMain)
+ throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
+#endif
+
+ // Observe safe mode
+ string strWarning = GetWarnings("rpc");
+ if (strWarning != "" && !GetBoolArg("-disablesafemode", false) &&
+ !cmd.okSafeMode)
+ throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);
+}
+
std::string HelpMessage(HelpMessageMode mode)
{
+
// When adding new options to the categories, please keep and ensure alphabetical ordering.
- string strUsage = _("Options:") + "\n";
- strUsage += " -? " + _("This help message") + "\n";
- strUsage += " -alertnotify=<cmd> " + _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)") + "\n";
- strUsage += " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n";
- strUsage += " -checkblocks=<n> " + strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288) + "\n";
- strUsage += " -checklevel=<n> " + strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3) + "\n";
- strUsage += " -conf=<file> " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n";
+ string strUsage = HelpMessageGroup(_("Options:"));
+ strUsage += HelpMessageOpt("-?", _("This help message"));
+ strUsage += HelpMessageOpt("-alertnotify=<cmd>", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)"));
+ strUsage += HelpMessageOpt("-blocknotify=<cmd>", _("Execute command when the best block changes (%s in cmd is replaced by block hash)"));
+ strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288));
+ strUsage += HelpMessageOpt("-checklevel=<n>", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3));
+ strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
if (mode == HMM_BITCOIND)
{
#if !defined(WIN32)
- strUsage += " -daemon " + _("Run in the background as a daemon and accept commands") + "\n";
+ strUsage += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands"));
#endif
}
- strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
- strUsage += " -dbcache=<n> " + strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache) + "\n";
- strUsage += " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + " " + _("on startup") + "\n";
- strUsage += " -maxorphanblocks=<n> " + strprintf(_("Keep at most <n> unconnectable blocks in memory (default: %u)"), DEFAULT_MAX_ORPHAN_BLOCKS) + "\n";
- strUsage += " -maxorphantx=<n> " + strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "\n";
- strUsage += " -par=<n> " + strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS) + "\n";
+ strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
+ strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache));
+ strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup"));
+ strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
+ strUsage += HelpMessageOpt("-par=<n>", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"),
+ -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS));
#ifndef WIN32
- strUsage += " -pid=<file> " + strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid") + "\n";
+ strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid"));
#endif
- strUsage += " -reindex " + _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup") + "\n";
+ strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup"));
#if !defined(WIN32)
- strUsage += " -sysperms " + _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)") + "\n";
+ strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)"));
#endif
- strUsage += " -txindex " + strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0) + "\n";
-
- strUsage += "\n" + _("Connection options:") + "\n";
- strUsage += " -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n";
- strUsage += " -banscore=<n> " + strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100) + "\n";
- strUsage += " -bantime=<n> " + strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400) + "\n";
- strUsage += " -bind=<addr> " + _("Bind to given address and always listen on it. Use [host]:port notation for IPv6") + "\n";
- strUsage += " -connect=<ip> " + _("Connect only to the specified node(s)") + "\n";
- strUsage += " -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n";
- strUsage += " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)") + "\n";
- strUsage += " -dnsseed " + _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)") + "\n";
- strUsage += " -externalip=<ip> " + _("Specify your own public address") + "\n";
- strUsage += " -forcednsseed " + strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0) + "\n";
- strUsage += " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n";
- strUsage += " -maxconnections=<n> " + strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125) + "\n";
- strUsage += " -maxreceivebuffer=<n> " + strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000) + "\n";
- strUsage += " -maxsendbuffer=<n> " + strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000) + "\n";
- strUsage += " -onion=<ip:port> " + strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy") + "\n";
- strUsage += " -onlynet=<net> " + _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)") + "\n";
- strUsage += " -permitbaremultisig " + strprintf(_("Relay non-P2SH multisig (default: %u)"), 1) + "\n";
- strUsage += " -port=<port> " + strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 8333, 18333) + "\n";
- strUsage += " -proxy=<ip:port> " + _("Connect through SOCKS5 proxy") + "\n";
- strUsage += " -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n";
- strUsage += " -timeout=<n> " + strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT) + "\n";
+ strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0));
+
+ strUsage += HelpMessageGroup(_("Connection options:"));
+ strUsage += HelpMessageOpt("-addnode=<ip>", _("Add a node to connect to and attempt to keep the connection open"));
+ strUsage += HelpMessageOpt("-banscore=<n>", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100));
+ strUsage += HelpMessageOpt("-bantime=<n>", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400));
+ strUsage += HelpMessageOpt("-bind=<addr>", _("Bind to given address and always listen on it. Use [host]:port notation for IPv6"));
+ strUsage += HelpMessageOpt("-connect=<ip>", _("Connect only to the specified node(s)"));
+ strUsage += HelpMessageOpt("-discover", _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)"));
+ strUsage += HelpMessageOpt("-dns", _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)"));
+ strUsage += HelpMessageOpt("-dnsseed", _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)"));
+ strUsage += HelpMessageOpt("-externalip=<ip>", _("Specify your own public address"));
+ strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)"));
+ strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125));
+ strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000));
+ strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000));
+ strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy"));
+ strUsage += HelpMessageOpt("-onlynet=<net>", _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)"));
+ strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-port=<port>", strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 8333, 18333));
+ strUsage += HelpMessageOpt("-proxy=<ip:port>", _("Connect through SOCKS5 proxy"));
+ strUsage += HelpMessageOpt("-seednode=<ip>", _("Connect to a node to retrieve peer addresses, and disconnect"));
+ strUsage += HelpMessageOpt("-timeout=<n>", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT));
#ifdef USE_UPNP
#if USE_UPNP
- strUsage += " -upnp " + _("Use UPnP to map the listening port (default: 1 when listening)") + "\n";
+ strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening)"));
#else
- strUsage += " -upnp " + strprintf(_("Use UPnP to map the listening port (default: %u)"), 0) + "\n";
+ strUsage += HelpMessageOpt("-upnp", strprintf(_("Use UPnP to map the listening port (default: %u)"), 0));
#endif
#endif
- strUsage += " -whitebind=<addr> " + _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6") + "\n";
- strUsage += " -whitelist=<netmask> " + _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + "\n";
- strUsage += " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway") + "\n";
+ strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6"));
+ strUsage += HelpMessageOpt("-whitelist=<netmask>", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") +
+ " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway"));
+
#ifdef ENABLE_WALLET
- strUsage += "\n" + _("Wallet options:") + "\n";
- strUsage += " -disablewallet " + _("Do not load the wallet and disable wallet RPC calls") + "\n";
- strUsage += " -keypool=<n> " + strprintf(_("Set key pool size to <n> (default: %u)"), 100) + "\n";
+ strUsage += HelpMessageGroup(_("Wallet options:"));
+ strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
+ strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100));
if (GetBoolArg("-help-debug", false))
- strUsage += " -mintxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"), FormatMoney(CWallet::minTxFee.GetFeePerK())) + "\n";
- strUsage += " -paytxfee=<amt> " + strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())) + "\n";
- strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + " " + _("on startup") + "\n";
- strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n";
- strUsage += " -sendfreetransactions " + strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0) + "\n";
- strUsage += " -spendzeroconfchange " + strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1) + "\n";
- strUsage += " -txconfirmtarget=<n> " + strprintf(_("If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)"), 1) + "\n";
- strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n";
- strUsage += " -wallet=<file> " + _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat") + "\n";
- strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n";
- strUsage += " -zapwallettxes=<mode> " + _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + "\n";
- strUsage += " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)") + "\n";
+ strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"),
+ FormatMoney(CWallet::minTxFee.GetFeePerK())));
+ strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())));
+ strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup"));
+ strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup"));
+ strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"),
+ FormatMoney(maxTxFee)));
+ strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup"));
+ strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat"));
+ strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
+ strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
+ " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
+
#endif
- strUsage += "\n" + _("Debugging/Testing options:") + "\n";
+ strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
if (GetBoolArg("-help-debug", false))
{
- strUsage += " -checkpoints " + strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1) + "\n";
- strUsage += " -dblogsize=<n> " + strprintf(_("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)"), 100) + "\n";
- strUsage += " -disablesafemode " + strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0) + "\n";
- strUsage += " -testsafemode " + strprintf(_("Force safe mode (default: %u)"), 0) + "\n";
- strUsage += " -dropmessagestest=<n> " + _("Randomly drop 1 of every <n> network messages") + "\n";
- strUsage += " -fuzzmessagestest=<n> " + _("Randomly fuzz 1 of every <n> network messages") + "\n";
- strUsage += " -flushwallet " + strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1) + "\n";
- strUsage += " -stopafterblockimport " + strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0) + "\n";
+ strUsage += HelpMessageOpt("-checkpoints", strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf(_("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)"), 100));
+ strUsage += HelpMessageOpt("-disablesafemode", strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-testsafemode", strprintf(_("Force safe mode (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-dropmessagestest=<n>", _("Randomly drop 1 of every <n> network messages"));
+ strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", _("Randomly fuzz 1 of every <n> network messages"));
+ strUsage += HelpMessageOpt("-flushwallet", strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-stopafterblockimport", strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0));
}
- strUsage += " -debug=<category> " + strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + "\n";
- strUsage += " " + _("If <category> is not supplied, output all debugging information.") + "\n";
- strUsage += " " + _("<category> can be:");
- strUsage += " addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below
+ string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below
if (mode == HMM_BITCOIN_QT)
- strUsage += ", qt";
- strUsage += ".\n";
+ debugCategories += ", qt";
+ strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
+ _("If <category> is not supplied, output all debugging information.") + _("<category> can be:") + " " + debugCategories + ".");
#ifdef ENABLE_WALLET
- strUsage += " -gen " + strprintf(_("Generate coins (default: %u)"), 0) + "\n";
- strUsage += " -genproclimit=<n> " + strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1) + "\n";
+ strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1));
#endif
- strUsage += " -help-debug " + _("Show all debugging options (usage: --help -help-debug)") + "\n";
- strUsage += " -logips " + strprintf(_("Include IP addresses in debug output (default: %u)"), 0) + "\n";
- strUsage += " -logtimestamps " + strprintf(_("Prepend debug output with timestamp (default: %u)"), 1) + "\n";
+ strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)"));
+ strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1));
if (GetBoolArg("-help-debug", false))
{
- strUsage += " -limitfreerelay=<n> " + strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15) + "\n";
- strUsage += " -maxsigcachesize=<n> " + strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000) + "\n";
+ strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15));
+ strUsage += HelpMessageOpt("-relaypriority", strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1));
+ strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000));
}
- strUsage += " -minrelaytxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())) + "\n";
- strUsage += " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n";
+ strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())));
+ strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file"));
if (GetBoolArg("-help-debug", false))
{
- strUsage += " -printblock=<hash> " + _("Print block on startup, if found in block index") + "\n";
- strUsage += " -printblocktree " + strprintf(_("Print block tree on startup (default: %u)"), 0) + "\n";
- strUsage += " -printpriority " + strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0) + "\n";
- strUsage += " -privdb " + strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1) + "\n";
- strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n";
- strUsage += " " + _("This is intended for regression testing tools and app development.") + "\n";
- strUsage += " " + _("In this mode -genproclimit controls how many blocks are generated immediately.") + "\n";
+ strUsage += HelpMessageOpt("-printpriority", strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-privdb", strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + " " +
+ _("This is intended for regression testing tools and app development.") + " " +
+ _("In this mode -genproclimit controls how many blocks are generated immediately."));
+ }
+ strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)"));
+ strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
+
+ strUsage += HelpMessageGroup(_("Node relay options:"));
+ strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1));
+ strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY));
+
+ strUsage += HelpMessageGroup(_("Block creation options:"));
+ strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-blockmaxsize=<n>", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE));
+ strUsage += HelpMessageOpt("-blockprioritysize=<n>", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE));
+
+ strUsage += HelpMessageGroup(_("RPC server options:"));
+ strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands"));
+ strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), 0));
+ strUsage += HelpMessageOpt("-rpcbind=<addr>", _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)"));
+ strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332));
+ strUsage += HelpMessageOpt("-rpcallowip=<ip>", _("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"));
+ strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4));
+ strUsage += HelpMessageOpt("-rpckeepalive", strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1));
+
+ strUsage += HelpMessageGroup(_("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
+ strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
+ strUsage += HelpMessageOpt("-rpcsslcertificatechainfile=<file.cert>", strprintf(_("Server certificate file (default: %s)"), "server.cert"));
+ strUsage += HelpMessageOpt("-rpcsslprivatekeyfile=<file.pem>", strprintf(_("Server private key (default: %s)"), "server.pem"));
+ strUsage += HelpMessageOpt("-rpcsslciphers=<ciphers>", strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"));
+
+ if (mode == HMM_BITCOIN_QT)
+ {
+ strUsage += HelpMessageGroup(_("UI Options:"));
+ if (GetBoolArg("-help-debug", false)) {
+ strUsage += HelpMessageOpt("-allowselfsignedrootcertificates", _("Allow self signed root certificates (default: 0)"));
+ }
+ strUsage += HelpMessageOpt("-choosedatadir", _("Choose data directory on startup (default: 0)"));
+ strUsage += HelpMessageOpt("-lang=<lang>", _("Set language, for example \"de_DE\" (default: system locale)"));
+ strUsage += HelpMessageOpt("-min", _("Start minimized"));
+ strUsage += HelpMessageOpt("-rootcertificates=<file>", _("Set SSL root certificates for payment request (default: -system-)"));
+ strUsage += HelpMessageOpt("-splash", _("Show splash screen on startup (default: 1)"));
}
- strUsage += " -shrinkdebugfile " + _("Shrink debug.log file on client startup (default: 1 when no -debug)") + "\n";
- strUsage += " -testnet " + _("Use the test network") + "\n";
-
- strUsage += "\n" + _("Node relay options:") + "\n";
- strUsage += " -datacarrier " + strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1) + "\n";
- strUsage += " -datacarriersize " + strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY) + "\n";
-
- strUsage += "\n" + _("Block creation options:") + "\n";
- strUsage += " -blockminsize=<n> " + strprintf(_("Set minimum block size in bytes (default: %u)"), 0) + "\n";
- strUsage += " -blockmaxsize=<n> " + strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE) + "\n";
- strUsage += " -blockprioritysize=<n> " + strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE) + "\n";
-
- strUsage += "\n" + _("RPC server options:") + "\n";
- strUsage += " -server " + _("Accept command line and JSON-RPC commands") + "\n";
- strUsage += " -rpcbind=<addr> " + _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)") + "\n";
- strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
- strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
- strUsage += " -rpcport=<port> " + strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n";
- strUsage += " -rpcallowip=<ip> " + _("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") + "\n";
- strUsage += " -rpcthreads=<n> " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n";
-
- strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
- strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
- strUsage += " -rpcsslcertificatechainfile=<file.cert> " + strprintf(_("Server certificate file (default: %s)"), "server.cert") + "\n";
- strUsage += " -rpcsslprivatekeyfile=<file.pem> " + strprintf(_("Server private key (default: %s)"), "server.pem") + "\n";
- strUsage += " -rpcsslciphers=<ciphers> " + strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH") + "\n";
return strUsage;
}
}
// hardcoded $DATADIR/bootstrap.dat
- filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
- if (filesystem::exists(pathBootstrap)) {
+ boost::filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
+ if (boost::filesystem::exists(pathBootstrap)) {
FILE *file = fopen(pathBootstrap.string().c_str(), "rb");
if (file) {
CImportingNow imp;
- filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
+ boost::filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
LogPrintf("Importing bootstrap.dat...\n");
LoadExternalBlockFile(file);
RenameOver(pathBootstrap, pathBootstrapOld);
#endif
// ********************************************************* Step 2: parameter interactions
+
// Set this early so that parameter interactions go to console
fPrintToConsole = GetBoolArg("-printtoconsole", false);
fLogTimestamps = GetBoolArg("-logtimestamps", true);
fLogIPs = GetBoolArg("-logips", false);
- if (mapArgs.count("-bind") || mapArgs.count("-whitebind")) {
- // when specifying an explicit binding address, you want to listen on it
- // even when -connect or -proxy is specified
+ // when specifying an explicit binding address, you want to listen on it
+ // even when -connect or -proxy is specified
+ if (mapArgs.count("-bind")) {
+ if (SoftSetBoolArg("-listen", true))
+ LogPrintf("%s: parameter interaction: -bind set -> setting -listen=1\n", __func__);
+ }
+ if (mapArgs.count("-whitebind")) {
if (SoftSetBoolArg("-listen", true))
- LogPrintf("AppInit2 : parameter interaction: -bind or -whitebind set -> setting -listen=1\n");
+ LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__);
}
if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) {
// when only connecting to trusted nodes, do not seed via DNS, or listen by default
if (SoftSetBoolArg("-dnsseed", false))
- LogPrintf("AppInit2 : parameter interaction: -connect set -> setting -dnsseed=0\n");
+ LogPrintf("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__);
if (SoftSetBoolArg("-listen", false))
- LogPrintf("AppInit2 : parameter interaction: -connect set -> setting -listen=0\n");
+ LogPrintf("%s: parameter interaction: -connect set -> setting -listen=0\n", __func__);
}
if (mapArgs.count("-proxy")) {
// to protect privacy, do not listen by default if a default proxy server is specified
if (SoftSetBoolArg("-listen", false))
- LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -listen=0\n");
+ LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__);
// to protect privacy, do not discover addresses by default
if (SoftSetBoolArg("-discover", false))
- LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -discover=0\n");
+ LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__);
}
- if (!GetBoolArg("-listen", true)) {
+ if (!GetBoolArg("-listen", DEFAULT_LISTEN)) {
// do not map ports or try to retrieve public IP when not listening (pointless)
if (SoftSetBoolArg("-upnp", false))
- LogPrintf("AppInit2 : parameter interaction: -listen=0 -> setting -upnp=0\n");
+ LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__);
if (SoftSetBoolArg("-discover", false))
- LogPrintf("AppInit2 : parameter interaction: -listen=0 -> setting -discover=0\n");
+ LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__);
}
if (mapArgs.count("-externalip")) {
// if an explicit public IP is specified, do not try to find others
if (SoftSetBoolArg("-discover", false))
- LogPrintf("AppInit2 : parameter interaction: -externalip set -> setting -discover=0\n");
+ LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__);
}
if (GetBoolArg("-salvagewallet", false)) {
// Rewrite just private keys: rescan to find transactions
if (SoftSetBoolArg("-rescan", true))
- LogPrintf("AppInit2 : parameter interaction: -salvagewallet=1 -> setting -rescan=1\n");
+ LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__);
}
// -zapwallettx implies a rescan
if (GetBoolArg("-zapwallettxes", false)) {
if (SoftSetBoolArg("-rescan", true))
- LogPrintf("AppInit2 : parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n");
+ LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__);
}
// Make sure enough file descriptors are available
mapArgs["-paytxfee"], ::minRelayTxFee.ToString()));
}
}
+ if (mapArgs.count("-maxtxfee"))
+ {
+ CAmount nMaxFee = 0;
+ if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee))
+ return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s'"), mapArgs["-maptxfee"]));
+ if (nMaxFee > nHighTransactionMaxFeeWarning)
+ InitWarning(_("Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction."));
+ maxTxFee = nMaxFee;
+ if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee)
+ {
+ return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
+ mapArgs["-maxtxfee"], ::minRelayTxFee.ToString()));
+ }
+ }
nTxConfirmTarget = GetArg("-txconfirmtarget", 1);
bSpendZeroConfChange = GetArg("-spendzeroconfchange", true);
fSendFreeTransactions = GetArg("-sendfreetransactions", false);
if (fServer)
{
uiInterface.InitMessage.connect(SetRPCWarmupStatus);
+ RPCServer::OnStopped(&OnRPCStopped);
+ RPCServer::OnPreCommand(&OnRPCPreCommand);
StartRPCThreads();
}
try {
boost::filesystem::rename(pathDatabase, pathDatabaseBak);
LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string());
- } catch(boost::filesystem::filesystem_error &error) {
+ } catch (const boost::filesystem::filesystem_error&) {
// failure is ok (well, not really, but it's not worse than what we started with)
}
return false;
}
- if (filesystem::exists(GetDataDir() / strWalletFile))
+ if (boost::filesystem::exists(GetDataDir() / strWalletFile))
{
CDBEnv::VerifyResult r = bitdb.Verify(strWalletFile, CWalletDB::Recover);
if (r == CDBEnv::RECOVER_OK)
fReindex = GetBoolArg("-reindex", false);
// Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/
- filesystem::path blocksDir = GetDataDir() / "blocks";
- if (!filesystem::exists(blocksDir))
+ boost::filesystem::path blocksDir = GetDataDir() / "blocks";
+ if (!boost::filesystem::exists(blocksDir))
{
- filesystem::create_directories(blocksDir);
+ boost::filesystem::create_directories(blocksDir);
bool linked = false;
for (unsigned int i = 1; i < 10000; i++) {
- filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i);
- if (!filesystem::exists(source)) break;
- filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1);
+ boost::filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i);
+ if (!boost::filesystem::exists(source)) break;
+ boost::filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1);
try {
- filesystem::create_hard_link(source, dest);
+ boost::filesystem::create_hard_link(source, dest);
LogPrintf("Hardlinked %s -> %s\n", source.string(), dest.string());
linked = true;
- } catch (filesystem::filesystem_error & e) {
+ } catch (const boost::filesystem::filesystem_error& e) {
// Note: hardlink creation failing is not a disaster, it just means
// blocks will get re-downloaded from peers.
- LogPrintf("Error hardlinking blk%04u.dat : %s\n", i, e.what());
+ LogPrintf("Error hardlinking blk%04u.dat: %s\n", i, e.what());
break;
}
}
UnloadBlockIndex();
delete pcoinsTip;
delete pcoinsdbview;
+ delete pcoinscatcher;
delete pblocktree;
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
- pcoinsTip = new CCoinsViewCache(pcoinsdbview);
+ pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview);
+ pcoinsTip = new CCoinsViewCache(pcoinscatcher);
if (fReindex)
pblocktree->WriteReindexing(true);
strLoadError = _("Corrupted block database detected");
break;
}
- } catch(std::exception &e) {
+ } catch (const std::exception& e) {
if (fDebug) LogPrintf("%s\n", e.what());
strLoadError = _("Error opening block database");
break;
}
LogPrintf(" block index %15dms\n", GetTimeMillis() - nStart);
- if (GetBoolArg("-printblockindex", false) || GetBoolArg("-printblocktree", false))
- {
- PrintBlockTree();
- return false;
- }
-
- if (mapArgs.count("-printblock"))
- {
- string strMatch = mapArgs["-printblock"];
- int nFound = 0;
- for (BlockMap::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
- {
- uint256 hash = (*mi).first;
- if (boost::algorithm::starts_with(hash.ToString(), strMatch))
- {
- CBlockIndex* pindex = (*mi).second;
- CBlock block;
- ReadBlockFromDisk(block, pindex);
- block.BuildMerkleTree();
- LogPrintf("%s\n", block.ToString());
- nFound++;
- }
- }
- if (nFound == 0)
- LogPrintf("No blocks matching %s were found\n", strMatch);
- return false;
- }
-
boost::filesystem::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
CAutoFile est_filein(fopen(est_path.string().c_str(), "rb"), SER_DISK, CLIENT_VERSION);
// Allowed to fail as this file IS missing on first startup.
// Restore wallet transaction metadata after -zapwallettxes=1
if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2")
{
+ CWalletDB walletdb(strWalletFile);
+
BOOST_FOREACH(const CWalletTx& wtxOld, vWtx)
{
uint256 hash = wtxOld.GetHash();
copyTo->fFromMe = copyFrom->fFromMe;
copyTo->strFromAccount = copyFrom->strFromAccount;
copyTo->nOrderPos = copyFrom->nOrderPos;
- copyTo->WriteToDisk();
+ copyTo->WriteToDisk(&walletdb);
}
}
}
vImportFiles.push_back(strFile);
}
threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles));
+ if (chainActive.Tip() == NULL) {
+ LogPrintf("Waiting for genesis block to be imported...\n");
+ while (!fRequestShutdown && chainActive.Tip() == NULL)
+ MilliSleep(10);
+ }
// ********************************************************* Step 10: start node
// 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 Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_INIT_H
void Shutdown();
bool AppInit2(boost::thread_group& threadGroup);
-/* The help message mode determines what help message to show */
+/** The help message mode determines what help message to show */
enum HelpMessageMode {
HMM_BITCOIND,
HMM_BITCOIN_QT
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "key.h"
-#include "crypto/sha2.h"
+#include "arith_uint256.h"
+#include "crypto/hmac_sha512.h"
#include "eccryptoverify.h"
#include "pubkey.h"
#include "random.h"
}
void CKey::MakeNewKey(bool fCompressedIn) {
+ RandAddSeedPerfmon();
do {
GetRandBytes(vch, sizeof(vch));
} while (!Check(vch));
return result;
}
-bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const {
+extern "C"
+{
+static int secp256k1_nonce_function_test_case(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int attempt, const void *data)
+{
+ const uint32_t *test_case = static_cast<const uint32_t*>(data);
+ uint256 nonce;
+ secp256k1_nonce_function_rfc6979(nonce.begin(), msg32, key32, attempt, NULL);
+ nonce = ArithToUint256(UintToArith256(nonce) + *test_case);
+ memcpy(nonce32, nonce.begin(), 32);
+ return 1;
+}
+}
+
+bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_t test_case) const {
if (!fValid)
return false;
vchSig.resize(72);
int nSigLen = 72;
- CKey nonce;
- do {
- nonce.MakeNewKey(true);
- if (secp256k1_ecdsa_sign((const unsigned char*)&hash, 32, (unsigned char*)&vchSig[0], &nSigLen, begin(), nonce.begin()))
- break;
- } while(true);
+ int ret = secp256k1_ecdsa_sign(hash.begin(), (unsigned char*)&vchSig[0], &nSigLen, begin(), test_case == 0 ? secp256k1_nonce_function_rfc6979 : secp256k1_nonce_function_test_case, test_case == 0 ? NULL : &test_case);
+ assert(ret);
vchSig.resize(nSigLen);
return true;
}
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);
+ CHash256().Write((unsigned char*)str.data(), str.size()).Write(rnd, sizeof(rnd)).Finalize(hash.begin());
std::vector<unsigned char> vchSig;
Sign(hash, vchSig);
return pubkey.Verify(hash, vchSig);
return false;
vchSig.resize(65);
int rec = -1;
- CKey nonce;
- do {
- nonce.MakeNewKey(true);
- if (secp256k1_ecdsa_sign_compact((const unsigned char*)&hash, 32, &vchSig[1], begin(), nonce.begin(), &rec))
- break;
- } while(true);
+ int ret = secp256k1_ecdsa_sign_compact(hash.begin(), &vchSig[1], begin(), secp256k1_nonce_function_rfc6979, NULL, &rec);
+ assert(ret);
assert(rec != -1);
vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
return true;
}
bool ECC_InitSanityCheck() {
-#if !defined(USE_SECP256K1)
if (!CECKey::SanityCheck()) {
return false;
}
-#endif
CKey key;
key.MakeNewKey(true);
CPubKey pubkey = key.GetPubKey();
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
*/
CPubKey GetPubKey() const;
- //! Create a DER-serialized signature.
- bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig) const;
+ /**
+ * Create a DER-serialized signature.
+ * The test_case parameter tweaks the deterministic nonce, and is only for
+ * testing. It should be zero for normal use.
+ */
+ bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, uint32_t test_case = 0) const;
/**
* Create a compact signature (65 bytes), which allows reconstructing the used public key.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "crypter.h"
#include "key.h"
-#include "script/script.h"
-#include "script/standard.h"
#include "util.h"
#include <boost/foreach.hpp>
bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
{
if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
- return error("CBasicKeyStore::AddCScript() : redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
+ return error("CBasicKeyStore::AddCScript(): redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
LOCK(cs_KeyStore);
mapScripts[CScriptID(redeemScript)] = redeemScript;
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "key.h"
#include "pubkey.h"
+#include "script/script.h"
+#include "script/standard.h"
#include "sync.h"
#include <boost/signals2/signal.hpp>
#include <boost/variant.hpp>
-class CScript;
-class CScriptID;
-
/** A virtual base class for key stores */
class CKeyStore
{
-// Copyright (c) 2012-2014 The Bitcoin developers
+// Copyright (c) 2012-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.
-// Copyright (c) 2012-2014 The Bitcoin developers
+// Copyright (c) 2012-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.
-// Copyright (c) 2012-2014 The Bitcoin developers
+// Copyright (c) 2012-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.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "main.h"
+#include "arith_uint256.h"
#include "addrman.h"
#include "alert.h"
#include "chainparams.h"
#include "checkpoints.h"
#include "checkqueue.h"
#include "init.h"
+#include "merkleblock.h"
#include "net.h"
#include "pow.h"
#include "txdb.h"
#include "txmempool.h"
#include "ui_interface.h"
+#include "undo.h"
#include "util.h"
#include "utilmoneystr.h"
#include <boost/filesystem/fstream.hpp>
#include <boost/thread.hpp>
-using namespace boost;
using namespace std;
#if defined(NDEBUG)
# error "Bitcoin cannot be compiled without assertions."
#endif
-//
-// Global state
-//
+/**
+ * Global state
+ */
CCriticalSection cs_main;
bool fIsBareMultisigStd = true;
unsigned int nCoinCacheSize = 5000;
-
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
CFeeRate minRelayTxFee = CFeeRate(1000);
map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
void EraseOrphansFor(NodeId peer);
-// Constant stuff for coinbase transactions we create:
+/**
+ * Returns true if there are nRequired or more blocks of minVersion or above
+ * in the last Params().ToCheckBlockUpgradeMajority() blocks, starting at pstart
+ * and going backwards.
+ */
+static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired);
+
+/** Constant stuff for coinbase transactions we create: */
CScript COINBASE_FLAGS;
const string strMessageMagic = "Bitcoin Signed Message:\n";
CBlockIndex *pindexBestInvalid;
- // The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS or better that are at least
- // as good as our current tip. Entries may be failed, though.
+ /**
+ * The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS or better that are at least
+ * as good as our current tip. Entries may be failed, though.
+ */
set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
- // Number of nodes with fSyncStarted.
+ /** Number of nodes with fSyncStarted. */
int nSyncStarted = 0;
- // All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions.
+ /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions. */
multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked;
CCriticalSection cs_LastBlockFile;
std::vector<CBlockFileInfo> vinfoBlockFile;
int nLastBlockFile = 0;
- // Every received block is assigned a unique and increasing identifier, so we
- // know which one to give priority in case of a fork.
+ /**
+ * Every received block is assigned a unique and increasing identifier, so we
+ * know which one to give priority in case of a fork.
+ */
CCriticalSection cs_nBlockSequenceId;
- // Blocks loaded from disk are assigned id 0, so start the counter at 1.
+ /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
uint32_t nBlockSequenceId = 1;
- // Sources of received blocks, to be able to send them reject messages or ban
- // them, if processing happens afterwards. Protected by cs_main.
+ /**
+ * Sources of received blocks, to be able to send them reject messages or ban
+ * them, if processing happens afterwards. Protected by cs_main.
+ */
map<uint256, NodeId> mapBlockSource;
- // Blocks that are in flight, and that are in the queue to be downloaded.
- // Protected by cs_main.
+ /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
struct QueuedBlock {
uint256 hash;
- CBlockIndex *pindex; // Optional.
- int64_t nTime; // Time of "getdata" request in microseconds.
+ CBlockIndex *pindex; //! Optional.
+ int64_t nTime; //! Time of "getdata" request in microseconds.
+ int nValidatedQueuedBefore; //! Number of blocks queued with validated headers (globally) at the time this one is requested.
+ bool fValidatedHeaders; //! Whether this block has validated headers at the time of request.
};
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
- // Number of preferrable block download peers.
+ /** Number of blocks in flight with validated headers. */
+ int nQueuedValidatedHeaders = 0;
+
+ /** Number of preferable block download peers. */
int nPreferredDownload = 0;
+
+ /** Dirty block index entries. */
+ set<CBlockIndex*> setDirtyBlockIndex;
+
+ /** Dirty block file entries. */
+ set<int> setDirtyFileInfo;
} // anon namespace
//////////////////////////////////////////////////////////////////////////////
namespace {
struct CMainSignals {
- // Notifies listeners of updated transaction data (transaction, and optionally the block it is found in.
+ /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */
boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction;
- // Notifies listeners of an erased transaction (currently disabled, requires transaction replacement).
+ /** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */
boost::signals2::signal<void (const uint256 &)> EraseTransaction;
- // Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible).
+ /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
- // Notifies listeners of a new active block chain.
+ /** Notifies listeners of a new active block chain. */
boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
- // Notifies listeners about an inventory item being seen on the network.
+ /** Notifies listeners about an inventory item being seen on the network. */
boost::signals2::signal<void (const uint256 &)> Inventory;
- // Tells listeners to broadcast their data.
+ /** Tells listeners to broadcast their data. */
boost::signals2::signal<void ()> Broadcast;
- // Notifies listeners of a block validation result
+ /** Notifies listeners of a block validation result */
boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
} g_signals;
uint256 hashBlock;
};
-// Maintain validation-specific state about nodes, protected by cs_main, instead
-// by CNode's own locks. This simplifies asynchronous operation, where
-// processing of incoming data is done after the ProcessMessage call returns,
-// and we're no longer holding the node's locks.
+/**
+ * Maintain validation-specific state about nodes, protected by cs_main, instead
+ * by CNode's own locks. This simplifies asynchronous operation, where
+ * processing of incoming data is done after the ProcessMessage call returns,
+ * and we're no longer holding the node's locks.
+ */
struct CNodeState {
- // Accumulated misbehaviour score for this peer.
+ //! The peer's address
+ CService address;
+ //! Whether we have a fully established connection.
+ bool fCurrentlyConnected;
+ //! Accumulated misbehaviour score for this peer.
int nMisbehavior;
- // Whether this peer should be disconnected and banned (unless whitelisted).
+ //! Whether this peer should be disconnected and banned (unless whitelisted).
bool fShouldBan;
- // String name of this peer (debugging/logging purposes).
+ //! String name of this peer (debugging/logging purposes).
std::string name;
- // List of asynchronously-determined block rejections to notify this peer about.
+ //! List of asynchronously-determined block rejections to notify this peer about.
std::vector<CBlockReject> rejects;
- // The best known block we know this peer has announced.
+ //! The best known block we know this peer has announced.
CBlockIndex *pindexBestKnownBlock;
- // The hash of the last unknown block this peer has announced.
+ //! The hash of the last unknown block this peer has announced.
uint256 hashLastUnknownBlock;
- // The last full block we both have.
+ //! The last full block we both have.
CBlockIndex *pindexLastCommonBlock;
- // Whether we've started headers synchronization with this peer.
+ //! Whether we've started headers synchronization with this peer.
bool fSyncStarted;
- // Since when we're stalling block download progress (in microseconds), or 0.
+ //! Since when we're stalling block download progress (in microseconds), or 0.
int64_t nStallingSince;
list<QueuedBlock> vBlocksInFlight;
int nBlocksInFlight;
- // Whether we consider this a preferred download peer.
+ //! Whether we consider this a preferred download peer.
bool fPreferredDownload;
CNodeState() {
+ fCurrentlyConnected = false;
nMisbehavior = 0;
fShouldBan = false;
pindexBestKnownBlock = NULL;
- hashLastUnknownBlock = uint256(0);
+ hashLastUnknownBlock.SetNull();
pindexLastCommonBlock = NULL;
fSyncStarted = false;
nStallingSince = 0;
}
};
-// Map maintaining per-node state. Requires cs_main.
+/** Map maintaining per-node state. Requires cs_main. */
map<NodeId, CNodeState> mapNodeState;
// Requires cs_main.
LOCK(cs_main);
CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
state.name = pnode->addrName;
+ state.address = pnode->addr;
}
void FinalizeNode(NodeId nodeid) {
if (state->fSyncStarted)
nSyncStarted--;
+ if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
+ AddressCurrentlyConnected(state->address);
+ }
+
BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
mapBlocksInFlight.erase(entry.hash);
EraseOrphansFor(nodeid);
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
if (itInFlight != mapBlocksInFlight.end()) {
CNodeState *state = State(itInFlight->second.first);
+ nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
state->vBlocksInFlight.erase(itInFlight->second.second);
state->nBlocksInFlight--;
state->nStallingSince = 0;
// Make sure it's not listed somewhere already.
MarkBlockAsReceived(hash);
- QueuedBlock newentry = {hash, pindex, GetTimeMicros()};
+ QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != NULL};
+ nQueuedValidatedHeaders += newentry.fValidatedHeaders;
list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
state->nBlocksInFlight++;
mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
CNodeState *state = State(nodeid);
assert(state != NULL);
- if (state->hashLastUnknownBlock != 0) {
+ if (!state->hashLastUnknownBlock.IsNull()) {
BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0) {
if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
state->pindexBestKnownBlock = itOld->second;
- state->hashLastUnknownBlock = uint256(0);
+ state->hashLastUnknownBlock.SetNull();
}
}
}
// are not yet downloaded and not in flight to vBlocks. In the mean time, update
// pindexLastCommonBlock as long as all ancestors are already downloaded.
BOOST_FOREACH(CBlockIndex* pindex, vToFetch) {
+ if (!pindex->IsValid(BLOCK_VALID_TREE)) {
+ // We consider the chain that this peer is on invalid.
+ return;
+ }
if (pindex->nStatus & BLOCK_HAVE_DATA) {
if (pindex->nChainTx)
state->pindexLastCommonBlock = pindex;
bool IsStandardTx(const CTransaction& tx, string& reason)
{
- AssertLockHeld(cs_main);
if (tx.nVersion > CTransaction::CURRENT_VERSION || tx.nVersion < 1) {
reason = "version";
return false;
}
- // Treat non-final transactions as non-standard to prevent a specific type
- // of double-spend attack, as well as DoS attacks. (if the transaction
- // can't be mined, the attacker isn't expending resources broadcasting it)
- // Basically we don't want to propagate transactions that can't be included in
- // the next block.
- //
- // However, IsFinalTx() is confusing... Without arguments, it uses
- // chainActive.Height() to evaluate nLockTime; when a block is accepted, chainActive.Height()
- // is set to the value of nHeight in the block. However, when IsFinalTx()
- // is called within CBlock::AcceptBlock(), the height of the block *being*
- // evaluated is what is used. Thus if we want to know if a transaction can
- // be part of the *next* block, we need to call IsFinalTx() with one more
- // than chainActive.Height().
- //
- // Timestamps on the other hand don't get any special treatment, because we
- // can't know what timestamp the next block will have, and there aren't
- // timestamp applications where it matters.
- if (!IsFinalTx(tx, chainActive.Height() + 1)) {
- reason = "non-final";
- return false;
- }
-
// Extremely large transactions with lots of inputs can cost the network
// almost as much to process as they cost the sender in fees, because
// computing signature hashes is O(ninputs*txsize). Limiting transactions
return true;
}
-//
-// Check transaction inputs to mitigate two
-// potential denial-of-service attacks:
-//
-// 1. scriptSigs with extra data stuffed into them,
-// not consumed by scriptPubKey (or P2SH script)
-// 2. P2SH scripts with a crazy number of expensive
-// CHECKSIG/CHECKMULTISIG operations
-//
+/**
+ * Check transaction inputs to mitigate two
+ * potential denial-of-service attacks:
+ *
+ * 1. scriptSigs with extra data stuffed into them,
+ * not consumed by scriptPubKey (or P2SH script)
+ * 2. P2SH scripts with a crazy number of expensive
+ * CHECKSIG/CHECKMULTISIG operations
+ */
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
if (tx.IsCoinBase())
// non-standard. Note that this EvalScript() call will
// be quick, because if there are any operations
// beside "push data" in the scriptSig
- // IsStandard() will have already returned false
+ // IsStandardTx() will have already returned false
// and this method isn't called.
vector<vector<unsigned char> > stack;
- if (!EvalScript(stack, tx.vin[i].scriptSig, false, BaseSignatureChecker()))
+ if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker()))
return false;
if (whichType == TX_SCRIPTHASH)
{
// Basic checks that don't depend on any context
if (tx.vin.empty())
- return state.DoS(10, error("CheckTransaction() : vin empty"),
+ return state.DoS(10, error("CheckTransaction(): vin empty"),
REJECT_INVALID, "bad-txns-vin-empty");
if (tx.vout.empty())
- return state.DoS(10, error("CheckTransaction() : vout empty"),
+ return state.DoS(10, error("CheckTransaction(): vout empty"),
REJECT_INVALID, "bad-txns-vout-empty");
// Size limits
if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
- return state.DoS(100, error("CheckTransaction() : size limits failed"),
+ return state.DoS(100, error("CheckTransaction(): size limits failed"),
REJECT_INVALID, "bad-txns-oversize");
// Check for negative or overflow output values
BOOST_FOREACH(const CTxOut& txout, tx.vout)
{
if (txout.nValue < 0)
- return state.DoS(100, error("CheckTransaction() : txout.nValue negative"),
+ return state.DoS(100, error("CheckTransaction(): txout.nValue negative"),
REJECT_INVALID, "bad-txns-vout-negative");
if (txout.nValue > MAX_MONEY)
- return state.DoS(100, error("CheckTransaction() : txout.nValue too high"),
+ return state.DoS(100, error("CheckTransaction(): txout.nValue too high"),
REJECT_INVALID, "bad-txns-vout-toolarge");
nValueOut += txout.nValue;
if (!MoneyRange(nValueOut))
- return state.DoS(100, error("CheckTransaction() : txout total out of range"),
+ return state.DoS(100, error("CheckTransaction(): txout total out of range"),
REJECT_INVALID, "bad-txns-txouttotal-toolarge");
}
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
if (vInOutPoints.count(txin.prevout))
- return state.DoS(100, error("CheckTransaction() : duplicate inputs"),
+ return state.DoS(100, error("CheckTransaction(): duplicate inputs"),
REJECT_INVALID, "bad-txns-inputs-duplicate");
vInOutPoints.insert(txin.prevout);
}
if (tx.IsCoinBase())
{
if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
- return state.DoS(100, error("CheckTransaction() : coinbase script size"),
+ return state.DoS(100, error("CheckTransaction(): coinbase script size"),
REJECT_INVALID, "bad-cb-length");
}
else
{
BOOST_FOREACH(const CTxIn& txin, tx.vin)
if (txin.prevout.IsNull())
- return state.DoS(10, error("CheckTransaction() : prevout is null"),
+ return state.DoS(10, error("CheckTransaction(): prevout is null"),
REJECT_INVALID, "bad-txns-prevout-null");
}
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
- bool* pfMissingInputs, bool fRejectInsaneFee)
+ bool* pfMissingInputs, bool fRejectAbsurdFee)
{
AssertLockHeld(cs_main);
if (pfMissingInputs)
*pfMissingInputs = false;
if (!CheckTransaction(tx, state))
- return error("AcceptToMemoryPool: : CheckTransaction failed");
+ return error("AcceptToMemoryPool: CheckTransaction failed");
// Coinbase is only valid in a block, not as a loose transaction
if (tx.IsCoinBase())
- return state.DoS(100, error("AcceptToMemoryPool: : coinbase as individual tx"),
+ return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"),
REJECT_INVALID, "coinbase");
// Rather not work on nonstandard transactions (unless -testnet/-regtest)
string reason;
if (Params().RequireStandard() && !IsStandardTx(tx, reason))
return state.DoS(0,
- error("AcceptToMemoryPool : nonstandard transaction: %s", reason),
+ error("AcceptToMemoryPool: nonstandard transaction: %s", reason),
REJECT_NONSTANDARD, reason);
+ // Only accept nLockTime-using transactions that can be mined in the next
+ // block; we don't want our mempool filled up with transactions that can't
+ // be mined yet.
+ //
+ // However, IsFinalTx() is confusing... Without arguments, it uses
+ // chainActive.Height() to evaluate nLockTime; when a block is accepted,
+ // chainActive.Height() is set to the value of nHeight in the block.
+ // However, when IsFinalTx() is called within CBlock::AcceptBlock(), the
+ // height of the block *being* evaluated is what is used. Thus if we want
+ // to know if a transaction can be part of the *next* block, we need to
+ // call IsFinalTx() with one more than chainActive.Height().
+ //
+ // Timestamps on the other hand don't get any special treatment, because we
+ // can't know what timestamp the next block will have, and there aren't
+ // timestamp applications where it matters.
+ if (!IsFinalTx(tx, chainActive.Height() + 1))
+ return state.DoS(0,
+ error("AcceptToMemoryPool: non-final"),
+ REJECT_NONSTANDARD, "non-final");
+
// is it already in the memory pool?
uint256 hash = tx.GetHash();
if (pool.exists(hash))
// are the actual inputs available?
if (!view.HaveInputs(tx))
- return state.Invalid(error("AcceptToMemoryPool : inputs already spent"),
+ return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),
REJECT_DUPLICATE, "bad-txns-inputs-spent");
// Bring the best block into scope
// Check for non-standard pay-to-script-hash in inputs
if (Params().RequireStandard() && !AreInputsStandard(tx, view))
- return error("AcceptToMemoryPool: : nonstandard transaction input");
+ return error("AcceptToMemoryPool: nonstandard transaction input");
// Check that the transaction doesn't have an excessive number of
// sigops, making it impossible to mine. Since the coinbase transaction
- // itself can contain sigops MAX_TX_SIGOPS is less than
+ // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
// MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
// merely non-standard transaction.
unsigned int nSigOps = GetLegacySigOpCount(tx);
nSigOps += GetP2SHSigOpCount(tx, view);
- if (nSigOps > MAX_TX_SIGOPS)
+ if (nSigOps > MAX_STANDARD_TX_SIGOPS)
return state.DoS(0,
- error("AcceptToMemoryPool : too many sigops %s, %d > %d",
- hash.ToString(), nSigOps, MAX_TX_SIGOPS),
+ error("AcceptToMemoryPool: too many sigops %s, %d > %d",
+ hash.ToString(), nSigOps, MAX_STANDARD_TX_SIGOPS),
REJECT_NONSTANDARD, "bad-txns-too-many-sigops");
CAmount nValueOut = tx.GetValueOut();
// Don't accept it if it can't get into a block
CAmount txMinFee = GetMinRelayFee(tx, nSize, true);
if (fLimitFree && nFees < txMinFee)
- return state.DoS(0, error("AcceptToMemoryPool : not enough fees %s, %d < %d",
+ return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",
hash.ToString(), nFees, txMinFee),
REJECT_INSUFFICIENTFEE, "insufficient fee");
- // Continuously rate-limit free (really, very-low-fee)transactions
+ // Require that free transactions have sufficient priority to be mined in the next block.
+ if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
+ return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
+ }
+
+ // Continuously rate-limit free (really, very-low-fee) transactions
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
// be annoying or make others' transactions take longer to confirm.
if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
// -limitfreerelay unit is thousand-bytes-per-minute
// At default rate it would take over a month to fill 1GB
if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
- return state.DoS(0, error("AcceptToMemoryPool : free transaction rejected by rate limiter"),
- REJECT_INSUFFICIENTFEE, "insufficient priority");
+ return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"),
+ REJECT_INSUFFICIENTFEE, "rate limited free transaction");
LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
dFreeCount += nSize;
}
- if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000)
- return error("AcceptToMemoryPool: : insane fees %s, %d > %d",
+ if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000)
+ return error("AcceptToMemoryPool: absurdly high fees %s, %d > %d",
hash.ToString(),
nFees, ::minRelayTxFee.GetFee(nSize) * 10000);
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true))
{
- return error("AcceptToMemoryPool: : ConnectInputs failed %s", hash.ToString());
+ return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString());
+ }
+
+ // Check again against just the consensus-critical mandatory script
+ // verification flags, in case of bugs in the standard flags that cause
+ // transactions to pass as valid when they're actually invalid. For
+ // instance the STRICTENC flag was incorrectly allowing certain
+ // CHECKSIG NOT scripts to pass, even though they were invalid.
+ //
+ // There is a similar check in CreateNewBlock() to prevent creating
+ // invalid blocks, however allowing such transactions into the mempool
+ // can be exploited as a DoS attack.
+ if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
+ {
+ return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
}
+
// Store transaction in memory
pool.addUnchecked(hash, entry);
}
return true;
}
-// Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock
+/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
{
CBlockIndex *pindexSlow = NULL;
CDiskTxPos postx;
if (pblocktree->ReadTxIndex(hash, postx)) {
CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
+ if (file.IsNull())
+ return error("%s: OpenBlockFile failed", __func__);
CBlockHeader header;
try {
file >> header;
fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
file >> txOut;
- } catch (std::exception &e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ } catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
hashBlock = header.GetHash();
if (txOut.GetHash() != hash)
- return error("%s : txid mismatch", __func__);
+ return error("%s: txid mismatch", __func__);
return true;
}
}
// Open history file to append
CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
if (fileout.IsNull())
- return error("WriteBlockToDisk : OpenBlockFile failed");
+ return error("WriteBlockToDisk: OpenBlockFile failed");
// Write index header
unsigned int nSize = fileout.GetSerializeSize(block);
// Write block
long fileOutPos = ftell(fileout.Get());
if (fileOutPos < 0)
- return error("WriteBlockToDisk : ftell failed");
+ return error("WriteBlockToDisk: ftell failed");
pos.nPos = (unsigned int)fileOutPos;
fileout << block;
- // Flush stdio buffers and commit to disk before returning
- fflush(fileout.Get());
- if (!IsInitialBlockDownload())
- FileCommit(fileout.Get());
-
return true;
}
// Open history file to read
CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
if (filein.IsNull())
- return error("ReadBlockFromDisk : OpenBlockFile failed");
+ return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
// Read block
try {
filein >> block;
}
- catch (std::exception &e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
}
// Check the header
if (!CheckProofOfWork(block.GetHash(), block.nBits))
- return error("ReadBlockFromDisk : Errors in block header");
+ return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
return true;
}
if (!ReadBlockFromDisk(block, pindex->GetBlockPos()))
return false;
if (block.GetHash() != pindex->GetBlockHash())
- return error("ReadBlockFromDisk(CBlock&, CBlockIndex*) : GetHash() doesn't match index");
+ return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
+ pindex->ToString(), pindex->GetBlockPos().ToString());
return true;
}
CAmount GetBlockValue(int nHeight, const CAmount& nFees)
{
- int64_t nSubsidy = 50 * COIN;
+ CAmount nSubsidy = 50 * COIN;
int halvings = nHeight / Params().SubsidyHalvingInterval();
// Force block reward to zero when right shift is undefined.
LOCK(cs_main);
if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate())
return true;
- static int64_t nLastUpdate;
- static CBlockIndex* pindexLastBest;
- if (chainActive.Tip() != pindexLastBest)
- {
- pindexLastBest = chainActive.Tip();
- nLastUpdate = GetTime();
- }
- return (GetTime() - nLastUpdate < 10 &&
- chainActive.Tip()->GetBlockTime() < GetTime() - 24 * 60 * 60);
+ static bool lockIBDState = false;
+ if (lockIBDState)
+ return false;
+ bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 ||
+ pindexBestHeader->GetBlockTime() < GetTime() - 24 * 60 * 60);
+ if (!state)
+ lockIBDState = true;
+ return state;
}
bool fLargeWorkForkFound = false;
if (state.IsInvalid(nDoS)) {
std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
if (it != mapBlockSource.end() && State(it->second)) {
- CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason(), pindex->GetBlockHash()};
+ CBlockReject reject = {state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
State(it->second)->rejects.push_back(reject);
if (nDoS > 0)
Misbehaving(it->second, nDoS);
}
if (!state.CorruptionPossible()) {
pindex->nStatus |= BLOCK_FAILED_VALID;
- pblocktree->WriteBlockIndex(CDiskBlockIndex(pindex));
+ setDirtyBlockIndex.insert(pindex);
setBlockIndexCandidates.erase(pindex);
InvalidChainFound(pindex);
}
if (!tx.IsCoinBase()) {
txundo.vprevout.reserve(tx.vin.size());
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
- txundo.vprevout.push_back(CTxInUndo());
- bool ret = inputs.ModifyCoins(txin.prevout.hash)->Spend(txin.prevout, txundo.vprevout.back());
- assert(ret);
+ CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
+ unsigned nPos = txin.prevout.n;
+
+ if (nPos >= coins->vout.size() || coins->vout[nPos].IsNull())
+ assert(false);
+ // mark an outpoint spent, and construct undo information
+ txundo.vprevout.push_back(CTxInUndo(coins->vout[nPos]));
+ coins->Spend(nPos);
+ if (coins->vout.size() == 0) {
+ CTxInUndo& undo = txundo.vprevout.back();
+ undo.nHeight = coins->nHeight;
+ undo.fCoinBase = coins->fCoinBase;
+ undo.nVersion = coins->nVersion;
+ }
}
}
inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight);
}
-bool CScriptCheck::operator()() const {
+void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight)
+{
+ CTxUndo txundo;
+ UpdateCoins(tx, state, inputs, txundo, nHeight);
+}
+
+bool CScriptCheck::operator()() {
const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
- if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingSignatureChecker(*ptxTo, nIn, cacheStore)))
- return error("CScriptCheck() : %s:%d VerifySignature failed", ptxTo->GetHash().ToString(), nIn);
+ if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) {
+ return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
+ }
return true;
}
// This doesn't trigger the DoS code on purpose; if it did, it would make it easier
// for an attacker to attempt to split the network.
if (!inputs.HaveInputs(tx))
- return state.Invalid(error("CheckInputs() : %s inputs unavailable", tx.GetHash().ToString()));
+ return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString()));
// While checking, GetBestBlock() refers to the parent block.
// This is also true for mempool checks.
if (coins->IsCoinBase()) {
if (nSpendHeight - coins->nHeight < COINBASE_MATURITY)
return state.Invalid(
- error("CheckInputs() : tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
+ error("CheckInputs(): tried to spend coinbase at depth %d", nSpendHeight - coins->nHeight),
REJECT_INVALID, "bad-txns-premature-spend-of-coinbase");
}
// Check for negative or overflow input values
nValueIn += coins->vout[prevout.n].nValue;
if (!MoneyRange(coins->vout[prevout.n].nValue) || !MoneyRange(nValueIn))
- return state.DoS(100, error("CheckInputs() : txin values out of range"),
+ return state.DoS(100, error("CheckInputs(): txin values out of range"),
REJECT_INVALID, "bad-txns-inputvalues-outofrange");
}
if (nValueIn < tx.GetValueOut())
- return state.DoS(100, error("CheckInputs() : %s value in (%s) < value out (%s)",
+ return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s)",
tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())),
REJECT_INVALID, "bad-txns-in-belowout");
// Tally transaction fees
CAmount nTxFee = nValueIn - tx.GetValueOut();
if (nTxFee < 0)
- return state.DoS(100, error("CheckInputs() : %s nTxFee < 0", tx.GetHash().ToString()),
+ return state.DoS(100, error("CheckInputs(): %s nTxFee < 0", tx.GetHash().ToString()),
REJECT_INVALID, "bad-txns-fee-negative");
nFees += nTxFee;
if (!MoneyRange(nFees))
- return state.DoS(100, error("CheckInputs() : nFees out of range"),
+ return state.DoS(100, error("CheckInputs(): nFees out of range"),
REJECT_INVALID, "bad-txns-fee-outofrange");
// The first loop above does all the inexpensive checks.
CScriptCheck check(*coins, tx, i,
flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore);
if (check())
- return state.Invalid(false, REJECT_NONSTANDARD, "non-mandatory-script-verify-flag");
+ return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
}
// Failures of other flags indicate a transaction that is
// invalid in new blocks, e.g. a invalid P2SH. We DoS ban
// as to the correct behavior - we may want to continue
// peering with non-upgraded nodes even after a soft-fork
// super-majority vote has passed.
- return state.DoS(100,false, REJECT_INVALID, "mandatory-script-verify-flag-failed");
+ return state.DoS(100,false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
}
}
}
return true;
}
+namespace {
+bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock)
+{
+ // Open history file to append
+ CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
+ if (fileout.IsNull())
+ return error("%s: OpenUndoFile failed", __func__);
+
+ // Write index header
+ unsigned int nSize = fileout.GetSerializeSize(blockundo);
+ fileout << FLATDATA(Params().MessageStart()) << nSize;
+
+ // Write undo data
+ long fileOutPos = ftell(fileout.Get());
+ if (fileOutPos < 0)
+ return error("%s: ftell failed", __func__);
+ pos.nPos = (unsigned int)fileOutPos;
+ fileout << blockundo;
+
+ // calculate & write checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << blockundo;
+ fileout << hasher.GetHash();
+
+ return true;
+}
+
+bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uint256& hashBlock)
+{
+ // Open history file to read
+ CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
+ if (filein.IsNull())
+ return error("%s: OpenBlockFile failed", __func__);
+
+ // Read block
+ uint256 hashChecksum;
+ try {
+ filein >> blockundo;
+ filein >> hashChecksum;
+ }
+ catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
+ }
+
+ // Verify checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << blockundo;
+ if (hashChecksum != hasher.GetHash())
+ return error("%s: Checksum mismatch", __func__);
+
+ return true;
+}
+
+} // anon namespace
+
+/**
+ * Apply the undo operation of a CTxInUndo to the given chain state.
+ * @param undo The undo object.
+ * @param view The coins view to which to apply the changes.
+ * @param out The out point that corresponds to the tx input.
+ * @return True on success.
+ */
+static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
+{
+ bool fClean = true;
+
+ CCoinsModifier coins = view.ModifyCoins(out.hash);
+ if (undo.nHeight != 0) {
+ // undo data contains height: this is the last output of the prevout tx being spent
+ if (!coins->IsPruned())
+ fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
+ coins->Clear();
+ coins->fCoinBase = undo.fCoinBase;
+ coins->nHeight = undo.nHeight;
+ coins->nVersion = undo.nVersion;
+ } else {
+ if (coins->IsPruned())
+ fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
+ }
+ if (coins->IsAvailable(out.n))
+ fClean = fClean && error("%s: undo data overwriting existing output", __func__);
+ if (coins->vout.size() < out.n+1)
+ coins->vout.resize(out.n+1);
+ coins->vout[out.n] = undo.txout;
+
+ return fClean;
+}
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
{
CBlockUndo blockUndo;
CDiskBlockPos pos = pindex->GetUndoPos();
if (pos.IsNull())
- return error("DisconnectBlock() : no undo data available");
- if (!blockUndo.ReadFromDisk(pos, pindex->pprev->GetBlockHash()))
- return error("DisconnectBlock() : failure reading undo data");
+ return error("DisconnectBlock(): no undo data available");
+ if (!UndoReadFromDisk(blockUndo, pos, pindex->pprev->GetBlockHash()))
+ return error("DisconnectBlock(): failure reading undo data");
if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
- return error("DisconnectBlock() : block and undo data inconsistent");
+ return error("DisconnectBlock(): block and undo data inconsistent");
// undo transactions in reverse order
for (int i = block.vtx.size() - 1; i >= 0; i--) {
uint256 hash = tx.GetHash();
// Check that all outputs are available and match the outputs in the block itself
- // exactly. Note that transactions with only provably unspendable outputs won't
- // have outputs available even in the block itself, so we handle that case
- // specially with outsEmpty.
+ // exactly.
{
- CCoins outsEmpty;
CCoinsModifier outs = view.ModifyCoins(hash);
outs->ClearUnspendable();
if (outsBlock.nVersion < 0)
outs->nVersion = outsBlock.nVersion;
if (*outs != outsBlock)
- fClean = fClean && error("DisconnectBlock() : added transaction mismatch? database corrupted");
+ fClean = fClean && error("DisconnectBlock(): added transaction mismatch? database corrupted");
// remove outputs
outs->Clear();
if (i > 0) { // not coinbases
const CTxUndo &txundo = blockUndo.vtxundo[i-1];
if (txundo.vprevout.size() != tx.vin.size())
- return error("DisconnectBlock() : transaction and undo data inconsistent");
+ return error("DisconnectBlock(): transaction and undo data inconsistent");
for (unsigned int j = tx.vin.size(); j-- > 0;) {
const COutPoint &out = tx.vin[j].prevout;
const CTxInUndo &undo = txundo.vprevout[j];
- CCoinsModifier coins = view.ModifyCoins(out.hash);
- if (undo.nHeight != 0) {
- // undo data contains height: this is the last output of the prevout tx being spent
- if (!coins->IsPruned())
- fClean = fClean && error("DisconnectBlock() : undo data overwriting existing transaction");
- coins->Clear();
- coins->fCoinBase = undo.fCoinBase;
- coins->nHeight = undo.nHeight;
- coins->nVersion = undo.nVersion;
- } else {
- if (coins->IsPruned())
- fClean = fClean && error("DisconnectBlock() : undo data adding output to missing transaction");
- }
- if (coins->IsAvailable(out.n))
- fClean = fClean && error("DisconnectBlock() : undo data overwriting existing output");
- if (coins->vout.size() < out.n+1)
- coins->vout.resize(out.n+1);
- coins->vout[out.n] = undo.txout;
+ if (!ApplyTxInUndo(undo, view, out))
+ fClean = false;
}
}
}
if (pfClean) {
*pfClean = fClean;
return true;
- } else {
- return fClean;
}
+
+ return fClean;
}
void static FlushBlockFile(bool fFinalize = false)
return false;
// verify that the view's current state corresponds to the previous block
- uint256 hashPrevBlock = pindex->pprev == NULL ? uint256(0) : pindex->pprev->GetBlockHash();
+ uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
assert(hashPrevBlock == view.GetBestBlock());
// Special case for the genesis block, skipping connection of its transactions
// (its coinbase is unspendable)
if (block.GetHash() == Params().HashGenesisBlock()) {
- view.SetBestBlock(pindex->GetBlockHash());
+ if (!fJustCheck)
+ view.SetBestBlock(pindex->GetBlockHash());
return true;
}
// two in the chain that violate it. This prevents exploiting the issue against nodes in their
// initial block download.
bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash.
- !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
- (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
+ !((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
+ (pindex->nHeight==91880 && pindex->GetBlockHash() == uint256S("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
if (fEnforceBIP30) {
BOOST_FOREACH(const CTransaction& tx, block.vtx) {
const CCoins* coins = view.AccessCoins(tx.GetHash());
if (coins && !coins->IsPruned())
- return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"),
+ return state.DoS(100, error("ConnectBlock(): tried to overwrite transaction"),
REJECT_INVALID, "bad-txns-BIP30");
}
}
unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE;
+ // Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks, when 75% of the network has upgraded:
+ if (block.nVersion >= 3 && IsSuperMajority(3, pindex->pprev, Params().EnforceBlockUpgradeMajority())) {
+ flags |= SCRIPT_VERIFY_DERSIG;
+ }
+
CBlockUndo blockundo;
CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
nInputs += tx.vin.size();
nSigOps += GetLegacySigOpCount(tx);
if (nSigOps > MAX_BLOCK_SIGOPS)
- return state.DoS(100, error("ConnectBlock() : too many sigops"),
+ return state.DoS(100, error("ConnectBlock(): too many sigops"),
REJECT_INVALID, "bad-blk-sigops");
if (!tx.IsCoinBase())
{
if (!view.HaveInputs(tx))
- return state.DoS(100, error("ConnectBlock() : inputs missing/spent"),
+ return state.DoS(100, error("ConnectBlock(): inputs missing/spent"),
REJECT_INVALID, "bad-txns-inputs-missingorspent");
if (fStrictPayToScriptHash)
// an incredibly-expensive-to-validate block.
nSigOps += GetP2SHSigOpCount(tx, view);
if (nSigOps > MAX_BLOCK_SIGOPS)
- return state.DoS(100, error("ConnectBlock() : too many sigops"),
+ return state.DoS(100, error("ConnectBlock(): too many sigops"),
REJECT_INVALID, "bad-blk-sigops");
}
if (block.vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees))
return state.DoS(100,
- error("ConnectBlock() : coinbase pays too much (actual=%d vs limit=%d)",
+ error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
block.vtx[0].GetValueOut(), GetBlockValue(pindex->nHeight, nFees)),
REJECT_INVALID, "bad-cb-amount");
if (pindex->GetUndoPos().IsNull()) {
CDiskBlockPos pos;
if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
- return error("ConnectBlock() : FindUndoPos failed");
- if (!blockundo.WriteToDisk(pos, pindex->pprev->GetBlockHash()))
+ return error("ConnectBlock(): FindUndoPos failed");
+ if (!UndoWriteToDisk(blockundo, pos, pindex->pprev->GetBlockHash()))
return state.Abort("Failed to write undo data");
// update nUndoPos in block index
}
pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
-
- CDiskBlockIndex blockindex(pindex);
- if (!pblocktree->WriteBlockIndex(blockindex))
- return state.Abort("Failed to write block index");
+ setDirtyBlockIndex.insert(pindex);
}
if (fTxIndex)
return true;
}
-// Update the on-disk chain state.
-bool static WriteChainState(CValidationState &state, bool forceWrite=false) {
+enum FlushStateMode {
+ FLUSH_STATE_IF_NEEDED,
+ FLUSH_STATE_PERIODIC,
+ FLUSH_STATE_ALWAYS
+};
+
+/**
+ * Update the on-disk chain state.
+ * The caches and indexes are flushed if either they're too large, forceWrite is set, or
+ * fast is not set and it's been a while since the last write.
+ */
+bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
+ LOCK(cs_main);
static int64_t nLastWrite = 0;
- if (forceWrite || pcoinsTip->GetCacheSize() > nCoinCacheSize || (!IsInitialBlockDownload() && GetTimeMicros() > nLastWrite + 600*1000000)) {
+ try {
+ if ((mode == FLUSH_STATE_ALWAYS) ||
+ ((mode == FLUSH_STATE_PERIODIC || mode == FLUSH_STATE_IF_NEEDED) && pcoinsTip->GetCacheSize() > nCoinCacheSize) ||
+ (mode == FLUSH_STATE_PERIODIC && GetTimeMicros() > nLastWrite + DATABASE_WRITE_INTERVAL * 1000000)) {
// Typical CCoins structures on disk are around 100 bytes in size.
// Pushing a new one to the database can cause it to be written
// twice (once in the log, and once in the tables). This is already
// overwrite one. Still, use a conservative safety factor of 2.
if (!CheckDiskSpace(100 * 2 * 2 * pcoinsTip->GetCacheSize()))
return state.Error("out of disk space");
+ // First make sure all block and undo data is flushed to disk.
FlushBlockFile();
- pblocktree->Sync();
+ // Then update all block file information (which may refer to block and undo files).
+ {
+ std::vector<std::pair<int, const CBlockFileInfo*> > vFiles;
+ vFiles.reserve(setDirtyFileInfo.size());
+ for (set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
+ vFiles.push_back(make_pair(*it, &vinfoBlockFile[*it]));
+ setDirtyFileInfo.erase(it++);
+ }
+ std::vector<const CBlockIndex*> vBlocks;
+ vBlocks.reserve(setDirtyBlockIndex.size());
+ for (set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
+ vBlocks.push_back(*it);
+ setDirtyBlockIndex.erase(it++);
+ }
+ if (!pblocktree->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
+ return state.Abort("Files to write to block index database");
+ }
+ }
+ // Finally flush the chainstate (which may refer to block index entries).
if (!pcoinsTip->Flush())
return state.Abort("Failed to write to coin database");
+ // Update best block in wallet (so we can detect restored wallets).
+ if (mode != FLUSH_STATE_IF_NEEDED) {
+ g_signals.SetBestChain(chainActive.GetLocator());
+ }
nLastWrite = GetTimeMicros();
}
+ } catch (const std::runtime_error& e) {
+ return state.Abort(std::string("System error while flushing: ") + e.what());
+ }
return true;
}
-// Update chainActive and related internal data structures.
+void FlushStateToDisk() {
+ CValidationState state;
+ FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
+}
+
+/** Update chainActive and related internal data structures. */
void static UpdateTip(CBlockIndex *pindexNew) {
chainActive.SetTip(pindexNew);
}
}
-// Disconnect chainActive's tip.
+/** Disconnect chainActive's tip. */
bool static DisconnectTip(CValidationState &state) {
CBlockIndex *pindexDelete = chainActive.Tip();
assert(pindexDelete);
{
CCoinsViewCache view(pcoinsTip);
if (!DisconnectBlock(block, state, pindexDelete, view))
- return error("DisconnectTip() : DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
+ return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
assert(view.Flush());
}
LogPrint("bench", "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * 0.001);
// Write the chain state to disk, if necessary.
- if (!WriteChainState(state))
+ if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
return false;
// Resurrect mempool transactions from the disconnected block.
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
// ignore validation errors in resurrected transactions
list<CTransaction> removed;
CValidationState stateDummy;
- if (!tx.IsCoinBase())
- if (!AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
- mempool.remove(tx, removed, true);
+ if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
+ mempool.remove(tx, removed, true);
}
+ mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight);
mempool.check(pcoinsTip);
// Update chainActive and related variables.
UpdateTip(pindexDelete->pprev);
static int64_t nTimeChainState = 0;
static int64_t nTimePostConnect = 0;
-// Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
-// corresponding to pindexNew, to bypass loading it again from disk.
+/**
+ * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
+ * corresponding to pindexNew, to bypass loading it again from disk.
+ */
bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) {
assert(pindexNew->pprev == chainActive.Tip());
mempool.check(pcoinsTip);
if (!rv) {
if (state.IsInvalid())
InvalidBlockFound(pindexNew, state);
- return error("ConnectTip() : ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
+ return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
}
mapBlockSource.erase(inv.hash);
nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
LogPrint("bench", " - Flush: %.2fms [%.2fs]\n", (nTime4 - nTime3) * 0.001, nTimeFlush * 0.000001);
// Write the chain state to disk, if necessary.
- if (!WriteChainState(state))
+ if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED))
return false;
int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
SyncWithWallets(tx, pblock);
}
- // Update best block in wallet (so we can detect restored wallets)
- // Emit this signal after the SyncWithWallets signals as the wallet relies on that everything up to this point has been synced
- if ((chainActive.Height() % 20160) == 0 || ((chainActive.Height() % 144) == 0 && !IsInitialBlockDownload()))
- g_signals.SetBestChain(chainActive.GetLocator());
int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
return true;
}
-// Return the tip of the chain with the most work in it, that isn't
-// known to be invalid (it's however far from certain to be valid).
+/**
+ * Return the tip of the chain with the most work in it, that isn't
+ * known to be invalid (it's however far from certain to be valid).
+ */
static CBlockIndex* FindMostWorkChain() {
do {
CBlockIndex *pindexNew = NULL;
} while(true);
}
-// Try to make some progress towards making pindexMostWork the active block.
-// pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
+/** Delete all entries in setBlockIndexCandidates that are worse than the current tip. */
+static void PruneBlockIndexCandidates() {
+ // Note that we can't delete the current block itself, as we may need to return to it later in case a
+ // reorganization to a better block fails.
+ std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
+ while (it != setBlockIndexCandidates.end() && setBlockIndexCandidates.value_comp()(*it, chainActive.Tip())) {
+ setBlockIndexCandidates.erase(it++);
+ }
+ // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
+ assert(!setBlockIndexCandidates.empty());
+}
+
+/**
+ * Try to make some progress towards making pindexMostWork the active block.
+ * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
+ */
static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, CBlock *pblock) {
AssertLockHeld(cs_main);
bool fInvalidFound = false;
return false;
}
} else {
- // Delete all entries in setBlockIndexCandidates that are worse than our new current block.
- // Note that we can't delete the current block itself, as we may need to return to it later in case a
- // reorganization to a better block fails.
- std::set<CBlockIndex*, CBlockIndexWorkComparator>::iterator it = setBlockIndexCandidates.begin();
- while (setBlockIndexCandidates.value_comp()(*it, chainActive.Tip())) {
- setBlockIndexCandidates.erase(it++);
- }
- // Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
- assert(!setBlockIndexCandidates.empty());
+ PruneBlockIndexCandidates();
if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) {
// We're in a better position than we were. Return temporarily to release the lock.
fContinue = false;
else
CheckForkWarningConditions();
- if (!pblocktree->Flush())
- return state.Abort("Failed to sync block index");
-
return true;
}
-// Make the best chain active, in multiple steps. The result is either failure
-// or an activated best chain. pblock is either NULL or a pointer to a block
-// that is already loaded (to avoid loading it again from disk).
+/**
+ * Make the best chain active, in multiple steps. The result is either failure
+ * or an activated best chain. pblock is either NULL or a pointer to a block
+ * that is already loaded (to avoid loading it again from disk).
+ */
bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
CBlockIndex *pindexNewTip = NULL;
CBlockIndex *pindexMostWork = NULL;
if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
}
-
+ // Notify external listeners about the new tip.
uiInterface.NotifyBlockTip(hashNewTip);
}
} while(pindexMostWork != chainActive.Tip());
+ // Write changes periodically to disk, after relay.
+ if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
+ AssertLockHeld(cs_main);
+
+ // Mark the block itself as invalid.
+ pindex->nStatus |= BLOCK_FAILED_VALID;
+ setDirtyBlockIndex.insert(pindex);
+ setBlockIndexCandidates.erase(pindex);
+
+ while (chainActive.Contains(pindex)) {
+ CBlockIndex *pindexWalk = chainActive.Tip();
+ pindexWalk->nStatus |= BLOCK_FAILED_CHILD;
+ setDirtyBlockIndex.insert(pindexWalk);
+ setBlockIndexCandidates.erase(pindexWalk);
+ // ActivateBestChain considers blocks already in chainActive
+ // unconditionally valid already, so force disconnect away from it.
+ if (!DisconnectTip(state)) {
+ return false;
+ }
+ }
+
+ // The resulting new best tip may not be in setBlockIndexCandidates anymore, so
+ // add them again.
+ BlockMap::iterator it = mapBlockIndex.begin();
+ while (it != mapBlockIndex.end()) {
+ if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
+ setBlockIndexCandidates.insert(it->second);
+ }
+ it++;
+ }
+
+ InvalidChainFound(pindex);
+ return true;
+}
+
+bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex) {
+ AssertLockHeld(cs_main);
+
+ int nHeight = pindex->nHeight;
+
+ // Remove the invalidity flag from this block and all its descendants.
+ BlockMap::iterator it = mapBlockIndex.begin();
+ while (it != mapBlockIndex.end()) {
+ if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
+ it->second->nStatus &= ~BLOCK_FAILED_MASK;
+ setDirtyBlockIndex.insert(it->second);
+ if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
+ setBlockIndexCandidates.insert(it->second);
+ }
+ if (it->second == pindexBestInvalid) {
+ // Reset invalid block marker if it was pointing to one of those.
+ pindexBestInvalid = NULL;
+ }
+ }
+ it++;
+ }
+
+ // Remove the invalidity flag from all ancestors too.
+ while (pindex != NULL) {
+ if (pindex->nStatus & BLOCK_FAILED_MASK) {
+ pindex->nStatus &= ~BLOCK_FAILED_MASK;
+ setDirtyBlockIndex.insert(pindex);
+ }
+ pindex = pindex->pprev;
+ }
return true;
}
if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork)
pindexBestHeader = pindexNew;
- // Ok if it fails, we'll download the header again next time.
- pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew));
+ setDirtyBlockIndex.insert(pindexNew);
return pindexNew;
}
-// Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS).
+/** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
{
pindexNew->nTx = block.vtx.size();
LOCK(cs_nBlockSequenceId);
pindexNew->nSequenceId = nBlockSequenceId++;
}
+ setDirtyBlockIndex.insert(pindexNew);
if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
// If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
range.first++;
mapBlocksUnlinked.erase(it);
}
- if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindex)))
- return state.Abort("Failed to write block index");
}
} else {
if (pindexNew->pprev && pindexNew->pprev->IsValid(BLOCK_VALID_TREE)) {
mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew));
}
- if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew)))
- return state.Abort("Failed to write block index");
}
return true;
bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false)
{
- bool fUpdatedLast = false;
-
LOCK(cs_LastBlockFile);
unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
if (vinfoBlockFile.size() <= nFile) {
vinfoBlockFile.resize(nFile + 1);
}
- fUpdatedLast = true;
}
pos.nFile = nFile;
pos.nPos = vinfoBlockFile[nFile].nSize;
}
nLastBlockFile = nFile;
- vinfoBlockFile[nFile].nSize += nAddSize;
vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
+ if (fKnown)
+ vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
+ else
+ vinfoBlockFile[nFile].nSize += nAddSize;
if (!fKnown) {
unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
}
}
- if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, vinfoBlockFile[nFile]))
- return state.Abort("Failed to write file info");
- if (fUpdatedLast)
- pblocktree->WriteLastBlockFile(nLastBlockFile);
-
+ setDirtyFileInfo.insert(nFile);
return true;
}
unsigned int nNewSize;
pos.nPos = vinfoBlockFile[nFile].nUndoSize;
nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize;
- if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, vinfoBlockFile[nLastBlockFile])) {
- return state.Abort("Failed to write block info");
- }
+ setDirtyFileInfo.insert(nFile);
unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
unsigned int nNewChunks = (nNewSize + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
{
// Check proof of work matches claimed amount
if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits))
- return state.DoS(50, error("CheckBlockHeader() : proof of work failed"),
+ return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),
REJECT_INVALID, "high-hash");
// Check timestamp
if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
- return state.Invalid(error("CheckBlockHeader() : block timestamp too far in the future"),
+ return state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),
REJECT_INVALID, "time-too-new");
return true;
bool mutated;
uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
if (block.hashMerkleRoot != hashMerkleRoot2)
- return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"),
+ return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"),
REJECT_INVALID, "bad-txnmrklroot", true);
// Check for merkle tree malleability (CVE-2012-2459): repeating sequences
// of transactions in a block without affecting the merkle root of a block,
// while still invalidating it.
if (mutated)
- return state.DoS(100, error("CheckBlock() : duplicate transaction"),
+ return state.DoS(100, error("CheckBlock(): duplicate transaction"),
REJECT_INVALID, "bad-txns-duplicate", true);
}
// Size limits
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
- return state.DoS(100, error("CheckBlock() : size limits failed"),
+ return state.DoS(100, error("CheckBlock(): size limits failed"),
REJECT_INVALID, "bad-blk-length");
// First transaction must be coinbase, the rest must not be
if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
- return state.DoS(100, error("CheckBlock() : first tx is not coinbase"),
+ return state.DoS(100, error("CheckBlock(): first tx is not coinbase"),
REJECT_INVALID, "bad-cb-missing");
for (unsigned int i = 1; i < block.vtx.size(); i++)
if (block.vtx[i].IsCoinBase())
- return state.DoS(100, error("CheckBlock() : more than one coinbase"),
+ return state.DoS(100, error("CheckBlock(): more than one coinbase"),
REJECT_INVALID, "bad-cb-multiple");
// Check transactions
BOOST_FOREACH(const CTransaction& tx, block.vtx)
if (!CheckTransaction(tx, state))
- return error("CheckBlock() : CheckTransaction failed");
+ return error("CheckBlock(): CheckTransaction failed");
unsigned int nSigOps = 0;
BOOST_FOREACH(const CTransaction& tx, block.vtx)
nSigOps += GetLegacySigOpCount(tx);
}
if (nSigOps > MAX_BLOCK_SIGOPS)
- return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"),
+ return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"),
REJECT_INVALID, "bad-blk-sigops", true);
return true;
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__),
+ if ((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__),
+ 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),
+ 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));
+ 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()))
+ if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority()))
{
- return state.Invalid(error("%s : rejected nVersion=1 block", __func__),
+ return state.Invalid(error("%s: rejected nVersion=1 block", __func__),
+ REJECT_OBSOLETE, "bad-version");
+ }
+
+ // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded:
+ if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, Params().RejectBlockOutdatedMajority()))
+ {
+ return state.Invalid(error("%s : rejected nVersion=2 block", __func__),
REJECT_OBSOLETE, "bad-version");
}
// 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");
+ 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()))
+ if (block.nVersion >= 2 && 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 state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height");
}
}
if (ppindex)
*ppindex = pindex;
if (pindex->nStatus & BLOCK_FAILED_MASK)
- return state.Invalid(error("%s : block is marked invalid", __func__), 0, "duplicate");
+ return state.Invalid(error("%s: block is marked invalid", __func__), 0, "duplicate");
return true;
}
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");
+ return state.DoS(10, error("%s: prev block not found", __func__), 0, "bad-prevblk");
pindexPrev = (*mi).second;
+ if (pindexPrev->nStatus & BLOCK_FAILED_MASK)
+ return state.DoS(100, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
}
if (!ContextualCheckBlockHeader(block, state, pindexPrev))
if (pindex->nStatus & BLOCK_HAVE_DATA) {
// TODO: deal better with duplicate blocks.
- // return state.DoS(20, error("AcceptBlock() : already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate");
+ // return state.DoS(20, error("AcceptBlock(): already have block %d %s", pindex->nHeight, pindex->GetBlockHash().ToString()), REJECT_DUPLICATE, "duplicate");
return true;
}
if ((!CheckBlock(block, state)) || !ContextualCheckBlock(block, state, pindex->pprev)) {
if (state.IsInvalid() && !state.CorruptionPossible()) {
pindex->nStatus |= BLOCK_FAILED_VALID;
+ setDirtyBlockIndex.insert(pindex);
}
return false;
}
if (dbp != NULL)
blockPos = *dbp;
if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL))
- return error("AcceptBlock() : FindBlockPos failed");
+ return error("AcceptBlock(): FindBlockPos failed");
if (dbp == NULL)
if (!WriteBlockToDisk(block, blockPos))
return state.Abort("Failed to write block");
if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
- return error("AcceptBlock() : ReceivedBlockTransactions failed");
- } catch(std::runtime_error &e) {
+ return error("AcceptBlock(): ReceivedBlockTransactions failed");
+ } catch (const std::runtime_error& e) {
return state.Abort(std::string("System error: ") + e.what());
}
return true;
}
-bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired)
+static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired)
{
unsigned int nToCheck = Params().ToCheckBlockUpgradeMajority();
unsigned int nFound = 0;
return (nFound >= nRequired);
}
-/** Turn the lowest '1' bit in the binary representation of a number into a '0'. */
-int static inline InvertLowestOne(int n) { return n & (n - 1); }
-
-/** Compute what height to jump back to with the CBlockIndex::pskip pointer. */
-int static inline GetSkipHeight(int height) {
- if (height < 2)
- return 0;
-
- // Determine which height to jump back to. Any number strictly lower than height is acceptable,
- // but the following expression seems to perform well in simulations (max 110 steps to go back
- // up to 2**18 blocks).
- return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 : InvertLowestOne(height);
-}
-
-CBlockIndex* CBlockIndex::GetAncestor(int height)
-{
- if (height > nHeight || height < 0)
- return NULL;
-
- CBlockIndex* pindexWalk = this;
- int heightWalk = nHeight;
- while (heightWalk > height) {
- int heightSkip = GetSkipHeight(heightWalk);
- int heightSkipPrev = GetSkipHeight(heightWalk - 1);
- if (heightSkip == height ||
- (heightSkip > height && !(heightSkipPrev < heightSkip - 2 &&
- heightSkipPrev >= height))) {
- // Only follow pskip if pprev->pskip isn't better than pskip->pprev.
- pindexWalk = pindexWalk->pskip;
- heightWalk = heightSkip;
- } else {
- pindexWalk = pindexWalk->pprev;
- heightWalk--;
- }
- }
- return pindexWalk;
-}
-
-const CBlockIndex* CBlockIndex::GetAncestor(int height) const
-{
- return const_cast<CBlockIndex*>(this)->GetAncestor(height);
-}
-
-void CBlockIndex::BuildSkip()
-{
- if (pprev)
- pskip = pprev->GetAncestor(GetSkipHeight(nHeight));
-}
bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp)
{
LOCK(cs_main);
MarkBlockAsReceived(pblock->GetHash());
if (!checked) {
- return error("%s : CheckBlock FAILED", __func__);
+ return error("%s: CheckBlock FAILED", __func__);
}
// Store to disk
mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
}
if (!ret)
- return error("%s : AcceptBlock FAILED", __func__);
+ return error("%s: AcceptBlock FAILED", __func__);
}
if (!ActivateBestChain(state, pblock))
- return error("%s : ActivateBestChain failed", __func__);
+ return error("%s: ActivateBestChain failed", __func__);
return true;
}
-CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter)
-{
- header = block.GetBlockHeader();
-
- vector<bool> vMatch;
- vector<uint256> vHashes;
-
- vMatch.reserve(block.vtx.size());
- vHashes.reserve(block.vtx.size());
-
- for (unsigned int i = 0; i < block.vtx.size(); i++)
- {
- const uint256& hash = block.vtx[i].GetHash();
- if (filter.IsRelevantAndUpdate(block.vtx[i]))
- {
- vMatch.push_back(true);
- vMatchedTxn.push_back(make_pair(i, hash));
- }
- else
- vMatch.push_back(false);
- vHashes.push_back(hash);
- }
-
- txn = CPartialMerkleTree(vHashes, vMatch);
-}
-
-
-
-
-
-
-
-
-uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) {
- if (height == 0) {
- // hash at height 0 is the txids themself
- return vTxid[pos];
- } else {
- // calculate left hash
- uint256 left = CalcHash(height-1, pos*2, vTxid), right;
- // calculate right hash if not beyong the end of the array - copy left hash otherwise1
- if (pos*2+1 < CalcTreeWidth(height-1))
- right = CalcHash(height-1, pos*2+1, vTxid);
- else
- right = left;
- // combine subhashes
- return Hash(BEGIN(left), END(left), BEGIN(right), END(right));
- }
-}
-
-void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) {
- // determine whether this node is the parent of at least one matched txid
- bool fParentOfMatch = false;
- for (unsigned int p = pos << height; p < (pos+1) << height && p < nTransactions; p++)
- fParentOfMatch |= vMatch[p];
- // store as flag bit
- vBits.push_back(fParentOfMatch);
- if (height==0 || !fParentOfMatch) {
- // if at height 0, or nothing interesting below, store hash and stop
- vHash.push_back(CalcHash(height, pos, vTxid));
- } else {
- // otherwise, don't store any hash, but descend into the subtrees
- TraverseAndBuild(height-1, pos*2, vTxid, vMatch);
- if (pos*2+1 < CalcTreeWidth(height-1))
- TraverseAndBuild(height-1, pos*2+1, vTxid, vMatch);
- }
-}
-
-uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch) {
- if (nBitsUsed >= vBits.size()) {
- // overflowed the bits array - failure
- fBad = true;
- return 0;
- }
- bool fParentOfMatch = vBits[nBitsUsed++];
- if (height==0 || !fParentOfMatch) {
- // if at height 0, or nothing interesting below, use stored hash and do not descend
- if (nHashUsed >= vHash.size()) {
- // overflowed the hash array - failure
- fBad = true;
- return 0;
- }
- const uint256 &hash = vHash[nHashUsed++];
- if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid
- vMatch.push_back(hash);
- return hash;
- } else {
- // otherwise, descend into the subtrees to extract matched txids and hashes
- uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch), right;
- if (pos*2+1 < CalcTreeWidth(height-1))
- right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch);
- else
- right = left;
- // and combine them before returning
- return Hash(BEGIN(left), END(left), BEGIN(right), END(right));
- }
-}
-
-CPartialMerkleTree::CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) {
- // reset state
- vBits.clear();
- vHash.clear();
-
- // calculate height of tree
- int nHeight = 0;
- while (CalcTreeWidth(nHeight) > 1)
- nHeight++;
-
- // traverse the partial tree
- TraverseAndBuild(nHeight, 0, vTxid, vMatch);
-}
-
-CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {}
-
-uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
- vMatch.clear();
- // An empty set will not work
- if (nTransactions == 0)
- return 0;
- // check for excessively high numbers of transactions
- if (nTransactions > MAX_BLOCK_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction
- return 0;
- // there can never be more hashes provided than one for every txid
- if (vHash.size() > nTransactions)
- return 0;
- // there must be at least one bit per node in the partial tree, and at least one node per hash
- if (vBits.size() < vHash.size())
- return 0;
- // calculate height of tree
- int nHeight = 0;
- while (CalcTreeWidth(nHeight) > 1)
- nHeight++;
- // traverse the partial tree
- unsigned int nBitsUsed = 0, nHashUsed = 0;
- uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch);
- // verify that no problems occured during the tree traversal
- if (fBad)
- return 0;
- // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence)
- if ((nBitsUsed+7)/8 != (vBits.size()+7)/8)
- return 0;
- // verify that all hashes were consumed
- if (nHashUsed != vHash.size())
- return 0;
- return hashMerkleRoot;
-}
-
-
-
-
-
-
-
bool AbortNode(const std::string &strMessage, const std::string &userMessage) {
strMiscWarning = strMessage;
LogPrintf("*** %s\n", strMessage);
bool CheckDiskSpace(uint64_t nAdditionalBytes)
{
- uint64_t nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
+ uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available;
// Check for nMinDiskSpace bytes (currently 50MB)
if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
CBlockIndex * InsertBlockIndex(uint256 hash)
{
- if (hash == 0)
+ if (hash.IsNull())
return NULL;
// Return existing
// Create new
CBlockIndex* pindexNew = new CBlockIndex();
if (!pindexNew)
- throw runtime_error("LoadBlockIndex() : new CBlockIndex failed");
+ throw runtime_error("LoadBlockIndex(): new CBlockIndex failed");
mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
pindexNew->phashBlock = &((*mi).first);
if (it == mapBlockIndex.end())
return true;
chainActive.SetTip(it->second);
+
+ PruneBlockIndexCandidates();
+
LogPrintf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s progress=%f\n",
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
CBlock block;
// check level 0: read from disk
if (!ReadBlockFromDisk(block, pindex))
- return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
// check level 1: verify block validity
if (nCheckLevel >= 1 && !CheckBlock(block, state))
- return error("VerifyDB() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
// check level 2: verify undo validity
if (nCheckLevel >= 2 && pindex) {
CBlockUndo undo;
CDiskBlockPos pos = pindex->GetUndoPos();
if (!pos.IsNull()) {
- if (!undo.ReadFromDisk(pos, pindex->pprev->GetBlockHash()))
- return error("VerifyDB() : *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
+ if (!UndoReadFromDisk(undo, pos, pindex->pprev->GetBlockHash()))
+ return error("VerifyDB(): *** found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
}
}
// check level 3: check for inconsistencies during memory-only disconnect of tip blocks
if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= nCoinCacheSize) {
bool fClean = true;
if (!DisconnectBlock(block, state, pindex, coins, &fClean))
- return error("VerifyDB() : *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return error("VerifyDB(): *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
pindexState = pindex->pprev;
if (!fClean) {
nGoodTransactions = 0;
} else
nGoodTransactions += block.vtx.size();
}
+ if (ShutdownRequested())
+ return true;
}
if (pindexFailure)
- return error("VerifyDB() : *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
+ return error("VerifyDB(): *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
// check level 4: try reconnecting blocks
if (nCheckLevel >= 4) {
pindex = chainActive.Next(pindex);
CBlock block;
if (!ReadBlockFromDisk(block, pindex))
- return error("VerifyDB() : *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
if (!ConnectBlock(block, state, pindex, coins))
- return error("VerifyDB() : *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
+ return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
}
}
void UnloadBlockIndex()
{
- mapBlockIndex.clear();
+ LOCK(cs_main);
setBlockIndexCandidates.clear();
chainActive.SetTip(NULL);
pindexBestInvalid = NULL;
+ pindexBestHeader = NULL;
+ mempool.clear();
+ mapOrphanTransactions.clear();
+ mapOrphanTransactionsByPrev.clear();
+ nSyncStarted = 0;
+ mapBlocksUnlinked.clear();
+ vinfoBlockFile.clear();
+ nLastBlockFile = 0;
+ nBlockSequenceId = 1;
+ mapBlockSource.clear();
+ mapBlocksInFlight.clear();
+ nQueuedValidatedHeaders = 0;
+ nPreferredDownload = 0;
+ setDirtyBlockIndex.clear();
+ setDirtyFileInfo.clear();
+ mapNodeState.clear();
+
+ BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
+ delete entry.second;
+ }
+ mapBlockIndex.clear();
}
bool LoadBlockIndex()
CDiskBlockPos blockPos;
CValidationState state;
if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime()))
- return error("LoadBlockIndex() : FindBlockPos failed");
+ return error("LoadBlockIndex(): FindBlockPos failed");
if (!WriteBlockToDisk(block, blockPos))
- return error("LoadBlockIndex() : writing genesis block to disk failed");
+ return error("LoadBlockIndex(): writing genesis block to disk failed");
CBlockIndex *pindex = AddToBlockIndex(block);
if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
- return error("LoadBlockIndex() : genesis block not accepted");
+ return error("LoadBlockIndex(): genesis block not accepted");
if (!ActivateBestChain(state, &block))
- return error("LoadBlockIndex() : genesis block cannot be activated");
- // Force a chainstate write so that when we VerifyDB in a moment, it doesnt check stale data
- return WriteChainState(state, true);
- } catch(std::runtime_error &e) {
- return error("LoadBlockIndex() : failed to initialize block database: %s", e.what());
+ return error("LoadBlockIndex(): genesis block cannot be activated");
+ // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data
+ return FlushStateToDisk(state, FLUSH_STATE_ALWAYS);
+ } catch (const std::runtime_error& e) {
+ return error("LoadBlockIndex(): failed to initialize block database: %s", e.what());
}
}
-void PrintBlockTree()
-{
- AssertLockHeld(cs_main);
- // pre-compute tree structure
- map<CBlockIndex*, vector<CBlockIndex*> > mapNext;
- for (BlockMap::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
- {
- CBlockIndex* pindex = (*mi).second;
- mapNext[pindex->pprev].push_back(pindex);
- // test
- //while (rand() % 3 == 0)
- // mapNext[pindex->pprev].push_back(pindex);
- }
-
- vector<pair<int, CBlockIndex*> > vStack;
- vStack.push_back(make_pair(0, chainActive.Genesis()));
-
- int nPrevCol = 0;
- while (!vStack.empty())
- {
- int nCol = vStack.back().first;
- CBlockIndex* pindex = vStack.back().second;
- vStack.pop_back();
-
- // print split or gap
- if (nCol > nPrevCol)
- {
- for (int i = 0; i < nCol-1; i++)
- LogPrintf("| ");
- LogPrintf("|\\\n");
- }
- else if (nCol < nPrevCol)
- {
- for (int i = 0; i < nCol; i++)
- LogPrintf("| ");
- LogPrintf("|\n");
- }
- nPrevCol = nCol;
-
- // print columns
- for (int i = 0; i < nCol; i++)
- LogPrintf("| ");
-
- // print item
- CBlock block;
- ReadBlockFromDisk(block, pindex);
- LogPrintf("%d (blk%05u.dat:0x%x) %s tx %u\n",
- pindex->nHeight,
- pindex->GetBlockPos().nFile, pindex->GetBlockPos().nPos,
- DateTimeStrFormat("%Y-%m-%d %H:%M:%S", block.GetBlockTime()),
- block.vtx.size());
-
- // put the main time-chain first
- vector<CBlockIndex*>& vNext = mapNext[pindex];
- for (unsigned int i = 0; i < vNext.size(); i++)
- {
- if (chainActive.Next(vNext[i]))
- {
- swap(vNext[0], vNext[i]);
- break;
- }
- }
-
- // iterate children
- for (unsigned int i = 0; i < vNext.size(); i++)
- vStack.push_back(make_pair(nCol+i, vNext[i]));
- }
-}
-
bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
{
// Map of disk positions for blocks with unknown parent (only used for reindex)
blkdat >> nSize;
if (nSize < 80 || nSize > MAX_BLOCK_SIZE)
continue;
- } catch (const std::exception &) {
+ } catch (const std::exception&) {
// no valid block header found; don't complain
break;
}
mapBlocksUnknownParent.erase(it);
}
}
- } catch (std::exception &e) {
- LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what());
+ } catch (const std::exception& e) {
+ LogPrintf("%s: Deserialize or I/O error - %s", __func__, e.what());
}
}
- } catch(std::runtime_error &e) {
+ } catch (const std::runtime_error& e) {
AbortNode(std::string("System error: ") + e.what());
}
if (nLoaded > 0)
return strStatusBar;
else if (strFor == "rpc")
return strRPC;
- assert(!"GetWarnings() : invalid parameter");
+ assert(!"GetWarnings(): invalid parameter");
return "error";
}
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
if (mi != mapBlockIndex.end())
{
- // If the requested block is at a height below our last
- // checkpoint, only serve it if it's in the checkpointed chain
- int nHeight = mi->second->nHeight;
- CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
- if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
- if (!chainActive.Contains(mi->second))
- {
- LogPrintf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n");
- } else {
- send = true;
- }
- } else {
+ if (chainActive.Contains(mi->second)) {
send = true;
+ } else {
+ // To prevent fingerprinting attacks, only send blocks outside of the active
+ // chain if they are valid, and no more than a month older than the best header
+ // chain we know about.
+ send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
+ (mi->second->GetBlockTime() > pindexBestHeader->GetBlockTime() - 30 * 24 * 60 * 60);
+ if (!send) {
+ LogPrintf("ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId());
+ }
}
}
if (send)
vector<CInv> vInv;
vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash()));
pfrom->PushMessage("inv", vInv);
- pfrom->hashContinue = 0;
+ pfrom->hashContinue.SetNull();
}
}
}
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
{
RandAddSeedPerfmon();
- LogPrint("net", "received: %s (%u bytes) peer=%d\n", strCommand, vRecv.size(), pfrom->id);
+ LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
{
LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
pfrom->nStartingHeight, addrMe.ToString(), pfrom->id,
remoteAddr);
- AddTimeData(pfrom->addr, nTime);
+ int64_t nTimeOffset = nTime - GetTime();
+ pfrom->nTimeOffset = nTimeOffset;
+ AddTimeData(pfrom->addr, nTimeOffset);
}
else if (strCommand == "verack")
{
pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
+
+ // Mark this node as currently connected, so we update its timestamp later.
+ if (pfrom->fNetworkNode) {
+ LOCK(cs_main);
+ State(pfrom->GetId())->fCurrentlyConnected = true;
+ }
}
// Use deterministic randomness to send to the same nodes for 24 hours
// at a time so the setAddrKnowns of the chosen nodes prevent repeats
static uint256 hashSalt;
- if (hashSalt == 0)
+ if (hashSalt.IsNull())
hashSalt = GetRandHash();
uint64_t hashAddr = addr.GetHash();
- uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60));
+ uint256 hashRand = ArithToUint256(UintToArith256(hashSalt) ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/(24*60*60)));
hashRand = Hash(BEGIN(hashRand), END(hashRand));
multimap<uint256, CNode*> mapMix;
BOOST_FOREACH(CNode* pnode, vNodes)
continue;
unsigned int nPointer;
memcpy(&nPointer, &pnode, sizeof(nPointer));
- uint256 hashKey = hashRand ^ nPointer;
+ uint256 hashKey = ArithToUint256(UintToArith256(hashRand) ^ nPointer);
hashKey = Hash(BEGIN(hashKey), END(hashKey));
mapMix.insert(make_pair(hashKey, pnode));
}
// doing this will result in the received block being rejected as an orphan in case it is
// not a direct successor.
pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
- if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20) {
+ CNodeState *nodestate = State(pfrom->GetId());
+ if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20 &&
+ nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
vToFetch.push_back(inv);
// Mark block as in flight already, even though the actual "getdata" message only goes out
// later (within the same cs_main lock, though).
if (pindex)
pindex = chainActive.Next(pindex);
int nLimit = 500;
- LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop==uint256(0) ? "end" : hashStop.ToString(), nLimit, pfrom->id);
+ LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->id);
for (; pindex; pindex = chainActive.Next(pindex))
{
if (pindex->GetBlockHash() == hashStop)
vWorkQueue.push_back(inv.hash);
vEraseQueue.push_back(inv.hash);
- LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s : accepted %s (poolsz %u)\n",
+ LogPrint("mempool", "AcceptToMemoryPool: peer=%d %s: accepted %s (poolsz %u)\n",
pfrom->id, pfrom->cleanSubVer,
tx.GetHash().ToString(),
mempool.mapTx.size());
pfrom->id, pfrom->cleanSubVer,
state.GetRejectReason());
pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
- state.GetRejectReason(), inv.hash);
+ state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
if (nDoS > 0)
Misbehaving(pfrom->GetId(), nDoS);
}
// TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
// from there instead.
LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
- pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256(0));
+ pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256());
}
}
int nDoS;
if (state.IsInvalid(nDoS)) {
pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
- state.GetRejectReason(), inv.hash);
+ state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
if (nDoS > 0) {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), nDoS);
}
- else if (strCommand == "getaddr")
+ // This asymmetric behavior for inbound and outbound connections was introduced
+ // to prevent a fingerprinting attack: an attacker can send specific fake addresses
+ // to users' AddrMan and later request them by sending getaddr messages.
+ // Making users (which are behind NAT and can only make outgoing connections) ignore
+ // getaddr message mitigates the attack.
+ else if ((strCommand == "getaddr") && (pfrom->fInbound))
{
pfrom->vAddrToSend.clear();
vector<CAddress> vAddr = addrman.GetAddr();
if (fDebug) {
try {
string strMsg; unsigned char ccode; string strReason;
- vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, 111);
+ vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, MAX_REJECT_MESSAGE_LENGTH);
ostringstream ss;
ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
ss << ": hash " << hash.ToString();
}
LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
- } catch (std::ios_base::failure& e) {
+ } catch (const std::ios_base::failure&) {
// Avoid feedback loops by preventing reject messages from triggering a new reject message.
LogPrint("net", "Unparseable reject message received\n");
}
}
- // Update the last seen time for this node's address
- if (pfrom->fNetworkNode)
- if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping")
- AddressCurrentlyConnected(pfrom->addr);
-
return true;
}
// Scan for message start
if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
- LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", msg.hdr.GetCommand(), pfrom->id);
+ LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
fOk = false;
break;
}
// Read header
CMessageHeader& hdr = msg.hdr;
- if (!hdr.IsValid())
+ if (!hdr.IsValid(Params().MessageStart()))
{
- LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", hdr.GetCommand(), pfrom->id);
+ LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
continue;
}
string strCommand = hdr.GetCommand();
// Checksum
CDataStream& vRecv = msg.vRecv;
uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
- unsigned int nChecksum = 0;
- memcpy(&nChecksum, &hash, sizeof(nChecksum));
+ unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
if (nChecksum != hdr.nChecksum)
{
- LogPrintf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
- strCommand, nMessageSize, nChecksum, hdr.nChecksum);
+ LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
+ SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
continue;
}
fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime);
boost::this_thread::interruption_point();
}
- catch (std::ios_base::failure& e)
+ catch (const std::ios_base::failure& e)
{
pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message"));
if (strstr(e.what(), "end of data"))
{
// Allow exceptions from under-length message on vRecv
- LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand, nMessageSize, e.what());
+ LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", SanitizeString(strCommand), nMessageSize, e.what());
}
else if (strstr(e.what(), "size too large"))
{
// Allow exceptions from over-long size
- LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand, nMessageSize, e.what());
+ LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", SanitizeString(strCommand), nMessageSize, e.what());
}
else
{
PrintExceptionContinue(&e, "ProcessMessages()");
}
}
- catch (boost::thread_interrupted) {
+ catch (const boost::thread_interrupted&) {
throw;
}
- catch (std::exception& e) {
+ catch (const std::exception& e) {
PrintExceptionContinue(&e, "ProcessMessages()");
} catch (...) {
PrintExceptionContinue(NULL, "ProcessMessages()");
}
if (!fRet)
- LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", strCommand, nMessageSize, pfrom->id);
+ LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", SanitizeString(strCommand), nMessageSize, pfrom->id);
break;
}
nSyncStarted++;
CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight);
- pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256(0));
+ pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256());
}
}
{
// 1/4 of tx invs blast to all immediately
static uint256 hashSalt;
- if (hashSalt == 0)
+ if (hashSalt.IsNull())
hashSalt = GetRandHash();
- uint256 hashRand = inv.hash ^ hashSalt;
+ uint256 hashRand = ArithToUint256(UintToArith256(inv.hash) ^ UintToArith256(hashSalt));
hashRand = Hash(BEGIN(hashRand), END(hashRand));
- bool fTrickleWait = ((hashRand & 3) != 0);
+ bool fTrickleWait = ((UintToArith256(hashRand) & 3) != 0);
if (fTrickleWait)
{
LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
pto->fDisconnect = true;
}
+ // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
+ // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
+ // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
+ // being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes
+ // to unreasonably increase our timeout.
+ if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacing() * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) {
+ LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id);
+ pto->fDisconnect = true;
+ }
//
// Message: getdata (blocks)
return true;
}
-
-bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock)
-{
- // Open history file to append
- CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
- if (fileout.IsNull())
- return error("CBlockUndo::WriteToDisk : OpenUndoFile failed");
-
- // Write index header
- unsigned int nSize = fileout.GetSerializeSize(*this);
- fileout << FLATDATA(Params().MessageStart()) << nSize;
-
- // Write undo data
- long fileOutPos = ftell(fileout.Get());
- if (fileOutPos < 0)
- return error("CBlockUndo::WriteToDisk : ftell failed");
- pos.nPos = (unsigned int)fileOutPos;
- fileout << *this;
-
- // calculate & write checksum
- CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
- hasher << hashBlock;
- hasher << *this;
- fileout << hasher.GetHash();
-
- // Flush stdio buffers and commit to disk before returning
- fflush(fileout.Get());
- if (!IsInitialBlockDownload())
- FileCommit(fileout.Get());
-
- return true;
-}
-
-bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock)
-{
- // Open history file to read
- CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
- if (filein.IsNull())
- return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed");
-
- // Read block
- uint256 hashChecksum;
- try {
- filein >> *this;
- filein >> hashChecksum;
- }
- catch (std::exception &e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
- }
-
- // Verify checksum
- CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
- hasher << hashBlock;
- hasher << *this;
- if (hashChecksum != hasher.GetHash())
- return error("CBlockUndo::ReadFromDisk : Checksum mismatch");
-
- return true;
-}
-
std::string CBlockFileInfo::ToString() const {
return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst), DateTimeStrFormat("%Y-%m-%d", nTimeLast));
}
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_MAIN_H
#include "chain.h"
#include "chainparams.h"
#include "coins.h"
-#include "core/block.h"
-#include "core/transaction.h"
+#include "primitives/block.h"
+#include "primitives/transaction.h"
#include "net.h"
#include "pow.h"
#include "script/script.h"
#include "tinyformat.h"
#include "txmempool.h"
#include "uint256.h"
-#include "undo.h"
#include <algorithm>
#include <exception>
class CValidationInterface;
class CValidationState;
-struct CBlockTemplate;
struct CNodeStateStats;
-/** The maximum allowed size for a serialized block, in bytes (network rule) */
-static const unsigned int MAX_BLOCK_SIZE = 1000000;
/** Default for -blockmaxsize and -blockminsize, which control the range of sizes the mining code will create **/
static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000;
static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0;
static const unsigned int MAX_STANDARD_TX_SIZE = 100000;
/** The maximum allowed number of signature check operations in a block (network rule) */
static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
-/** Maxiumum number of signature check operations in an IsStandard() P2SH script */
+/** Maximum number of signature check operations in an IsStandard() P2SH script */
static const unsigned int MAX_P2SH_SIGOPS = 15;
/** The maximum number of sigops we're willing to relay/mine in a single tx */
-static const unsigned int MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5;
+static const unsigned int MAX_STANDARD_TX_SIGOPS = MAX_BLOCK_SIGOPS/5;
/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */
static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100;
-/** Default for -maxorphanblocks, maximum number of orphan blocks kept in memory */
-static const unsigned int DEFAULT_MAX_ORPHAN_BLOCKS = 750;
/** The maximum size of a blk?????.dat file (since 0.8) */
static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
/** The pre-allocation chunk size for blk?????.dat files (since 0.8) */
* degree of disordering of blocks on disk (which make reindexing and in the future perhaps pruning
* harder). We'll probably want to make this a per-peer adaptive value at some point. */
static const unsigned int BLOCK_DOWNLOAD_WINDOW = 1024;
+/** Time to wait (in seconds) between writing blockchain state to disk. */
+static const unsigned int DATABASE_WRITE_INTERVAL = 3600;
+/** Maximum length of reject messages. */
+static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111;
-/** "reject" message codes **/
+/** "reject" message codes */
static const unsigned char REJECT_MALFORMED = 0x01;
static const unsigned char REJECT_INVALID = 0x10;
static const unsigned char REJECT_OBSOLETE = 0x11;
struct BlockHasher
{
- size_t operator()(const uint256& hash) const { return hash.GetLow64(); }
+ size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); }
};
extern CScript COINBASE_FLAGS;
extern unsigned int nCoinCacheSize;
extern CFeeRate minRelayTxFee;
-// Best header we've seen so far (used for getheaders queries' starting points).
+/** Best header we've seen so far (used for getheaders queries' starting points). */
extern CBlockIndex *pindexBestHeader;
-// Minimum disk space required - used in CheckDiskSpace()
+/** Minimum disk space required - used in CheckDiskSpace() */
static const uint64_t nMinDiskSpace = 52428800;
/** Register a wallet to receive updates from core */
/** Unregister a network node */
void UnregisterNodeSignals(CNodeSignals& nodeSignals);
-/** Process an incoming block. This only returns after the best known valid
- block is made active. Note that it does not, however, guarantee that the
- specific block passed to it has been checked for validity!
- @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state iff pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface - this will have its BlockChecked method called whenever *any* block completes validation.
- @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid.
- @param[in] pblock The block we want to process.
- @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location.
- @return True if state.IsValid()
-*/
+/**
+ * Process an incoming block. This only returns after the best known valid
+ * block is made active. Note that it does not, however, guarantee that the
+ * specific block passed to it has been checked for validity!
+ *
+ * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface - this will have its BlockChecked method called whenever *any* block completes validation.
+ * @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid.
+ * @param[in] pblock The block we want to process.
+ * @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location.
+ * @return True if state.IsValid()
+ */
bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp = NULL);
/** Check whether enough disk space is available for an incoming block */
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
bool LoadBlockIndex();
/** Unload database information */
void UnloadBlockIndex();
-/** Print the loaded block tree */
-void PrintBlockTree();
/** Process protocol messages received from a given node */
bool ProcessMessages(CNode* pfrom);
/** Send queued protocol messages to be sent to a give node */
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats);
/** Increase a node's misbehavior score. */
void Misbehaving(NodeId nodeid, int howmuch);
+/** Flush all state, indexes and buffers to disk. */
+void FlushStateToDisk();
/** (try to) add transaction to memory pool **/
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
- bool* pfMissingInputs, bool fRejectInsaneFee=false);
+ bool* pfMissingInputs, bool fRejectAbsurdFee=false);
struct CNodeStateStats {
CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree);
-//
-// Check transaction inputs, and make sure any
-// pay-to-script-hash transactions are evaluating IsStandard scripts
-//
-// Why bother? To avoid denial-of-service attacks; an attacker
-// can submit a standard HASH... OP_EQUAL transaction,
-// which will get accepted into blocks. The redemption
-// script can be anything; an attacker could use a very
-// expensive-to-check-upon-redemption script like:
-// DUP CHECKSIG DROP ... repeated 100 times... OP_1
-//
+/**
+ * Check transaction inputs, and make sure any
+ * pay-to-script-hash transactions are evaluating IsStandard scripts
+ *
+ * Why bother? To avoid denial-of-service attacks; an attacker
+ * can submit a standard HASH... OP_EQUAL transaction,
+ * which will get accepted into blocks. The redemption
+ * script can be anything; an attacker could use a very
+ * expensive-to-check-upon-redemption script like:
+ * DUP CHECKSIG DROP ... repeated 100 times... OP_1
+ */
-/** Check for standard transaction types
- @param[in] mapInputs Map of previous transactions that have outputs we're spending
- @return True if all inputs (scriptSigs) use only standard transaction forms
-*/
+/**
+ * Check for standard transaction types
+ * @param[in] mapInputs Map of previous transactions that have outputs we're spending
+ * @return True if all inputs (scriptSigs) use only standard transaction forms
+ */
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs);
-/** Count ECDSA signature operations the old-fashioned (pre-0.6) way
- @return number of sigops this transaction's outputs will produce when spent
- @see CTransaction::FetchInputs
-*/
+/**
+ * Count ECDSA signature operations the old-fashioned (pre-0.6) way
+ * @return number of sigops this transaction's outputs will produce when spent
+ * @see CTransaction::FetchInputs
+ */
unsigned int GetLegacySigOpCount(const CTransaction& tx);
-/** Count ECDSA signature operations in pay-to-script-hash inputs.
-
- @param[in] mapInputs Map of previous transactions that have outputs we're spending
- @return maximum number of sigops required to validate this transaction's inputs
- @see CTransaction::FetchInputs
+/**
+ * Count ECDSA signature operations in pay-to-script-hash inputs.
+ *
+ * @param[in] mapInputs Map of previous transactions that have outputs we're spending
+ * @return maximum number of sigops required to validate this transaction's inputs
+ * @see CTransaction::FetchInputs
*/
unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& mapInputs);
-// Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts)
-// This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it
-// instead of being performed inline.
+/**
+ * Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts)
+ * This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it
+ * instead of being performed inline.
+ */
bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks,
unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks = NULL);
-// Apply the effects of this transaction on the UTXO set represented by view
-void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight);
+/** Apply the effects of this transaction on the UTXO set represented by view */
+void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight);
-// Context-independent validity checks
+/** Context-independent validity checks */
bool CheckTransaction(const CTransaction& tx, CValidationState& state);
/** Check for standard transaction types
- @return True if all outputs (scriptPubKeys) use only standard transaction forms
-*/
+ * @return True if all outputs (scriptPubKeys) use only standard transaction forms
+ */
bool IsStandardTx(const CTransaction& tx, std::string& reason);
bool IsFinalTx(const CTransaction &tx, int nBlockHeight = 0, int64_t nBlockTime = 0);
-/** Undo information for a CBlock */
-class CBlockUndo
-{
-public:
- std::vector<CTxUndo> vtxundo; // for all but the coinbase
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(vtxundo);
- }
-
- bool WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock);
- bool ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock);
-};
-
-
-/** Closure representing one script verification
- * Note that this stores references to the spending transaction */
+/**
+ * Closure representing one script verification
+ * Note that this stores references to the spending transaction
+ */
class CScriptCheck
{
private:
unsigned int nIn;
unsigned int nFlags;
bool cacheStore;
+ ScriptError error;
public:
- CScriptCheck(): ptxTo(0), nIn(0), nFlags(0), cacheStore(false) {}
+ CScriptCheck(): ptxTo(0), nIn(0), nFlags(0), cacheStore(false), error(SCRIPT_ERR_UNKNOWN_ERROR) {}
CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn) :
scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey),
- ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn) { }
+ ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), error(SCRIPT_ERR_UNKNOWN_ERROR) { }
- bool operator()() const;
+ bool operator()();
void swap(CScriptCheck &check) {
scriptPubKey.swap(check.scriptPubKey);
std::swap(nIn, check.nIn);
std::swap(nFlags, check.nFlags);
std::swap(cacheStore, check.cacheStore);
+ std::swap(error, check.error);
}
-};
-
-/** Data structure that represents a partial merkle tree.
- *
- * It respresents a subset of the txid's of a known block, in a way that
- * allows recovery of the list of txid's and the merkle root, in an
- * authenticated way.
- *
- * The encoding works as follows: we traverse the tree in depth-first order,
- * storing a bit for each traversed node, signifying whether the node is the
- * parent of at least one matched leaf txid (or a matched txid itself). In
- * case we are at the leaf level, or this bit is 0, its merkle node hash is
- * stored, and its children are not explorer further. Otherwise, no hash is
- * stored, but we recurse into both (or the only) child branch. During
- * decoding, the same depth-first traversal is performed, consuming bits and
- * hashes as they written during encoding.
- *
- * The serialization is fixed and provides a hard guarantee about the
- * encoded size:
- *
- * SIZE <= 10 + ceil(32.25*N)
- *
- * Where N represents the number of leaf nodes of the partial tree. N itself
- * is bounded by:
- *
- * N <= total_transactions
- * N <= 1 + matched_transactions*tree_height
- *
- * The serialization format:
- * - uint32 total_transactions (4 bytes)
- * - varint number of hashes (1-3 bytes)
- * - uint256[] hashes in depth-first order (<= 32*N bytes)
- * - varint number of bytes of flag bits (1-3 bytes)
- * - byte[] flag bits, packed per 8 in a byte, least significant bit first (<= 2*N-1 bits)
- * The size constraints follow from this.
- */
-class CPartialMerkleTree
-{
-protected:
- // the total number of transactions in the block
- unsigned int nTransactions;
-
- // node-is-parent-of-matched-txid bits
- std::vector<bool> vBits;
-
- // txids and internal hashes
- std::vector<uint256> vHash;
-
- // flag set when encountering invalid data
- bool fBad;
-
- // helper function to efficiently calculate the number of nodes at given height in the merkle tree
- unsigned int CalcTreeWidth(int height) {
- return (nTransactions+(1 << height)-1) >> height;
- }
-
- // calculate the hash of a node in the merkle tree (at leaf level: the txid's themself)
- uint256 CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid);
-
- // recursive function that traverses tree nodes, storing the data as bits and hashes
- void TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch);
-
- // recursive function that traverses tree nodes, consuming the bits and hashes produced by TraverseAndBuild.
- // it returns the hash of the respective node.
- uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch);
-
-public:
-
- // serialization implementation
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(nTransactions);
- READWRITE(vHash);
- std::vector<unsigned char> vBytes;
- if (ser_action.ForRead()) {
- READWRITE(vBytes);
- CPartialMerkleTree &us = *(const_cast<CPartialMerkleTree*>(this));
- us.vBits.resize(vBytes.size() * 8);
- for (unsigned int p = 0; p < us.vBits.size(); p++)
- us.vBits[p] = (vBytes[p / 8] & (1 << (p % 8))) != 0;
- us.fBad = false;
- } else {
- vBytes.resize((vBits.size()+7)/8);
- for (unsigned int p = 0; p < vBits.size(); p++)
- vBytes[p / 8] |= vBits[p] << (p % 8);
- READWRITE(vBytes);
- }
- }
-
- // Construct a partial merkle tree from a list of transaction id's, and a mask that selects a subset of them
- CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch);
- CPartialMerkleTree();
-
- // extract the matching txid's represented by this partial merkle tree.
- // returns the merkle root, or 0 in case of failure
- uint256 ExtractMatches(std::vector<uint256> &vMatch);
+ ScriptError GetScriptError() const { return error; }
};
-
/** Functions for disk access for blocks */
bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos);
bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos);
* of problems. Note that in any case, coins may be modified. */
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
+/** Apply the effects of this block (with given index) on the UTXO set represented by coins */
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false);
-// Context-independent validity checks
+/** 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
+/** 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)
+/** 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
+/** 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);
bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL);
class CBlockFileInfo
{
public:
- unsigned int nBlocks; // number of blocks stored in file
- unsigned int nSize; // number of used bytes of block file
- unsigned int nUndoSize; // number of used bytes in the undo file
- unsigned int nHeightFirst; // lowest height of block in file
- unsigned int nHeightLast; // highest height of block in file
- uint64_t nTimeFirst; // earliest time of block in file
- uint64_t nTimeLast; // latest time of block in file
+ unsigned int nBlocks; //! number of blocks stored in file
+ unsigned int nSize; //! number of used bytes of block file
+ unsigned int nUndoSize; //! number of used bytes in the undo file
+ unsigned int nHeightFirst; //! lowest height of block in file
+ unsigned int nHeightLast; //! highest height of block in file
+ uint64_t nTimeFirst; //! earliest time of block in file
+ uint64_t nTimeLast; //! latest time of block in file
ADD_SERIALIZE_METHODS;
std::string ToString() const;
- // update statistics (does not update nSize)
+ /** update statistics (does not update nSize) */
void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) {
if (nBlocks==0 || nHeightFirst > nHeightIn)
nHeightFirst = nHeightIn;
class CValidationState {
private:
enum mode_state {
- MODE_VALID, // everything ok
- MODE_INVALID, // network rule violation (DoS value may be set)
- MODE_ERROR, // run-time error
+ MODE_VALID, //! everything ok
+ MODE_INVALID, //! network rule violation (DoS value may be set)
+ MODE_ERROR, //! run-time error
} mode;
int nDoS;
std::string strRejectReason;
/** Find the last common block between the parameter chain and a locator. */
CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator);
+/** Mark a block as invalid. */
+bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex);
+
+/** Remove invalidity status from a block and its descendants. */
+bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex);
+
/** The currently-connected chain of blocks. */
extern CChain chainActive;
/** Global variable that points to the active block tree (protected by cs_main) */
extern CBlockTreeDB *pblocktree;
-struct CBlockTemplate
-{
- CBlock block;
- std::vector<CAmount> vTxFees;
- std::vector<int64_t> vTxSigOps;
-};
-
-
-
-
-
-
-/** Used to relay blocks as header + vector<merkle branch>
- * to filtered nodes.
- */
-class CMerkleBlock
-{
-public:
- // Public only for unit testing
- CBlockHeader header;
- CPartialMerkleTree txn;
-
-public:
- // Public only for unit testing and relay testing
- // (not relayed)
- std::vector<std::pair<unsigned int, uint256> > vMatchedTxn;
-
- // Create from a CBlock, filtering transactions according to filter
- // Note that this will call IsRelevantAndUpdate on the filter for each transaction,
- // thus the filter will likely be modified.
- CMerkleBlock(const CBlock& block, CBloomFilter& filter);
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(header);
- READWRITE(txn);
- }
-};
-
class CValidationInterface {
protected:
--- /dev/null
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "merkleblock.h"
+
+#include "hash.h"
+#include "primitives/block.h" // for MAX_BLOCK_SIZE
+#include "utilstrencodings.h"
+
+using namespace std;
+
+CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter)
+{
+ header = block.GetBlockHeader();
+
+ vector<bool> vMatch;
+ vector<uint256> vHashes;
+
+ vMatch.reserve(block.vtx.size());
+ vHashes.reserve(block.vtx.size());
+
+ for (unsigned int i = 0; i < block.vtx.size(); i++)
+ {
+ const uint256& hash = block.vtx[i].GetHash();
+ if (filter.IsRelevantAndUpdate(block.vtx[i]))
+ {
+ vMatch.push_back(true);
+ vMatchedTxn.push_back(make_pair(i, hash));
+ }
+ else
+ vMatch.push_back(false);
+ vHashes.push_back(hash);
+ }
+
+ txn = CPartialMerkleTree(vHashes, vMatch);
+}
+
+uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid) {
+ if (height == 0) {
+ // hash at height 0 is the txids themself
+ return vTxid[pos];
+ } else {
+ // calculate left hash
+ uint256 left = CalcHash(height-1, pos*2, vTxid), right;
+ // calculate right hash if not beyond the end of the array - copy left hash otherwise1
+ if (pos*2+1 < CalcTreeWidth(height-1))
+ right = CalcHash(height-1, pos*2+1, vTxid);
+ else
+ right = left;
+ // combine subhashes
+ return Hash(BEGIN(left), END(left), BEGIN(right), END(right));
+ }
+}
+
+void CPartialMerkleTree::TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) {
+ // determine whether this node is the parent of at least one matched txid
+ bool fParentOfMatch = false;
+ for (unsigned int p = pos << height; p < (pos+1) << height && p < nTransactions; p++)
+ fParentOfMatch |= vMatch[p];
+ // store as flag bit
+ vBits.push_back(fParentOfMatch);
+ if (height==0 || !fParentOfMatch) {
+ // if at height 0, or nothing interesting below, store hash and stop
+ vHash.push_back(CalcHash(height, pos, vTxid));
+ } else {
+ // otherwise, don't store any hash, but descend into the subtrees
+ TraverseAndBuild(height-1, pos*2, vTxid, vMatch);
+ if (pos*2+1 < CalcTreeWidth(height-1))
+ TraverseAndBuild(height-1, pos*2+1, vTxid, vMatch);
+ }
+}
+
+uint256 CPartialMerkleTree::TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch) {
+ if (nBitsUsed >= vBits.size()) {
+ // overflowed the bits array - failure
+ fBad = true;
+ return uint256();
+ }
+ bool fParentOfMatch = vBits[nBitsUsed++];
+ if (height==0 || !fParentOfMatch) {
+ // if at height 0, or nothing interesting below, use stored hash and do not descend
+ if (nHashUsed >= vHash.size()) {
+ // overflowed the hash array - failure
+ fBad = true;
+ return uint256();
+ }
+ const uint256 &hash = vHash[nHashUsed++];
+ if (height==0 && fParentOfMatch) // in case of height 0, we have a matched txid
+ vMatch.push_back(hash);
+ return hash;
+ } else {
+ // otherwise, descend into the subtrees to extract matched txids and hashes
+ uint256 left = TraverseAndExtract(height-1, pos*2, nBitsUsed, nHashUsed, vMatch), right;
+ if (pos*2+1 < CalcTreeWidth(height-1)) {
+ right = TraverseAndExtract(height-1, pos*2+1, nBitsUsed, nHashUsed, vMatch);
+ if (right == left) {
+ // If the left and right branch should never be identical as the transaction
+ // hashes covered by them must be unique.
+ fBad = true;
+ }
+ } else {
+ right = left;
+ }
+ // and combine them before returning
+ return Hash(BEGIN(left), END(left), BEGIN(right), END(right));
+ }
+}
+
+CPartialMerkleTree::CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch) : nTransactions(vTxid.size()), fBad(false) {
+ // reset state
+ vBits.clear();
+ vHash.clear();
+
+ // calculate height of tree
+ int nHeight = 0;
+ while (CalcTreeWidth(nHeight) > 1)
+ nHeight++;
+
+ // traverse the partial tree
+ TraverseAndBuild(nHeight, 0, vTxid, vMatch);
+}
+
+CPartialMerkleTree::CPartialMerkleTree() : nTransactions(0), fBad(true) {}
+
+uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
+ vMatch.clear();
+ // An empty set will not work
+ if (nTransactions == 0)
+ return uint256();
+ // check for excessively high numbers of transactions
+ if (nTransactions > MAX_BLOCK_SIZE / 60) // 60 is the lower bound for the size of a serialized CTransaction
+ return uint256();
+ // there can never be more hashes provided than one for every txid
+ if (vHash.size() > nTransactions)
+ return uint256();
+ // there must be at least one bit per node in the partial tree, and at least one node per hash
+ if (vBits.size() < vHash.size())
+ return uint256();
+ // calculate height of tree
+ int nHeight = 0;
+ while (CalcTreeWidth(nHeight) > 1)
+ nHeight++;
+ // traverse the partial tree
+ unsigned int nBitsUsed = 0, nHashUsed = 0;
+ uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch);
+ // verify that no problems occured during the tree traversal
+ if (fBad)
+ return uint256();
+ // verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence)
+ if ((nBitsUsed+7)/8 != (vBits.size()+7)/8)
+ return uint256();
+ // verify that all hashes were consumed
+ if (nHashUsed != vHash.size())
+ return uint256();
+ return hashMerkleRoot;
+}
--- /dev/null
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_MERKLEBLOCK_H
+#define BITCOIN_MERKLEBLOCK_H
+
+#include "serialize.h"
+#include "uint256.h"
+#include "primitives/block.h"
+#include "bloom.h"
+
+#include <vector>
+
+/** Data structure that represents a partial merkle tree.
+ *
+ * It represents a subset of the txid's of a known block, in a way that
+ * allows recovery of the list of txid's and the merkle root, in an
+ * authenticated way.
+ *
+ * The encoding works as follows: we traverse the tree in depth-first order,
+ * storing a bit for each traversed node, signifying whether the node is the
+ * parent of at least one matched leaf txid (or a matched txid itself). In
+ * case we are at the leaf level, or this bit is 0, its merkle node hash is
+ * stored, and its children are not explorer further. Otherwise, no hash is
+ * stored, but we recurse into both (or the only) child branch. During
+ * decoding, the same depth-first traversal is performed, consuming bits and
+ * hashes as they written during encoding.
+ *
+ * The serialization is fixed and provides a hard guarantee about the
+ * encoded size:
+ *
+ * SIZE <= 10 + ceil(32.25*N)
+ *
+ * Where N represents the number of leaf nodes of the partial tree. N itself
+ * is bounded by:
+ *
+ * N <= total_transactions
+ * N <= 1 + matched_transactions*tree_height
+ *
+ * The serialization format:
+ * - uint32 total_transactions (4 bytes)
+ * - varint number of hashes (1-3 bytes)
+ * - uint256[] hashes in depth-first order (<= 32*N bytes)
+ * - varint number of bytes of flag bits (1-3 bytes)
+ * - byte[] flag bits, packed per 8 in a byte, least significant bit first (<= 2*N-1 bits)
+ * The size constraints follow from this.
+ */
+class CPartialMerkleTree
+{
+protected:
+ /** the total number of transactions in the block */
+ unsigned int nTransactions;
+
+ /** node-is-parent-of-matched-txid bits */
+ std::vector<bool> vBits;
+
+ /** txids and internal hashes */
+ std::vector<uint256> vHash;
+
+ /** flag set when encountering invalid data */
+ bool fBad;
+
+ /** helper function to efficiently calculate the number of nodes at given height in the merkle tree */
+ unsigned int CalcTreeWidth(int height) {
+ return (nTransactions+(1 << height)-1) >> height;
+ }
+
+ /** calculate the hash of a node in the merkle tree (at leaf level: the txid's themselves) */
+ uint256 CalcHash(int height, unsigned int pos, const std::vector<uint256> &vTxid);
+
+ /** recursive function that traverses tree nodes, storing the data as bits and hashes */
+ void TraverseAndBuild(int height, unsigned int pos, const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch);
+
+ /**
+ * recursive function that traverses tree nodes, consuming the bits and hashes produced by TraverseAndBuild.
+ * it returns the hash of the respective node.
+ */
+ uint256 TraverseAndExtract(int height, unsigned int pos, unsigned int &nBitsUsed, unsigned int &nHashUsed, std::vector<uint256> &vMatch);
+
+public:
+
+ /** serialization implementation */
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(nTransactions);
+ READWRITE(vHash);
+ std::vector<unsigned char> vBytes;
+ if (ser_action.ForRead()) {
+ READWRITE(vBytes);
+ CPartialMerkleTree &us = *(const_cast<CPartialMerkleTree*>(this));
+ us.vBits.resize(vBytes.size() * 8);
+ for (unsigned int p = 0; p < us.vBits.size(); p++)
+ us.vBits[p] = (vBytes[p / 8] & (1 << (p % 8))) != 0;
+ us.fBad = false;
+ } else {
+ vBytes.resize((vBits.size()+7)/8);
+ for (unsigned int p = 0; p < vBits.size(); p++)
+ vBytes[p / 8] |= vBits[p] << (p % 8);
+ READWRITE(vBytes);
+ }
+ }
+
+ /** Construct a partial merkle tree from a list of transaction id's, and a mask that selects a subset of them */
+ CPartialMerkleTree(const std::vector<uint256> &vTxid, const std::vector<bool> &vMatch);
+
+ CPartialMerkleTree();
+
+ /**
+ * extract the matching txid's represented by this partial merkle tree.
+ * returns the merkle root, or 0 in case of failure
+ */
+ uint256 ExtractMatches(std::vector<uint256> &vMatch);
+};
+
+
+/**
+ * Used to relay blocks as header + vector<merkle branch>
+ * to filtered nodes.
+ */
+class CMerkleBlock
+{
+public:
+ /** Public only for unit testing */
+ CBlockHeader header;
+ CPartialMerkleTree txn;
+
+public:
+ /** Public only for unit testing and relay testing (not relayed) */
+ std::vector<std::pair<unsigned int, uint256> > vMatchedTxn;
+
+ /**
+ * Create from a CBlock, filtering transactions according to filter
+ * Note that this will call IsRelevantAndUpdate on the filter for each transaction,
+ * thus the filter will likely be modified.
+ */
+ CMerkleBlock(const CBlock& block, CBloomFilter& filter);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(header);
+ READWRITE(txn);
+ }
+};
+
+#endif // BITCOIN_MERKLEBLOCK_H
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "miner.h"
#include "amount.h"
-#include "core/block.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "hash.h"
#include "main.h"
#include "net.h"
if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
continue;
- CTxUndo txundo;
- UpdateCoins(tx, state, view, txundo, nHeight);
+ UpdateCoins(tx, state, view, nHeight);
// Added
pblock->vtx.push_back(tx);
CValidationState state;
if (!TestBlockValidity(state, *pblock, pindexPrev, false, false))
- throw std::runtime_error("CreateNewBlock() : TestBlockValidity failed");
+ throw std::runtime_error("CreateNewBlock(): TestBlockValidity failed");
}
return pblocktemplate.release();
//
// Internal miner
//
-double dHashesPerSec = 0.0;
-int64_t nHPSTimerStart = 0;
//
// ScanHash scans nonces looking for a hash with at least some zero bits.
return true;
// If nothing found after trying for a while, return -1
- if ((nNonce & 0xffff) == 0)
- return false;
if ((nNonce & 0xfff) == 0)
- boost::this_thread::interruption_point();
+ return false;
}
}
return CreateNewBlock(scriptPubKey);
}
-bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
+static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
{
LogPrintf("%s\n", pblock->ToString());
LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
{
LOCK(cs_main);
if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockHash())
- return error("BitcoinMiner : generated block is stale");
+ return error("BitcoinMiner: generated block is stale");
}
// Remove key from key pool
// Process this block the same as if we had received it from another node
CValidationState state;
if (!ProcessNewBlock(state, NULL, pblock))
- return error("BitcoinMiner : ProcessNewBlock, block not accepted");
+ return error("BitcoinMiner: ProcessNewBlock, block not accepted");
return true;
}
// Search
//
int64_t nStart = GetTime();
- uint256 hashTarget = uint256().SetCompact(pblock->nBits);
+ arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
uint256 hash;
uint32_t nNonce = 0;
- uint32_t nOldNonce = 0;
while (true) {
- bool fFound = ScanHash(pblock, nNonce, &hash);
- uint32_t nHashesDone = nNonce - nOldNonce;
- nOldNonce = nNonce;
-
// Check if something found
- if (fFound)
+ if (ScanHash(pblock, nNonce, &hash))
{
- if (hash <= hashTarget)
+ if (UintToArith256(hash) <= hashTarget)
{
// Found a solution
pblock->nNonce = nNonce;
}
}
- // Meter hashes/sec
- static int64_t nHashCounter;
- if (nHPSTimerStart == 0)
- {
- nHPSTimerStart = GetTimeMillis();
- nHashCounter = 0;
- }
- else
- nHashCounter += nHashesDone;
- if (GetTimeMillis() - nHPSTimerStart > 4000)
- {
- static CCriticalSection cs;
- {
- LOCK(cs);
- if (GetTimeMillis() - nHPSTimerStart > 4000)
- {
- dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
- nHPSTimerStart = GetTimeMillis();
- nHashCounter = 0;
- static int64_t nLogTime;
- if (GetTime() - nLogTime > 30 * 60)
- {
- nLogTime = GetTime();
- LogPrintf("hashmeter %6.0f khash/s\n", dHashesPerSec/1000.0);
- }
- }
- }
- }
-
// Check for stop or if block needs to be rebuilt
boost::this_thread::interruption_point();
// Regtest mode doesn't require peers
}
}
}
- catch (boost::thread_interrupted)
+ catch (const boost::thread_interrupted&)
{
LogPrintf("BitcoinMiner terminated\n");
throw;
// 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-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_MINER_H
#define BITCOIN_MINER_H
+#include "primitives/block.h"
+
#include <stdint.h>
-class CBlock;
-class CBlockHeader;
class CBlockIndex;
class CReserveKey;
class CScript;
class CWallet;
-struct CBlockTemplate;
+struct CBlockTemplate
+{
+ CBlock block;
+ std::vector<CAmount> vTxFees;
+ std::vector<int64_t> vTxSigOps;
+};
/** Run the miner threads */
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads);
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
/** Modify the extranonce in a block */
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;
-
#endif // BITCOIN_MINER_H
-// Copyright (c) 2012 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2012 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_MRUSET_H
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include "addrman.h"
#include "chainparams.h"
#include "clientversion.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "ui_interface.h"
+#include "crypto/common.h"
#ifdef WIN32
#include <string.h>
#endif
#endif
-using namespace boost;
using namespace std;
namespace {
return ret;
}
-bool RecvLine(SOCKET hSocket, string& strLine)
-{
- strLine = "";
- while (true)
- {
- char c;
- int nBytes = recv(hSocket, &c, 1, 0);
- if (nBytes > 0)
- {
- if (c == '\n')
- continue;
- if (c == '\r')
- return true;
- strLine += c;
- if (strLine.size() >= 9000)
- return true;
- }
- else if (nBytes <= 0)
- {
- boost::this_thread::interruption_point();
- if (nBytes < 0)
- {
- int nErr = WSAGetLastError();
- if (nErr == WSAEMSGSIZE)
- continue;
- if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
- {
- MilliSleep(10);
- continue;
- }
- }
- if (!strLine.empty())
- return true;
- if (nBytes == 0)
- {
- // socket closed
- LogPrint("net", "socket closed\n");
- return false;
- }
- else
- {
- // socket error
- int nErr = WSAGetLastError();
- LogPrint("net", "recv failed: %s\n", NetworkErrorString(nErr));
- return false;
- }
- }
- }
-}
-
int GetnScore(const CService& addr)
{
LOCK(cs_mapLocalHost);
// Connect
SOCKET hSocket;
- if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort()) : ConnectSocket(addrConnect, hSocket))
+ bool proxyConnectionFailed = false;
+ if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) :
+ ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed))
{
addrman.Attempt(addrConnect);
pnode->nTimeConnected = GetTime();
return pnode;
+ } else if (!proxyConnectionFailed) {
+ // If connecting to the node failed, and failure is not caused by a problem connecting to
+ // the proxy, mark this as an attempt.
+ addrman.Attempt(addrConnect);
}
return NULL;
{
int nBestHeight = g_signals.GetHeight().get_value_or(0);
- /// when NTP implemented, change to just nTime = GetAdjustedTime()
int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
CAddress addrMe = GetLocalAddress(&addr);
X(nLastSend);
X(nLastRecv);
X(nTimeConnected);
+ X(nTimeOffset);
X(addrName);
X(nVersion);
X(cleanSubVer);
// get current incomplete message, or create a new one
if (vRecvMsg.empty() ||
vRecvMsg.back().complete())
- vRecvMsg.push_back(CNetMessage(SER_NETWORK, nRecvVersion));
+ vRecvMsg.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK, nRecvVersion));
CNetMessage& msg = vRecvMsg.back();
if (handled < 0)
return false;
+ if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
+ LogPrint("net", "Oversized message from peer=%i, disconnecting", GetId());
+ return false;
+ }
+
pch += handled;
nBytes -= handled;
try {
hdrbuf >> hdr;
}
- catch (const std::exception &) {
+ catch (const std::exception&) {
return -1;
}
MilliSleep(20*60*1000); // Refresh every 20 minutes
}
}
- catch (boost::thread_interrupted)
+ catch (const boost::thread_interrupted&)
{
r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
- LogPrintf("UPNP_DeletePortMapping() returned : %d\n", r);
+ LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
freeUPNPDevlist(devlist); devlist = 0;
FreeUPNPUrls(&urls);
throw;
#ifdef WIN32
// Get local host IP
- char pszHostName[1000] = "";
+ char pszHostName[256] = "";
if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
{
vector<CNetAddr> vaddr;
{
BOOST_FOREACH (const CNetAddr &addr, vaddr)
{
- AddLocal(addr, LOCAL_IF);
+ if (AddLocal(addr, LOCAL_IF))
+ LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
}
}
}
struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
CNetAddr addr(s4->sin_addr);
if (AddLocal(addr, LOCAL_IF))
- LogPrintf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString());
+ LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
}
else if (ifa->ifa_addr->sa_family == AF_INET6)
{
struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
CNetAddr addr(s6->sin6_addr);
if (AddLocal(addr, LOCAL_IF))
- LogPrintf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString());
+ LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
}
}
freeifaddrs(myaddrs);
}
#endif
-
}
void StartNode(boost::thread_group& threadGroup)
FILE *file = fopen(pathTmp.string().c_str(), "wb");
CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
if (fileout.IsNull())
- return error("%s : Failed to open file %s", __func__, pathTmp.string());
+ return error("%s: Failed to open file %s", __func__, pathTmp.string());
// Write and commit header, data
try {
fileout << ssPeers;
}
- catch (std::exception &e) {
- return error("%s : Serialize or I/O error - %s", __func__, e.what());
+ catch (const std::exception& e) {
+ return error("%s: Serialize or I/O error - %s", __func__, e.what());
}
FileCommit(fileout.Get());
fileout.fclose();
// replace existing peers.dat, if any, with new peers.dat.XXXX
if (!RenameOver(pathTmp, pathAddr))
- return error("%s : Rename-into-place failed", __func__);
+ return error("%s: Rename-into-place failed", __func__);
return true;
}
FILE *file = fopen(pathAddr.string().c_str(), "rb");
CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
if (filein.IsNull())
- return error("%s : Failed to open file %s", __func__, pathAddr.string());
+ return error("%s: Failed to open file %s", __func__, pathAddr.string());
// use file size to size memory buffer
int fileSize = boost::filesystem::file_size(pathAddr);
filein.read((char *)&vchData[0], dataSize);
filein >> hashIn;
}
- catch (std::exception &e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
filein.fclose();
// verify stored checksum matches input data
uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
if (hashIn != hashTmp)
- return error("%s : Checksum mismatch, data corrupted", __func__);
+ return error("%s: Checksum mismatch, data corrupted", __func__);
unsigned char pchMsgTmp[4];
try {
// ... verify the network matches ours
if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
- return error("%s : Invalid network magic number", __func__);
+ return error("%s: Invalid network magic number", __func__);
// de-serialize address data into one CAddrMan object
ssPeers >> addr;
}
- catch (std::exception &e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
return true;
nSendBytes = 0;
nRecvBytes = 0;
nTimeConnected = GetTime();
+ nTimeOffset = 0;
addr = addrIn;
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
nVersion = 0;
nRefCount = 0;
nSendSize = 0;
nSendOffset = 0;
- hashContinue = 0;
+ hashContinue = uint256();
nStartingHeight = -1;
fGetAddr = false;
fRelayTxes = false;
{
ENTER_CRITICAL_SECTION(cs_vSend);
assert(ssSend.size() == 0);
- ssSend << CMessageHeader(pszCommand, 0);
- LogPrint("net", "sending: %s ", pszCommand);
+ ssSend << CMessageHeader(Params().MessageStart(), pszCommand, 0);
+ LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
}
void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
// Set the size
unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
- memcpy((char*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], &nSize, sizeof(nSize));
+ WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
// Set the checksum
uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_NET_H
static const int TIMEOUT_INTERVAL = 20 * 60;
/** The maximum number of entries in an 'inv' protocol message */
static const unsigned int MAX_INV_SZ = 50000;
+/** The maximum number of new addresses to accumulate before announcing. */
+static const unsigned int MAX_ADDR_TO_SEND = 1000;
+/** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */
+static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024;
/** -listen default */
static const bool DEFAULT_LISTEN = true;
/** -upnp default */
unsigned int SendBufferSize();
void AddOneShot(std::string strDest);
-bool RecvLine(SOCKET hSocket, std::string& strLine);
void AddressCurrentlyConnected(const CService& addr);
CNode* FindNode(const CNetAddr& ip);
CNode* FindNode(const std::string& addrName);
typedef int NodeId;
+struct CombinerAll
+{
+ typedef bool result_type;
+
+ template<typename I>
+ bool operator()(I first, I last) const
+ {
+ while (first != last) {
+ if (!(*first)) return false;
+ ++first;
+ }
+ return true;
+ }
+};
+
// Signals for message handling
struct CNodeSignals
{
boost::signals2::signal<int ()> GetHeight;
- boost::signals2::signal<bool (CNode*)> ProcessMessages;
- boost::signals2::signal<bool (CNode*, bool)> SendMessages;
+ boost::signals2::signal<bool (CNode*), CombinerAll> ProcessMessages;
+ boost::signals2::signal<bool (CNode*, bool), CombinerAll> SendMessages;
boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
boost::signals2::signal<void (NodeId)> FinalizeNode;
};
int64_t nLastSend;
int64_t nLastRecv;
int64_t nTimeConnected;
+ int64_t nTimeOffset;
std::string addrName;
int nVersion;
std::string cleanSubVer;
int64_t nTime; // time (in microseconds) of message receipt.
- CNetMessage(int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), vRecv(nTypeIn, nVersionIn) {
+ CNetMessage(const CMessageHeader::MessageStartChars& pchMessageStartIn, int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), hdr(pchMessageStartIn), vRecv(nTypeIn, nVersionIn) {
hdrbuf.resize(24);
in_data = false;
nHdrPos = 0;
int64_t nLastSend;
int64_t nLastRecv;
int64_t nTimeConnected;
+ int64_t nTimeOffset;
CAddress addr;
std::string addrName;
CService addrLocal;
// Known checking here is only to save space from duplicates.
// SendMessages will filter it again for knowns that were added
// after addresses were pushed.
- if (addr.IsValid() && !setAddrKnown.count(addr))
- vAddrToSend.push_back(addr);
+ if (addr.IsValid() && !setAddrKnown.count(addr)) {
+ if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) {
+ vAddrToSend[insecure_rand() % vAddrToSend.size()] = addr;
+ } else {
+ vAddrToSend.push_back(addr);
+ }
+ }
}
}
}
- bool IsSubscribed(unsigned int nChannel);
- void Subscribe(unsigned int nChannel, unsigned int nHops=0);
- void CancelSubscribe(unsigned int nChannel);
void CloseSocketDisconnect();
// Denial-of-service detection/prevention
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifdef HAVE_CONFIG_H
-#include "bitcoin-config.h"
+#include "config/bitcoin-config.h"
#endif
#include "netbase.h"
return false;
}
-bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
+bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
{
proxyType proxy;
+ if (outProxyConnectionFailed)
+ *outProxyConnectionFailed = false;
// no proxy needed (none set for target network)
if (!GetProxy(addrDest.GetNetwork(), proxy))
return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout);
SOCKET hSocket = INVALID_SOCKET;
// first connect to proxy server
- if (!ConnectSocketDirectly(proxy, hSocket, nTimeout))
+ if (!ConnectSocketDirectly(proxy, hSocket, nTimeout)) {
+ if (outProxyConnectionFailed)
+ *outProxyConnectionFailed = true;
return false;
+ }
// do socks negotiation
if (!Socks5(addrDest.ToStringIP(), addrDest.GetPort(), hSocket))
return false;
return true;
}
-bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout)
+bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed)
{
string strDest;
int port = portDefault;
+
+ if (outProxyConnectionFailed)
+ *outProxyConnectionFailed = false;
+
SplitHostPort(string(pszDest), port, strDest);
SOCKET hSocket = INVALID_SOCKET;
if (!HaveNameProxy())
return false;
// first connect to name proxy server
- if (!ConnectSocketDirectly(nameProxy, hSocket, nTimeout))
+ if (!ConnectSocketDirectly(nameProxy, hSocket, nTimeout)) {
+ if (outProxyConnectionFailed)
+ *outProxyConnectionFailed = true;
return false;
+ }
// do socks negotiation
if (!Socks5(strDest, (unsigned short)port, hSocket))
return false;
-// Copyright (c) 2009-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_NETBASE_H
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(FLATDATA(ip));
unsigned short portN = htons(port);
- READWRITE(portN);
+ READWRITE(FLATDATA(portN));
if (ser_action.ForRead())
port = ntohs(portN);
}
bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true);
bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault = 0, bool fAllowLookup = true, unsigned int nMaxSolutions = 0);
bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0);
-bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout);
-bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault = 0, int nTimeout = nConnectTimeout);
+bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed = 0);
+bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed = 0);
/** Return readable error string for a network error code */
std::string NetworkErrorString(int err);
/** Close socket and set hSocket to INVALID_SOCKET */
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "noui.h"
-// Copyright (c) 2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_NOUI_H
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "pow.h"
+#include "arith_uint256.h"
#include "chain.h"
#include "chainparams.h"
-#include "core/block.h"
+#include "primitives/block.h"
#include "uint256.h"
#include "util.h"
if (pindexLast == NULL)
return nProofOfWorkLimit;
- // Only change once per interval
- if ((pindexLast->nHeight+1) % Params().Interval() != 0)
+ // Only change once per difficulty adjustment interval
+ if ((pindexLast->nHeight+1) % Params().DifficultyAdjustmentInterval() != 0)
{
if (Params().AllowMinDifficultyBlocks())
{
{
// Return the last non-special-min-difficulty-rules-block
const CBlockIndex* pindex = pindexLast;
- while (pindex->pprev && pindex->nHeight % Params().Interval() != 0 && pindex->nBits == nProofOfWorkLimit)
+ while (pindex->pprev && pindex->nHeight % Params().DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
pindex = pindex->pprev;
return pindex->nBits;
}
// Go back by what we want to be 14 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
- for (int i = 0; pindexFirst && i < Params().Interval()-1; i++)
+ for (int i = 0; pindexFirst && i < Params().DifficultyAdjustmentInterval()-1; i++)
pindexFirst = pindexFirst->pprev;
assert(pindexFirst);
+ return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime());
+}
+
+unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime)
+{
// Limit adjustment step
- int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
+ int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
if (nActualTimespan < Params().TargetTimespan()/4)
nActualTimespan = Params().TargetTimespan()/4;
nActualTimespan = Params().TargetTimespan()*4;
// Retarget
- uint256 bnNew;
- uint256 bnOld;
+ arith_uint256 bnNew;
+ arith_uint256 bnOld;
bnNew.SetCompact(pindexLast->nBits);
bnOld = bnNew;
bnNew *= nActualTimespan;
{
bool fNegative;
bool fOverflow;
- uint256 bnTarget;
-
- if (Params().SkipProofOfWorkCheck())
- return true;
+ arith_uint256 bnTarget;
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
// Check range
if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit())
- return error("CheckProofOfWork() : nBits below minimum work");
+ return error("CheckProofOfWork(): nBits below minimum work");
// Check proof of work matches claimed amount
- if (hash > bnTarget)
- return error("CheckProofOfWork() : hash doesn't match nBits");
+ if (UintToArith256(hash) > bnTarget)
+ return error("CheckProofOfWork(): hash doesn't match nBits");
return true;
}
-uint256 GetBlockProof(const CBlockIndex& block)
+arith_uint256 GetBlockProof(const CBlockIndex& block)
{
- uint256 bnTarget;
+ arith_uint256 bnTarget;
bool fNegative;
bool 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
- // as it's too large for a uint256. However, as 2**256 is at least as large
+ // as it's too large for a arith_uint256. However, as 2**256 is at least as large
// as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
// or ~bnTarget / (nTarget+1) + 1.
return (~bnTarget / (bnTarget + 1)) + 1;
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_POW_H
class CBlockHeader;
class CBlockIndex;
class uint256;
+class arith_uint256;
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock);
+unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime);
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
-uint256 GetBlockProof(const CBlockIndex& block);
+arith_uint256 GetBlockProof(const CBlockIndex& block);
#endif // BITCOIN_POW_H
--- /dev/null
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "primitives/block.h"
+
+#include "hash.h"
+#include "tinyformat.h"
+#include "utilstrencodings.h"
+#include "crypto/common.h"
+
+uint256 CBlockHeader::GetHash() const
+{
+ return SerializeHash(*this);
+}
+
+uint256 CBlock::BuildMerkleTree(bool* fMutated) const
+{
+ /* WARNING! If you're reading this because you're learning about crypto
+ and/or designing a new system that will use merkle trees, keep in mind
+ that the following merkle tree algorithm has a serious flaw related to
+ duplicate txids, resulting in a vulnerability (CVE-2012-2459).
+
+ The reason is that if the number of hashes in the list at a given time
+ is odd, the last one is duplicated before computing the next level (which
+ is unusual in Merkle trees). This results in certain sequences of
+ transactions leading to the same merkle root. For example, these two
+ trees:
+
+ A A
+ / \ / \
+ B C B C
+ / \ | / \ / \
+ D E F D E F F
+ / \ / \ / \ / \ / \ / \ / \
+ 1 2 3 4 5 6 1 2 3 4 5 6 5 6
+
+ for transaction lists [1,2,3,4,5,6] and [1,2,3,4,5,6,5,6] (where 5 and
+ 6 are repeated) result in the same root hash A (because the hash of both
+ of (F) and (F,F) is C).
+
+ The vulnerability results from being able to send a block with such a
+ transaction list, with the same merkle root, and the same block hash as
+ the original without duplication, resulting in failed validation. If the
+ receiving node proceeds to mark that block as permanently invalid
+ however, it will fail to accept further unmodified (and thus potentially
+ valid) versions of the same block. We defend against this by detecting
+ the case where we would hash two identical hashes at the end of the list
+ together, and treating that identically to the block having an invalid
+ merkle root. Assuming no double-SHA256 collisions, this will detect all
+ known ways of changing the transactions without affecting the merkle
+ root.
+ */
+ vMerkleTree.clear();
+ vMerkleTree.reserve(vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes.
+ for (std::vector<CTransaction>::const_iterator it(vtx.begin()); it != vtx.end(); ++it)
+ vMerkleTree.push_back(it->GetHash());
+ int j = 0;
+ bool mutated = false;
+ for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
+ {
+ for (int i = 0; i < nSize; i += 2)
+ {
+ int i2 = std::min(i+1, nSize-1);
+ if (i2 == i + 1 && i2 + 1 == nSize && vMerkleTree[j+i] == vMerkleTree[j+i2]) {
+ // Two identical hashes at the end of the list at a particular level.
+ mutated = true;
+ }
+ vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]),
+ BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
+ }
+ j += nSize;
+ }
+ if (fMutated) {
+ *fMutated = mutated;
+ }
+ return (vMerkleTree.empty() ? uint256() : vMerkleTree.back());
+}
+
+std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
+{
+ if (vMerkleTree.empty())
+ BuildMerkleTree();
+ std::vector<uint256> vMerkleBranch;
+ int j = 0;
+ for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
+ {
+ int i = std::min(nIndex^1, nSize-1);
+ vMerkleBranch.push_back(vMerkleTree[j+i]);
+ nIndex >>= 1;
+ j += nSize;
+ }
+ return vMerkleBranch;
+}
+
+uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
+{
+ if (nIndex == -1)
+ return uint256();
+ for (std::vector<uint256>::const_iterator it(vMerkleBranch.begin()); it != vMerkleBranch.end(); ++it)
+ {
+ if (nIndex & 1)
+ hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash));
+ else
+ hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it));
+ nIndex >>= 1;
+ }
+ return hash;
+}
+
+std::string CBlock::ToString() const
+{
+ std::stringstream s;
+ s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
+ GetHash().ToString(),
+ nVersion,
+ hashPrevBlock.ToString(),
+ hashMerkleRoot.ToString(),
+ nTime, nBits, nNonce,
+ vtx.size());
+ for (unsigned int i = 0; i < vtx.size(); i++)
+ {
+ s << " " << vtx[i].ToString() << "\n";
+ }
+ s << " vMerkleTree: ";
+ for (unsigned int i = 0; i < vMerkleTree.size(); i++)
+ s << " " << vMerkleTree[i].ToString();
+ s << "\n";
+ return s.str();
+}
--- /dev/null
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_PRIMITIVES_BLOCK_H
+#define BITCOIN_PRIMITIVES_BLOCK_H
+
+#include "primitives/transaction.h"
+#include "serialize.h"
+#include "uint256.h"
+
+/** The maximum allowed size for a serialized block, in bytes (network rule) */
+static const unsigned int MAX_BLOCK_SIZE = 1000000;
+
+/** Nodes collect new transactions into a block, hash them into a hash tree,
+ * and scan through nonce values to make the block's hash satisfy proof-of-work
+ * requirements. When they solve the proof-of-work, they broadcast the block
+ * to everyone and the block is added to the block chain. The first transaction
+ * in the block is a special one that creates a new coin owned by the creator
+ * of the block.
+ */
+class CBlockHeader
+{
+public:
+ // header
+ static const int32_t CURRENT_VERSION=3;
+ int32_t nVersion;
+ uint256 hashPrevBlock;
+ uint256 hashMerkleRoot;
+ uint32_t nTime;
+ uint32_t nBits;
+ uint32_t nNonce;
+
+ CBlockHeader()
+ {
+ SetNull();
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(this->nVersion);
+ nVersion = this->nVersion;
+ READWRITE(hashPrevBlock);
+ READWRITE(hashMerkleRoot);
+ READWRITE(nTime);
+ READWRITE(nBits);
+ READWRITE(nNonce);
+ }
+
+ void SetNull()
+ {
+ nVersion = CBlockHeader::CURRENT_VERSION;
+ hashPrevBlock.SetNull();
+ hashMerkleRoot.SetNull();
+ nTime = 0;
+ nBits = 0;
+ nNonce = 0;
+ }
+
+ bool IsNull() const
+ {
+ return (nBits == 0);
+ }
+
+ uint256 GetHash() const;
+
+ int64_t GetBlockTime() const
+ {
+ return (int64_t)nTime;
+ }
+};
+
+
+class CBlock : public CBlockHeader
+{
+public:
+ // network and disk
+ std::vector<CTransaction> vtx;
+
+ // memory only
+ mutable std::vector<uint256> vMerkleTree;
+
+ CBlock()
+ {
+ SetNull();
+ }
+
+ CBlock(const CBlockHeader &header)
+ {
+ SetNull();
+ *((CBlockHeader*)this) = header;
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(*(CBlockHeader*)this);
+ READWRITE(vtx);
+ }
+
+ void SetNull()
+ {
+ CBlockHeader::SetNull();
+ vtx.clear();
+ vMerkleTree.clear();
+ }
+
+ CBlockHeader GetBlockHeader() const
+ {
+ CBlockHeader block;
+ block.nVersion = nVersion;
+ block.hashPrevBlock = hashPrevBlock;
+ block.hashMerkleRoot = hashMerkleRoot;
+ block.nTime = nTime;
+ block.nBits = nBits;
+ block.nNonce = nNonce;
+ return block;
+ }
+
+ // Build the in-memory merkle tree for this block and return the merkle root.
+ // If non-NULL, *mutated is set to whether mutation was detected in the merkle
+ // tree (a duplication of transactions in the block leading to an identical
+ // merkle root).
+ uint256 BuildMerkleTree(bool* mutated = NULL) const;
+
+ std::vector<uint256> GetMerkleBranch(int nIndex) const;
+ static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex);
+ std::string ToString() const;
+};
+
+
+/** Describes a place in the block chain to another node such that if the
+ * other node doesn't have the same branch, it can find a recent common trunk.
+ * The further back it is, the further before the fork it may be.
+ */
+struct CBlockLocator
+{
+ std::vector<uint256> vHave;
+
+ CBlockLocator() {}
+
+ CBlockLocator(const std::vector<uint256>& vHaveIn)
+ {
+ vHave = vHaveIn;
+ }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (!(nType & SER_GETHASH))
+ READWRITE(nVersion);
+ READWRITE(vHave);
+ }
+
+ void SetNull()
+ {
+ vHave.clear();
+ }
+
+ bool IsNull() const
+ {
+ return vHave.empty();
+ }
+};
+
+#endif // BITCOIN_PRIMITIVES_BLOCK_H
--- /dev/null
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "primitives/transaction.h"
+
+#include "hash.h"
+#include "tinyformat.h"
+#include "utilstrencodings.h"
+
+std::string COutPoint::ToString() const
+{
+ return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n);
+}
+
+CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn)
+{
+ prevout = prevoutIn;
+ scriptSig = scriptSigIn;
+ nSequence = nSequenceIn;
+}
+
+CTxIn::CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn)
+{
+ prevout = COutPoint(hashPrevTx, nOut);
+ scriptSig = scriptSigIn;
+ nSequence = nSequenceIn;
+}
+
+std::string CTxIn::ToString() const
+{
+ std::string str;
+ str += "CTxIn(";
+ str += prevout.ToString();
+ if (prevout.IsNull())
+ str += strprintf(", coinbase %s", HexStr(scriptSig));
+ else
+ str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24));
+ if (nSequence != std::numeric_limits<unsigned int>::max())
+ str += strprintf(", nSequence=%u", nSequence);
+ str += ")";
+ return str;
+}
+
+CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn)
+{
+ nValue = nValueIn;
+ scriptPubKey = scriptPubKeyIn;
+}
+
+uint256 CTxOut::GetHash() const
+{
+ return SerializeHash(*this);
+}
+
+std::string CTxOut::ToString() const
+{
+ return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30));
+}
+
+CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}
+CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {}
+
+uint256 CMutableTransaction::GetHash() const
+{
+ return SerializeHash(*this);
+}
+
+void CTransaction::UpdateHash() const
+{
+ *const_cast<uint256*>(&hash) = SerializeHash(*this);
+}
+
+CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { }
+
+CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {
+ UpdateHash();
+}
+
+CTransaction& CTransaction::operator=(const CTransaction &tx) {
+ *const_cast<int*>(&nVersion) = tx.nVersion;
+ *const_cast<std::vector<CTxIn>*>(&vin) = tx.vin;
+ *const_cast<std::vector<CTxOut>*>(&vout) = tx.vout;
+ *const_cast<unsigned int*>(&nLockTime) = tx.nLockTime;
+ *const_cast<uint256*>(&hash) = tx.hash;
+ return *this;
+}
+
+CAmount CTransaction::GetValueOut() const
+{
+ CAmount nValueOut = 0;
+ for (std::vector<CTxOut>::const_iterator it(vout.begin()); it != vout.end(); ++it)
+ {
+ nValueOut += it->nValue;
+ if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut))
+ throw std::runtime_error("CTransaction::GetValueOut(): value out of range");
+ }
+ return nValueOut;
+}
+
+double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const
+{
+ nTxSize = CalculateModifiedSize(nTxSize);
+ if (nTxSize == 0) return 0.0;
+
+ return dPriorityInputs / nTxSize;
+}
+
+unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const
+{
+ // In order to avoid disincentivizing cleaning up the UTXO set we don't count
+ // the constant overhead for each txin and up to 110 bytes of scriptSig (which
+ // is enough to cover a compressed pubkey p2sh redemption) for priority.
+ // Providing any more cleanup incentive than making additional inputs free would
+ // risk encouraging people to create junk outputs to redeem later.
+ if (nTxSize == 0)
+ nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
+ for (std::vector<CTxIn>::const_iterator it(vin.begin()); it != vin.end(); ++it)
+ {
+ unsigned int offset = 41U + std::min(110U, (unsigned int)it->scriptSig.size());
+ if (nTxSize > offset)
+ nTxSize -= offset;
+ }
+ return nTxSize;
+}
+
+std::string CTransaction::ToString() const
+{
+ std::string str;
+ str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
+ GetHash().ToString().substr(0,10),
+ nVersion,
+ vin.size(),
+ vout.size(),
+ nLockTime);
+ for (unsigned int i = 0; i < vin.size(); i++)
+ str += " " + vin[i].ToString() + "\n";
+ for (unsigned int i = 0; i < vout.size(); i++)
+ str += " " + vout[i].ToString() + "\n";
+ return str;
+}
--- /dev/null
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_PRIMITIVES_TRANSACTION_H
+#define BITCOIN_PRIMITIVES_TRANSACTION_H
+
+#include "amount.h"
+#include "script/script.h"
+#include "serialize.h"
+#include "uint256.h"
+
+/** An outpoint - a combination of a transaction hash and an index n into its vout */
+class COutPoint
+{
+public:
+ uint256 hash;
+ uint32_t n;
+
+ COutPoint() { SetNull(); }
+ COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; }
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(hash);
+ READWRITE(n);
+ }
+
+ void SetNull() { hash.SetNull(); n = (uint32_t) -1; }
+ bool IsNull() const { return (hash.IsNull() && n == (uint32_t) -1); }
+
+ friend bool operator<(const COutPoint& a, const COutPoint& b)
+ {
+ return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
+ }
+
+ friend bool operator==(const COutPoint& a, const COutPoint& b)
+ {
+ return (a.hash == b.hash && a.n == b.n);
+ }
+
+ friend bool operator!=(const COutPoint& a, const COutPoint& b)
+ {
+ return !(a == b);
+ }
+
+ std::string ToString() const;
+};
+
+/** An input of a transaction. It contains the location of the previous
+ * transaction's output that it claims and a signature that matches the
+ * output's public key.
+ */
+class CTxIn
+{
+public:
+ COutPoint prevout;
+ CScript scriptSig;
+ uint32_t nSequence;
+
+ CTxIn()
+ {
+ nSequence = std::numeric_limits<unsigned int>::max();
+ }
+
+ explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<unsigned int>::max());
+ CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=std::numeric_limits<uint32_t>::max());
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(prevout);
+ READWRITE(scriptSig);
+ READWRITE(nSequence);
+ }
+
+ bool IsFinal() const
+ {
+ return (nSequence == std::numeric_limits<uint32_t>::max());
+ }
+
+ friend bool operator==(const CTxIn& a, const CTxIn& b)
+ {
+ return (a.prevout == b.prevout &&
+ a.scriptSig == b.scriptSig &&
+ a.nSequence == b.nSequence);
+ }
+
+ friend bool operator!=(const CTxIn& a, const CTxIn& b)
+ {
+ return !(a == b);
+ }
+
+ std::string ToString() const;
+};
+
+/** An output of a transaction. It contains the public key that the next input
+ * must be able to sign with to claim it.
+ */
+class CTxOut
+{
+public:
+ CAmount nValue;
+ CScript scriptPubKey;
+
+ CTxOut()
+ {
+ SetNull();
+ }
+
+ CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(nValue);
+ READWRITE(scriptPubKey);
+ }
+
+ void SetNull()
+ {
+ nValue = -1;
+ scriptPubKey.clear();
+ }
+
+ bool IsNull() const
+ {
+ return (nValue == -1);
+ }
+
+ uint256 GetHash() const;
+
+ CAmount GetDustThreshold(const CFeeRate &minRelayTxFee) const
+ {
+ // "Dust" is defined in terms of CTransaction::minRelayTxFee,
+ // which has units satoshis-per-kilobyte.
+ // If you'd pay more than 1/3 in fees
+ // to spend something, then we consider it dust.
+ // A typical txout is 34 bytes big, and will
+ // need a CTxIn of at least 148 bytes to spend:
+ // so dust is a txout less than 546 satoshis
+ // with default minRelayTxFee.
+ size_t nSize = GetSerializeSize(SER_DISK,0)+148u;
+ return 3*minRelayTxFee.GetFee(nSize);
+ }
+
+ bool IsDust(const CFeeRate &minRelayTxFee) const
+ {
+ return (nValue < GetDustThreshold(minRelayTxFee));
+ }
+
+ friend bool operator==(const CTxOut& a, const CTxOut& b)
+ {
+ return (a.nValue == b.nValue &&
+ a.scriptPubKey == b.scriptPubKey);
+ }
+
+ friend bool operator!=(const CTxOut& a, const CTxOut& b)
+ {
+ return !(a == b);
+ }
+
+ std::string ToString() const;
+};
+
+struct CMutableTransaction;
+
+/** The basic transaction that is broadcasted on the network and contained in
+ * blocks. A transaction can contain multiple inputs and outputs.
+ */
+class CTransaction
+{
+private:
+ /** Memory only. */
+ const uint256 hash;
+ void UpdateHash() const;
+
+public:
+ static const int32_t CURRENT_VERSION=1;
+
+ // The local variables are made const to prevent unintended modification
+ // without updating the cached hash value. However, CTransaction is not
+ // actually immutable; deserialization and assignment are implemented,
+ // and bypass the constness. This is safe, as they update the entire
+ // structure, including the hash.
+ const int32_t nVersion;
+ const std::vector<CTxIn> vin;
+ const std::vector<CTxOut> vout;
+ const uint32_t nLockTime;
+
+ /** Construct a CTransaction that qualifies as IsNull() */
+ CTransaction();
+
+ /** Convert a CMutableTransaction into a CTransaction. */
+ CTransaction(const CMutableTransaction &tx);
+
+ CTransaction& operator=(const CTransaction& tx);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(*const_cast<int32_t*>(&this->nVersion));
+ nVersion = this->nVersion;
+ READWRITE(*const_cast<std::vector<CTxIn>*>(&vin));
+ READWRITE(*const_cast<std::vector<CTxOut>*>(&vout));
+ READWRITE(*const_cast<uint32_t*>(&nLockTime));
+ if (ser_action.ForRead())
+ UpdateHash();
+ }
+
+ bool IsNull() const {
+ return vin.empty() && vout.empty();
+ }
+
+ const uint256& GetHash() const {
+ return hash;
+ }
+
+ // Return sum of txouts.
+ CAmount GetValueOut() const;
+ // GetValueIn() is a method on CCoinsViewCache, because
+ // inputs must be known to compute value in.
+
+ // Compute priority, given priority of inputs and (optionally) tx size
+ double ComputePriority(double dPriorityInputs, unsigned int nTxSize=0) const;
+
+ // Compute modified tx size for priority calculation (optionally given tx size)
+ unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;
+
+ bool IsCoinBase() const
+ {
+ return (vin.size() == 1 && vin[0].prevout.IsNull());
+ }
+
+ friend bool operator==(const CTransaction& a, const CTransaction& b)
+ {
+ return a.hash == b.hash;
+ }
+
+ friend bool operator!=(const CTransaction& a, const CTransaction& b)
+ {
+ return a.hash != b.hash;
+ }
+
+ std::string ToString() const;
+};
+
+/** A mutable version of CTransaction. */
+struct CMutableTransaction
+{
+ int32_t nVersion;
+ std::vector<CTxIn> vin;
+ std::vector<CTxOut> vout;
+ uint32_t nLockTime;
+
+ CMutableTransaction();
+ CMutableTransaction(const CTransaction& tx);
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(this->nVersion);
+ nVersion = this->nVersion;
+ READWRITE(vin);
+ READWRITE(vout);
+ READWRITE(nLockTime);
+ }
+
+ /** Compute the hash of this CMutableTransaction. This is computed on the
+ * fly, as opposed to GetHash() in CTransaction, which uses a cached result.
+ */
+ uint256 GetHash() const;
+};
+
+#endif // BITCOIN_PRIMITIVES_TRANSACTION_H
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "protocol.h"
-#include "chainparams.h"
#include "util.h"
#include "utilstrencodings.h"
"filtered block"
};
-CMessageHeader::CMessageHeader()
+CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn)
{
- memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
+ memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
memset(pchCommand, 0, sizeof(pchCommand));
nMessageSize = -1;
nChecksum = 0;
}
-CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
+CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
{
- memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
+ memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
memset(pchCommand, 0, sizeof(pchCommand));
strncpy(pchCommand, pszCommand, COMMAND_SIZE);
nMessageSize = nMessageSizeIn;
return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
}
-bool CMessageHeader::IsValid() const
+bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const
{
// Check start string
- if (memcmp(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0)
+ if (memcmp(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE) != 0)
return false;
// Check the command string for errors
// Message size
if (nMessageSize > MAX_SIZE)
{
- LogPrintf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize);
+ LogPrintf("CMessageHeader::IsValid(): (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize);
return false;
}
CInv::CInv()
{
type = 0;
- hash = 0;
+ hash.SetNull();
}
CInv::CInv(int typeIn, const uint256& hashIn)
}
}
if (i == ARRAYLEN(ppszTypeName))
- throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType));
+ throw std::out_of_range(strprintf("CInv::CInv(string, uint256): unknown type '%s'", strType));
hash = hashIn;
}
const char* CInv::GetCommand() const
{
if (!IsKnownType())
- throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
+ throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type));
return ppszTypeName[type];
}
// 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-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef __cplusplus
class CMessageHeader
{
public:
- CMessageHeader();
- CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn);
+ typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
+
+ CMessageHeader(const MessageStartChars& pchMessageStartIn);
+ CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn);
std::string GetCommand() const;
- bool IsValid() const;
+ bool IsValid(const MessageStartChars& messageStart) const;
ADD_SERIALIZE_METHODS;
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "pubkey.h"
-#include "crypto/sha2.h"
#include "eccryptoverify.h"
-#ifdef USE_SECP256K1
-#include <secp256k1.h>
-#else
#include "ecwrapper.h"
-#endif
bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
if (!IsValid())
return false;
-#ifdef USE_SECP256K1
- if (secp256k1_ecdsa_verify((const unsigned char*)&hash, 32, &vchSig[0], vchSig.size(), begin(), size()) != 1)
- return false;
-#else
CECKey key;
if (!key.SetPubKey(begin(), size()))
return false;
if (!key.Verify(hash, vchSig))
return false;
-#endif
return true;
}
return false;
int recid = (vchSig[0] - 27) & 3;
bool fComp = ((vchSig[0] - 27) & 4) != 0;
-#ifdef USE_SECP256K1
- int pubkeylen = 65;
- if (!secp256k1_ecdsa_recover_compact((const unsigned char*)&hash, 32, &vchSig[1], (unsigned char*)begin(), &pubkeylen, fComp, recid))
- return false;
- assert((int)size() == pubkeylen);
-#else
CECKey key;
if (!key.Recover(hash, &vchSig[1], recid))
return false;
std::vector<unsigned char> pubkey;
key.GetPubKey(pubkey, fComp);
Set(pubkey.begin(), pubkey.end());
-#endif
return true;
}
bool CPubKey::IsFullyValid() const {
if (!IsValid())
return false;
-#ifdef USE_SECP256K1
- if (!secp256k1_ecdsa_pubkey_verify(begin(), size()))
- return false;
-#else
CECKey key;
if (!key.SetPubKey(begin(), size()))
return false;
-#endif
return true;
}
bool CPubKey::Decompress() {
if (!IsValid())
return false;
-#ifdef USE_SECP256K1
- int clen = size();
- int ret = secp256k1_ecdsa_pubkey_decompress((unsigned char*)begin(), &clen);
- assert(ret);
- assert(clen == (int)size());
-#else
CECKey key;
if (!key.SetPubKey(begin(), size()))
return false;
std::vector<unsigned char> pubkey;
key.GetPubKey(pubkey, false);
Set(pubkey.begin(), pubkey.end());
-#endif
return true;
}
unsigned char out[64];
BIP32Hash(cc, nChild, *begin(), begin()+1, out);
memcpy(ccChild, out+32, 32);
-#ifdef USE_SECP256K1
- pubkeyChild = *this;
- bool ret = secp256k1_ecdsa_pubkey_tweak_add((unsigned char*)pubkeyChild.begin(), pubkeyChild.size(), out);
-#else
CECKey key;
bool ret = key.SetPubKey(begin(), size());
ret &= key.TweakPublic(out);
std::vector<unsigned char> pubkey;
key.GetPubKey(pubkey, true);
pubkeyChild.Set(pubkey.begin(), pubkey.end());
-#endif
return ret;
}
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
class CKeyID : public uint160
{
public:
- CKeyID() : uint160(0) {}
+ CKeyID() : uint160() {}
CKeyID(const uint160& in) : uint160(in) {}
};
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include "csvmodelwriter.h"
#include "editaddressdialog.h"
#include "guiutil.h"
+#include "scicon.h"
#include <QIcon>
#include <QMenu>
ui->copyAddress->setIcon(QIcon());
ui->deleteAddress->setIcon(QIcon());
ui->exportButton->setIcon(QIcon());
+#else
+ ui->newAddress->setIcon(SingleColorIcon(":/icons/add"));
+ ui->copyAddress->setIcon(SingleColorIcon(":/icons/editcopy"));
+ ui->deleteAddress->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->exportButton->setIcon(SingleColorIcon(":/icons/export"));
#endif
switch(mode)
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_ADDRESSBOOKPAGE_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "addresstablemodel.h"
case CT_NEW:
if(inModel)
{
- qWarning() << "AddressTablePriv::updateEntry : Warning: Got CT_NEW, but entry is already in model";
+ qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_NEW, but entry is already in model";
break;
}
parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex);
case CT_UPDATED:
if(!inModel)
{
- qWarning() << "AddressTablePriv::updateEntry : Warning: Got CT_UPDATED, but entry is not in model";
+ qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_UPDATED, but entry is not in model";
break;
}
lower->type = newEntryType;
case CT_DELETED:
if(!inModel)
{
- qWarning() << "AddressTablePriv::updateEntry : Warning: Got CT_DELETED, but entry is not in model";
+ qWarning() << "AddressTablePriv::updateEntry: Warning: Got CT_DELETED, but entry is not in model";
break;
}
parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_ADDRESSTABLEMODEL_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "askpassphrasedialog.h"
{
QMessageBox::warning(this, tr("Wallet encrypted"),
"<qt>" +
- tr("Bitcoin will close now to finish the encryption process. "
+ tr("Bitcoin Core 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.") +
"<br><br><b>" +
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_ASKPASSPHRASEDIALOG_H
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-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.
#if defined(HAVE_CONFIG_H)
return QCoreApplication::translate("bitcoin-core", psz).toStdString();
}
+static QString GetLangTerritory()
+{
+ QSettings settings;
+ // Get desired locale (e.g. "de_DE")
+ // 1) System default language
+ QString lang_territory = QLocale::system().name();
+ // 2) Language from QSettings
+ QString lang_territory_qsettings = settings.value("language", "").toString();
+ if(!lang_territory_qsettings.isEmpty())
+ lang_territory = lang_territory_qsettings;
+ // 3) -lang command line argument
+ lang_territory = QString::fromStdString(GetArg("-lang", lang_territory.toStdString()));
+ return lang_territory;
+}
+
/** Set up translations */
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
{
- QSettings settings;
// Remove old translators
QApplication::removeTranslator(&qtTranslatorBase);
// Get desired locale (e.g. "de_DE")
// 1) System default language
- QString lang_territory = QLocale::system().name();
- // 2) Language from QSettings
- QString lang_territory_qsettings = settings.value("language", "").toString();
- if(!lang_territory_qsettings.isEmpty())
- lang_territory = lang_territory_qsettings;
- // 3) -lang command line argument
- lang_territory = QString::fromStdString(GetArg("-lang", lang_territory.toStdString()));
+ QString lang_territory = GetLangTerritory();
// Convert to "de" only by truncating "_DE"
QString lang = lang_territory;
boost::thread_group threadGroup;
/// Pass fatal exception message to UI thread
- void handleRunawayException(std::exception *e);
+ void handleRunawayException(const std::exception *e);
};
/** Main Bitcoin application object */
{
}
-void BitcoinCore::handleRunawayException(std::exception *e)
+void BitcoinCore::handleRunawayException(const std::exception *e)
{
PrintExceptionContinue(e, "Runaway exception");
emit runawayException(QString::fromStdString(strMiscWarning));
StartDummyRPCThread();
}
emit initializeResult(rv);
- } catch (std::exception& e) {
+ } catch (const std::exception& e) {
handleRunawayException(&e);
} catch (...) {
handleRunawayException(NULL);
Shutdown();
qDebug() << __func__ << ": Shutdown finished";
emit shutdownResult(1);
- } catch (std::exception& e) {
+ } catch (const std::exception& e) {
handleRunawayException(&e);
} catch (...) {
handleRunawayException(NULL);
Q_INIT_RESOURCE(bitcoin);
Q_INIT_RESOURCE(bitcoin_locale);
- GUIUtil::SubstituteFonts();
-
BitcoinApplication app(argc, argv);
#if QT_VERSION > 0x050100
// Generate high-dpi pixmaps
QApplication::setOrganizationName(QAPP_ORG_NAME);
QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
+ GUIUtil::SubstituteFonts(GetLangTerritory());
/// 4. Initialization of translations, so that intro dialog is in user's language
// Now that QSettings are accessible, initialize translations
}
try {
ReadConfigFile(mapArgs, mapMultiArgs);
- } catch(std::exception &e) {
+ } catch (const std::exception& e) {
QMessageBox::critical(0, QObject::tr("Bitcoin Core"),
QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what()));
return false;
}
#ifdef ENABLE_WALLET
// Parse URIs on command line -- this can affect Params()
- if (!PaymentServer::ipcParseCommandLine(argc, argv))
- exit(0);
+ PaymentServer::ipcParseCommandLine(argc, argv);
#endif
+
QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(QString::fromStdString(Params().NetworkIDString())));
assert(!networkStyle.isNull());
// Allow for separate UI settings for testnets
app.exec();
app.requestShutdown();
app.exec();
- } catch (std::exception& e) {
+ } catch (const std::exception& e) {
PrintExceptionContinue(&e, "Runaway exception");
app.handleRunawayException(QString::fromStdString(strMiscWarning));
} catch (...) {
<file alias="address-book">res/icons/address-book.png</file>
<file alias="quit">res/icons/quit.png</file>
<file alias="send">res/icons/send.png</file>
- <file alias="connect_0">res/icons/connect0_16.png</file>
- <file alias="connect_1">res/icons/connect1_16.png</file>
- <file alias="connect_2">res/icons/connect2_16.png</file>
- <file alias="connect_3">res/icons/connect3_16.png</file>
- <file alias="connect_4">res/icons/connect4_16.png</file>
+ <file alias="connect_0">res/icons/connect0.png</file>
+ <file alias="connect_1">res/icons/connect1.png</file>
+ <file alias="connect_2">res/icons/connect2.png</file>
+ <file alias="connect_3">res/icons/connect3.png</file>
+ <file alias="connect_4">res/icons/connect4.png</file>
<file alias="transaction_0">res/icons/transaction0.png</file>
<file alias="transaction_confirmed">res/icons/transaction2.png</file>
<file alias="transaction_conflicted">res/icons/transaction_conflicted.png</file>
<file alias="editpaste">res/icons/editpaste.png</file>
<file alias="editcopy">res/icons/editcopy.png</file>
<file alias="add">res/icons/add.png</file>
- <file alias="bitcoin_testnet">res/icons/bitcoin_testnet.png</file>
<file alias="edit">res/icons/edit.png</file>
<file alias="history">res/icons/history.png</file>
<file alias="overview">res/icons/overview.png</file>
<file alias="tx_input">res/icons/tx_input.png</file>
<file alias="tx_output">res/icons/tx_output.png</file>
<file alias="tx_inout">res/icons/tx_inout.png</file>
- <file alias="unit_btc">res/icons/unit_btc.png</file>
- <file alias="unit_mbtc">res/icons/unit_mbtc.png</file>
- <file alias="unit_ubtc">res/icons/unit_ubtc.png</file>
<file alias="lock_closed">res/icons/lock_closed.png</file>
<file alias="lock_open">res/icons/lock_open.png</file>
<file alias="key">res/icons/key.png</file>
<file alias="filesave">res/icons/filesave.png</file>
- <file alias="qrcode">res/icons/qrcode.png</file>
<file alias="debugwindow">res/icons/debugwindow.png</file>
- </qresource>
- <qresource prefix="/images">
- <file alias="about">res/images/about.png</file>
- <file alias="splash">res/images/splash.png</file>
- <file alias="splash_testnet">res/images/splash_testnet.png</file>
+ <file alias="open">res/icons/open.png</file>
+ <file alias="info">res/icons/info.png</file>
+ <file alias="about">res/icons/about.png</file>
+ <file alias="about_qt">res/icons/about_qt.png</file>
+ <file alias="verify">res/icons/verify.png</file>
</qresource>
<qresource prefix="/movies">
<file alias="spinner-000">res/movies/spinner-000.png</file>
<file alias="spinner-032">res/movies/spinner-032.png</file>
<file alias="spinner-033">res/movies/spinner-033.png</file>
<file alias="spinner-034">res/movies/spinner-034.png</file>
+ <file alias="spinner-035">res/movies/spinner-035.png</file>
</qresource>
</RCC>
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "bitcoinaddressvalidator.h"
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-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.
#ifndef BITCOIN_QT_BITCOINADDRESSVALIDATOR_H
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "bitcoinamountfield.h"
class AmountSpinBox: public QAbstractSpinBox
{
Q_OBJECT
+
public:
explicit AmountSpinBox(QWidget *parent):
QAbstractSpinBox(parent),
setValue(val);
}
- StepEnabled stepEnabled() const
- {
- StepEnabled rv = 0;
- if(text().isEmpty()) // Allow step-up with empty field
- return StepUpEnabled;
- bool valid = false;
- CAmount val = value(&valid);
- if(valid)
- {
- if(val > 0)
- rv |= StepDownEnabled;
- if(val < BitcoinUnits::maxMoney())
- rv |= StepUpEnabled;
- }
- return rv;
- }
-
void setDisplayUnit(int unit)
{
bool valid = false;
}
return cachedMinimumSizeHint;
}
+
private:
int currentUnit;
CAmount singleStep;
return QAbstractSpinBox::event(event);
}
+ StepEnabled stepEnabled() const
+ {
+ if (isReadOnly()) // Disable steps when AmountSpinBox is read-only
+ return StepNone;
+ if (text().isEmpty()) // Allow step-up with empty field
+ return StepUpEnabled;
+
+ StepEnabled rv = 0;
+ bool valid = false;
+ CAmount val = value(&valid);
+ if(valid)
+ {
+ if(val > 0)
+ rv |= StepDownEnabled;
+ if(val < BitcoinUnits::maxMoney())
+ rv |= StepUpEnabled;
+ }
+ return rv;
+ }
+
signals:
void valueChanged();
};
void BitcoinAmountField::setReadOnly(bool fReadOnly)
{
amount->setReadOnly(fReadOnly);
- unit->setEnabled(!fReadOnly);
}
void BitcoinAmountField::unitChanged(int idx)
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_BITCOINAMOUNTFIELD_H
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "bitcoingui.h"
#include "optionsdialog.h"
#include "optionsmodel.h"
#include "rpcconsole.h"
+#include "scicon.h"
#include "utilitydialog.h"
#ifdef ENABLE_WALLET
#include <QDateTime>
#include <QDesktopWidget>
#include <QDragEnterEvent>
-#include <QIcon>
#include <QListWidget>
#include <QMenuBar>
#include <QMessageBox>
historyAction(0),
quitAction(0),
sendCoinsAction(0),
+ sendCoinsMenuAction(0),
usedSendingAddressesAction(0),
usedReceivingAddressesAction(0),
signMessageAction(0),
verifyMessageAction(0),
aboutAction(0),
receiveCoinsAction(0),
+ receiveCoinsMenuAction(0),
optionsAction(0),
toggleHideAction(0),
encryptWalletAction(0),
}
windowTitle += " " + networkStyle->getTitleAddText();
#ifndef Q_OS_MAC
- QApplication::setWindowIcon(networkStyle->getAppIcon());
- setWindowIcon(networkStyle->getAppIcon());
+ QApplication::setWindowIcon(networkStyle->getTrayAndWindowIcon());
+ setWindowIcon(networkStyle->getTrayAndWindowIcon());
#else
MacDockIconHandler::instance()->setIcon(networkStyle->getAppIcon());
#endif
setUnifiedTitleAndToolBarOnMac(true);
#endif
- rpcConsole = new RPCConsole(enableWallet ? this : 0);
+ rpcConsole = new RPCConsole(0);
#ifdef ENABLE_WALLET
if(enableWallet)
{
// Create actions for the toolbar, menu bar and tray/dock icon
// Needs walletFrame to be initialized
- createActions(networkStyle);
+ createActions();
// Create application menu bar
createMenuBar();
// Create status bar
statusBar();
+
+ // Disable size grip because it looks ugly and nobody needs it
+ statusBar()->setSizeGripEnabled(false);
// Status bar notification icons
QFrame *frameBlocks = new QFrame();
trayIcon->hide();
#ifdef Q_OS_MAC
delete appMenuBar;
- MacDockIconHandler::instance()->setMainWindow(NULL);
+ MacDockIconHandler::cleanup();
#endif
+
+ delete rpcConsole;
}
-void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
+void BitcoinGUI::createActions()
{
QActionGroup *tabGroup = new QActionGroup(this);
- overviewAction = new QAction(QIcon(":/icons/overview"), tr("&Overview"), this);
+ overviewAction = new QAction(SingleColorIcon(":/icons/overview"), tr("&Overview"), this);
overviewAction->setStatusTip(tr("Show general overview of wallet"));
overviewAction->setToolTip(overviewAction->statusTip());
overviewAction->setCheckable(true);
overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1));
tabGroup->addAction(overviewAction);
- sendCoinsAction = new QAction(QIcon(":/icons/send"), tr("&Send"), this);
+ sendCoinsAction = new QAction(SingleColorIcon(":/icons/send"), tr("&Send"), this);
sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address"));
sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
sendCoinsAction->setCheckable(true);
sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
tabGroup->addAction(sendCoinsAction);
- receiveCoinsAction = new QAction(QIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
+ sendCoinsMenuAction = new QAction(TextColorIcon(":/icons/send"), sendCoinsAction->text(), this);
+ sendCoinsMenuAction->setStatusTip(sendCoinsAction->statusTip());
+ sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip());
+
+ receiveCoinsAction = new QAction(SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)"));
receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
receiveCoinsAction->setCheckable(true);
receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
tabGroup->addAction(receiveCoinsAction);
- historyAction = new QAction(QIcon(":/icons/history"), tr("&Transactions"), this);
+ receiveCoinsMenuAction = new QAction(TextColorIcon(":/icons/receiving_addresses"), receiveCoinsAction->text(), this);
+ receiveCoinsMenuAction->setStatusTip(receiveCoinsAction->statusTip());
+ receiveCoinsMenuAction->setToolTip(receiveCoinsMenuAction->statusTip());
+
+ historyAction = new QAction(SingleColorIcon(":/icons/history"), tr("&Transactions"), this);
historyAction->setStatusTip(tr("Browse transaction history"));
historyAction->setToolTip(historyAction->statusTip());
historyAction->setCheckable(true);
connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage()));
connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
+ connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
+ connect(sendCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
+ connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
+ connect(receiveCoinsMenuAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
#endif // ENABLE_WALLET
- quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this);
+ quitAction = new QAction(TextColorIcon(":/icons/quit"), tr("E&xit"), this);
quitAction->setStatusTip(tr("Quit application"));
quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
quitAction->setMenuRole(QAction::QuitRole);
- aboutAction = new QAction(networkStyle->getAppIcon(), tr("&About Bitcoin Core"), this);
+ aboutAction = new QAction(TextColorIcon(":/icons/about"), tr("&About Bitcoin Core"), this);
aboutAction->setStatusTip(tr("Show information about Bitcoin Core"));
aboutAction->setMenuRole(QAction::AboutRole);
-#if QT_VERSION < 0x050000
- aboutQtAction = new QAction(QIcon(":/trolltech/qmessagebox/images/qtlogo-64.png"), tr("About &Qt"), this);
-#else
- aboutQtAction = new QAction(QIcon(":/qt-project.org/qmessagebox/images/qtlogo-64.png"), tr("About &Qt"), this);
-#endif
+ aboutQtAction = new QAction(TextColorIcon(":/icons/about_qt"), tr("About &Qt"), this);
aboutQtAction->setStatusTip(tr("Show information about Qt"));
aboutQtAction->setMenuRole(QAction::AboutQtRole);
- optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this);
- optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin"));
+ optionsAction = new QAction(TextColorIcon(":/icons/options"), tr("&Options..."), this);
+ optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin Core"));
optionsAction->setMenuRole(QAction::PreferencesRole);
- toggleHideAction = new QAction(networkStyle->getAppIcon(), tr("&Show / Hide"), this);
+ toggleHideAction = new QAction(TextColorIcon(":/icons/about"), tr("&Show / Hide"), this);
toggleHideAction->setStatusTip(tr("Show or hide the main Window"));
- encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
+ encryptWalletAction = new QAction(TextColorIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet"));
encryptWalletAction->setCheckable(true);
- backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet..."), this);
+ backupWalletAction = new QAction(TextColorIcon(":/icons/filesave"), tr("&Backup Wallet..."), this);
backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
- changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this);
+ changePassphraseAction = new QAction(TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this);
changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
- signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this);
+ signMessageAction = new QAction(TextColorIcon(":/icons/edit"), tr("Sign &message..."), this);
signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
- verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this);
+ verifyMessageAction = new QAction(TextColorIcon(":/icons/verify"), tr("&Verify message..."), this);
verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
- openRPCConsoleAction = new QAction(QIcon(":/icons/debugwindow"), tr("&Debug window"), this);
+ openRPCConsoleAction = new QAction(TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this);
openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console"));
- usedSendingAddressesAction = new QAction(QIcon(":/icons/address-book"), tr("&Sending addresses..."), this);
+ usedSendingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Sending addresses..."), this);
usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels"));
- usedReceivingAddressesAction = new QAction(QIcon(":/icons/address-book"), tr("&Receiving addresses..."), this);
+ usedReceivingAddressesAction = new QAction(TextColorIcon(":/icons/address-book"), tr("&Receiving addresses..."), this);
usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels"));
- openAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_FileIcon), tr("Open &URI..."), this);
+ openAction = new QAction(TextColorIcon(":/icons/open"), tr("Open &URI..."), this);
openAction->setStatusTip(tr("Open a bitcoin: URI or payment request"));
- showHelpMessageAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation), tr("&Command-line options"), this);
+ showHelpMessageAction = new QAction(TextColorIcon(":/icons/info"), tr("&Command-line options"), this);
+ showHelpMessageAction->setMenuRole(QAction::NoRole);
showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options"));
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
setNumConnections(clientModel->getNumConnections());
connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
- setNumBlocks(clientModel->getNumBlocks());
- connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
+ setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate());
+ connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
// Receive and report messages from client model
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
{
overviewAction->setEnabled(enabled);
sendCoinsAction->setEnabled(enabled);
+ sendCoinsMenuAction->setEnabled(enabled);
receiveCoinsAction->setEnabled(enabled);
+ receiveCoinsMenuAction->setEnabled(enabled);
historyAction->setEnabled(enabled);
encryptWalletAction->setEnabled(enabled);
backupWalletAction->setEnabled(enabled);
trayIcon = new QSystemTrayIcon(this);
QString toolTip = tr("Bitcoin Core client") + " " + networkStyle->getTitleAddText();
trayIcon->setToolTip(toolTip);
- trayIcon->setIcon(networkStyle->getAppIcon());
+ trayIcon->setIcon(networkStyle->getTrayAndWindowIcon());
trayIcon->show();
#endif
// Configuration of the tray icon (or dock icon) icon menu
trayIconMenu->addAction(toggleHideAction);
trayIconMenu->addSeparator();
- trayIconMenu->addAction(sendCoinsAction);
- trayIconMenu->addAction(receiveCoinsAction);
+ trayIconMenu->addAction(sendCoinsMenuAction);
+ trayIconMenu->addAction(receiveCoinsMenuAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(signMessageAction);
trayIconMenu->addAction(verifyMessageAction);
case 7: case 8: case 9: icon = ":/icons/connect_3"; break;
default: icon = ":/icons/connect_4"; break;
}
- labelConnectionsIcon->setPixmap(QIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+ labelConnectionsIcon->setPixmap(SingleColorIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count));
}
-void BitcoinGUI::setNumBlocks(int count)
+void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate)
{
if(!clientModel)
return;
QString tooltip;
- QDateTime lastBlockDate = clientModel->getLastBlockDate();
QDateTime currentDate = QDateTime::currentDateTime();
- int secs = lastBlockDate.secsTo(currentDate);
+ qint64 secs = blockDate.secsTo(currentDate);
tooltip = tr("Processed %n blocks of transaction history.", "", count);
if(secs < 90*60)
{
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
- labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
+ labelBlocksIcon->setPixmap(SingleColorIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
#ifdef ENABLE_WALLET
if(walletFrame)
}
else
{
- int years = secs / YEAR_IN_SECONDS;
- int remainder = secs % YEAR_IN_SECONDS;
+ qint64 years = secs / YEAR_IN_SECONDS;
+ qint64 remainder = secs % YEAR_IN_SECONDS;
timeBehindText = tr("%1 and %2").arg(tr("%n year(s)", "", years)).arg(tr("%n week(s)","", remainder/WEEK_IN_SECONDS));
}
tooltip = tr("Catching up...") + QString("<br>") + tooltip;
if(count != prevBlocks)
{
- labelBlocksIcon->setPixmap(QIcon(QString(
+ labelBlocksIcon->setPixmap(SingleColorIcon(QString(
":/movies/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')))
.pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES;
if(!clientModel->getOptionsModel()->getMinimizeToTray() &&
!clientModel->getOptionsModel()->getMinimizeOnClose())
{
+ // close rpcConsole in case it was open to make some space for the shutdown window
+ rpcConsole->close();
+
QApplication::quit();
}
}
break;
case WalletModel::Unlocked:
labelEncryptionIcon->show();
- labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+ labelEncryptionIcon->setPixmap(SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
encryptWalletAction->setChecked(true);
changePassphraseAction->setEnabled(true);
break;
case WalletModel::Locked:
labelEncryptionIcon->show();
- labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
+ labelEncryptionIcon->setPixmap(SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
encryptWalletAction->setChecked(true);
changePassphraseAction->setEnabled(true);
{
createContextMenu();
setToolTip(tr("Unit to show amounts in. Click to select another unit."));
+ QList<BitcoinUnits::Unit> units = BitcoinUnits::availableUnits();
+ int max_width = 0;
+ const QFontMetrics fm(font());
+ foreach (const BitcoinUnits::Unit unit, units)
+ {
+ max_width = qMax(max_width, fm.width(BitcoinUnits::name(unit)));
+ }
+ setMinimumSize(max_width, 0);
+ setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ setStyleSheet(QString("QLabel { color : %1 }").arg(SingleColor().name()));
}
/** So that it responds to button clicks */
/** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
void UnitDisplayStatusBarControl::updateDisplayUnit(int newUnits)
{
- setPixmap(QIcon(":/icons/unit_" + BitcoinUnits::id(newUnits)).pixmap(31,STATUSBAR_ICONSIZE));
+ setText(BitcoinUnits::name(newUnits));
}
/** Shows context menu with Display Unit options by the mouse coordinates */
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-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.
#ifndef BITCOIN_QT_BITCOINGUI_H
QAction *historyAction;
QAction *quitAction;
QAction *sendCoinsAction;
+ QAction *sendCoinsMenuAction;
QAction *usedSendingAddressesAction;
QAction *usedReceivingAddressesAction;
QAction *signMessageAction;
QAction *verifyMessageAction;
QAction *aboutAction;
QAction *receiveCoinsAction;
+ QAction *receiveCoinsMenuAction;
QAction *optionsAction;
QAction *toggleHideAction;
QAction *encryptWalletAction;
int spinnerFrame;
/** Create the main UI actions. */
- void createActions(const NetworkStyle *networkStyle);
+ void createActions();
/** Create the menu bar and sub-menus. */
void createMenuBar();
/** Create the toolbars */
public slots:
/** Set number of connections shown in the UI */
void setNumConnections(int count);
- /** Set number of blocks shown in the UI */
- void setNumBlocks(int count);
+ /** Set number of blocks and last block date shown in the UI */
+ void setNumBlocks(int count, const QDateTime& blockDate);
/** Notify the user of an event from the core network or transaction handling code.
@param[in] title the message box / notification title
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "bitcoinunits.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include <QStringList>
}
}
-QString BitcoinUnits::id(int unit)
-{
- switch(unit)
- {
- case BTC: return QString("btc");
- case mBTC: return QString("mbtc");
- case uBTC: return QString("ubtc");
- default: return QString("???");
- }
-}
-
QString BitcoinUnits::name(int unit)
{
switch(unit)
QString quotient_str = QString::number(quotient);
QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0');
- // Use SI-stule separators as these are locale indendent and can't be
- // confused with the decimal marker. Rule is to use a thin space every
- // three digits on *both* sides of the decimal point - but only if there
- // are five or more digits
+ // Use SI-style thin space separators as these are locale independent and can't be
+ // confused with the decimal marker.
QChar thin_sp(THIN_SP_CP);
int q_size = quotient_str.size();
if (separators == separatorAlways || (separators == separatorStandard && q_size > 4))
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_BITCOINUNITS_H
static QList<Unit> availableUnits();
//! Is unit ID valid?
static bool valid(int unit);
- //! Identifier, e.g. for image names
- static QString id(int unit);
//! Short name
static QString name(int unit);
//! Longer description
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "clientmodel.h"
#include <stdint.h>
-#include <QDateTime>
#include <QDebug>
#include <QTimer>
optionsModel(optionsModel),
peerTableModel(0),
cachedNumBlocks(0),
- cachedReindexing(0), cachedImporting(0),
- numBlocksAtStartup(-1), pollTimer(0)
+ cachedBlockDate(QDateTime()),
+ cachedReindexing(0),
+ cachedImporting(0),
+ pollTimer(0)
{
peerTableModel = new PeerTableModel(this);
pollTimer = new QTimer(this);
return chainActive.Height();
}
-int ClientModel::getNumBlocksAtStartup()
-{
- if (numBlocksAtStartup == -1) numBlocksAtStartup = getNumBlocks();
- return numBlocksAtStartup;
-}
-
quint64 ClientModel::getTotalBytesRecv() const
{
return CNode::GetTotalBytesRecv();
QDateTime ClientModel::getLastBlockDate() const
{
LOCK(cs_main);
+
if (chainActive.Tip())
return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());
- else
- return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
+
+ return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
}
double ClientModel::getVerificationProgress() const
// periodical polls if the core is holding the locks for a longer time -
// for example, during a wallet rescan.
TRY_LOCK(cs_main, lockMain);
- if(!lockMain)
+ if (!lockMain)
return;
+
// Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change.
// Periodically check and update with a timer.
int newNumBlocks = getNumBlocks();
+ QDateTime newBlockDate = getLastBlockDate();
// check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state
if (cachedNumBlocks != newNumBlocks ||
- cachedReindexing != fReindex || cachedImporting != fImporting)
+ cachedBlockDate != newBlockDate ||
+ cachedReindexing != fReindex ||
+ cachedImporting != fImporting)
{
cachedNumBlocks = newNumBlocks;
+ cachedBlockDate = newBlockDate;
cachedReindexing = fReindex;
cachedImporting = fImporting;
- emit numBlocksChanged(newNumBlocks);
+ emit numBlocksChanged(newNumBlocks, newBlockDate);
}
emit bytesChanged(getTotalBytesRecv(), getTotalBytesSent());
static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
{
- // Too noisy: qDebug() << "NotifyNumConnectionsChanged : " + QString::number(newNumConnections);
+ // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
Q_ARG(int, newNumConnections));
}
static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status)
{
- qDebug() << "NotifyAlertChanged : " + QString::fromStdString(hash.GetHex()) + " status=" + QString::number(status);
+ qDebug() << "NotifyAlertChanged: " + QString::fromStdString(hash.GetHex()) + " status=" + QString::number(status);
QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection,
Q_ARG(QString, QString::fromStdString(hash.GetHex())),
Q_ARG(int, status));
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_CLIENTMODEL_H
#define BITCOIN_QT_CLIENTMODEL_H
#include <QObject>
+#include <QDateTime>
class AddressTableModel;
class OptionsModel;
class CWallet;
QT_BEGIN_NAMESPACE
-class QDateTime;
class QTimer;
QT_END_NAMESPACE
//! Return number of connections, default is in- and outbound (total)
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
int getNumBlocks() const;
- int getNumBlocksAtStartup();
quint64 getTotalBytesRecv() const;
quint64 getTotalBytesSent() const;
PeerTableModel *peerTableModel;
int cachedNumBlocks;
+ QDateTime cachedBlockDate;
bool cachedReindexing;
bool cachedImporting;
- int numBlocksAtStartup;
-
QTimer *pollTimer;
void subscribeToCoreSignals();
signals:
void numConnectionsChanged(int count);
- void numBlocksChanged(int count);
+ void numBlocksChanged(int count, const QDateTime& blockDate);
void alertsChanged(const QString &warnings);
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut);
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "coincontroldialog.h"
#include "guiutil.h"
#include "init.h"
#include "optionsmodel.h"
+#include "scicon.h"
#include "walletmodel.h"
#include "coincontrol.h"
using namespace std;
QList<CAmount> CoinControlDialog::payAmounts;
CCoinControl* CoinControlDialog::coinControl = new CCoinControl();
+bool CoinControlDialog::fSubtractFeeFromAmount = false;
CoinControlDialog::CoinControlDialog(QWidget *parent) :
QDialog(parent),
// (un)select all
connect(ui->pushButtonSelectAll, SIGNAL(clicked()), this, SLOT(buttonSelectAllClicked()));
+ // change coin control first column label due Qt4 bug.
+ // see https://github.com/bitcoin/bitcoin/issues/5716
+ ui->treeWidget->headerItem()->setText(COLUMN_CHECKBOX, QString());
+
ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, 84);
ui->treeWidget->setColumnWidth(COLUMN_AMOUNT, 100);
ui->treeWidget->setColumnWidth(COLUMN_LABEL, 170);
if (item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode)
{
copyTransactionHashAction->setEnabled(true);
- if (model->isLockedCoin(uint256(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()))
+ if (model->isLockedCoin(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()))
{
lockAction->setEnabled(false);
unlockAction->setEnabled(true);
if (contextMenuItem->checkState(COLUMN_CHECKBOX) == Qt::Checked)
contextMenuItem->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
- COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
+ COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
model->lockCoin(outpt);
contextMenuItem->setDisabled(true);
- contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon(":/icons/lock_closed"));
+ contextMenuItem->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed"));
updateLabelLocked();
}
// context menu action: unlock coin
void CoinControlDialog::unlockCoin()
{
- COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
+ COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
model->unlockCoin(outpt);
contextMenuItem->setDisabled(false);
contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon());
// copy label "Fee" to clipboard
void CoinControlDialog::clipboardFee()
{
- GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
}
// copy label "After fee" to clipboard
void CoinControlDialog::clipboardAfterFee()
{
- GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
}
// copy label "Bytes" to clipboard
void CoinControlDialog::clipboardBytes()
{
- GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace(ASYMP_UTF8, ""));
}
// copy label "Priority" to clipboard
// copy label "Change" to clipboard
void CoinControlDialog::clipboardChange()
{
- GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
}
// treeview: sort
{
if (column == COLUMN_CHECKBOX && item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode)
{
- COutPoint outpt(uint256(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt());
+ COutPoint outpt(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt());
if (item->checkState(COLUMN_CHECKBOX) == Qt::Unchecked)
coinControl->UnSelect(outpt);
dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29)); // 29 = 180 - 151 (uncompressed public keys are over the limit. max 151 bytes of the input are ignored for priority)
sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority);
+ // in the subtract fee from amount case, we can tell if zero change already and subtract the bytes, so that fee calculation afterwards is accurate
+ if (CoinControlDialog::fSubtractFeeFromAmount)
+ if (nAmount - nPayAmount == 0)
+ nBytes -= 34;
+
// Fee
nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
if (nPayAmount > 0)
{
- nChange = nAmount - nPayFee - nPayAmount;
+ nChange = nAmount - nPayAmount;
+ if (!CoinControlDialog::fSubtractFeeFromAmount)
+ nChange -= nPayFee;
// Never create dust outputs; if we would, just add the dust to the fee.
if (nChange > 0 && nChange < CENT)
CTxOut txout(nChange, (CScript)vector<unsigned char>(24, 0));
if (txout.IsDust(::minRelayTxFee))
{
- nPayFee += nChange;
- nChange = 0;
+ if (CoinControlDialog::fSubtractFeeFromAmount) // dust-change will be raised until no dust
+ nChange = txout.GetDustThreshold(::minRelayTxFee);
+ else
+ {
+ nPayFee += nChange;
+ nChange = 0;
+ }
}
}
- if (nChange == 0)
+ if (nChange == 0 && !CoinControlDialog::fSubtractFeeFromAmount)
nBytes -= 34;
}
l2->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAmount)); // Amount
l3->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nPayFee)); // Fee
l4->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAfterFee)); // After Fee
- l5->setText(((nBytes > 0) ? "~" : "") + QString::number(nBytes)); // Bytes
+ l5->setText(((nBytes > 0) ? ASYMP_UTF8 : "") + QString::number(nBytes)); // Bytes
l6->setText(sPriorityLabel); // Priority
l7->setText(fDust ? tr("yes") : tr("no")); // Dust
l8->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nChange)); // Change
if (nPayFee > 0 && !(payTxFee.GetFeePerK() > 0 && fPayAtLeastCustomFee && nBytes < 1000))
{
- l3->setText("~" + l3->text());
- l4->setText("~" + l4->text());
- if (nChange > 0)
- l8->setText("~" + l8->text());
+ l3->setText(ASYMP_UTF8 + l3->text());
+ l4->setText(ASYMP_UTF8 + l4->text());
+ if (nChange > 0 && !CoinControlDialog::fSubtractFeeFromAmount)
+ l8->setText(ASYMP_UTF8 + l8->text());
}
// turn labels "red"
COutPoint outpt(txhash, out.i);
coinControl->UnSelect(outpt); // just to be sure
itemOutput->setDisabled(true);
- itemOutput->setIcon(COLUMN_CHECKBOX, QIcon(":/icons/lock_closed"));
+ itemOutput->setIcon(COLUMN_CHECKBOX, SingleColorIcon(":/icons/lock_closed"));
}
// set checkbox
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_COINCONTROLDIALOG_H
class CoinControlDialog;
}
+#define ASYMP_UTF8 "\xE2\x89\x88"
+
class CoinControlDialog : public QDialog
{
Q_OBJECT
static QList<CAmount> payAmounts;
static CCoinControl *coinControl;
+ static bool fSubtractFeeFromAmount;
private:
Ui::CoinControlDialog *ui;
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "coincontroltreewidget.h"
{
event->ignore();
int COLUMN_CHECKBOX = 0;
- this->currentItem()->setCheckState(COLUMN_CHECKBOX, ((this->currentItem()->checkState(COLUMN_CHECKBOX) == Qt::Checked) ? Qt::Unchecked : Qt::Checked));
+ if(this->currentItem())
+ this->currentItem()->setCheckState(COLUMN_CHECKBOX, ((this->currentItem()->checkState(COLUMN_CHECKBOX) == Qt::Checked) ? Qt::Unchecked : Qt::Checked));
}
else if (event->key() == Qt::Key_Escape) // press esc -> close dialog
{
{
this->QTreeWidget::keyPressEvent(event);
}
-}
\ No newline at end of file
+}
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_COINCONTROLTREEWIDGET_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "csvmodelwriter.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_CSVMODELWRITER_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "editaddressdialog.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_EDITADDRESSDIALOG_H
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="toolTip">
- <string>Double-click to edit address or label</string>
+ <string>Right-click to edit address or label</string>
</property>
<property name="tabKeyNavigation">
<bool>false</bool>
<rect>
<x>0</x>
<y>0</y>
- <width>800</width>
+ <width>780</width>
<height>400</height>
</rect>
</property>
- <property name="font">
- <font>
- <pointsize>10</pointsize>
- </font>
- </property>
<property name="windowTitle">
<string notr="true">Bitcoin Core - Command-line options</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>12</number>
+ </property>
+ <property name="topMargin">
+ <number>12</number>
+ </property>
+ <property name="rightMargin">
+ <number>12</number>
+ </property>
+ <property name="bottomMargin">
+ <number>12</number>
+ </property>
<item>
- <widget class="QLabel" name="graphic">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <layout class="QVBoxLayout" name="verticalLayoutLogo" stretch="0,0">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>4</number>
</property>
- <property name="pixmap">
- <pixmap resource="../bitcoin.qrc">:/images/about</pixmap>
+ <property name="rightMargin">
+ <number>0</number>
</property>
- </widget>
+ <item>
+ <widget class="QLabel" name="aboutLogo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../bitcoin.qrc">:/icons/bitcoin</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTextEdit" name="helpMessage">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
<item>
<widget class="QScrollArea" name="scrollArea">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>659</width>
- <height>348</height>
- </rect>
- </property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <widget class="QLabel" name="helpMessageLabel">
+ <widget class="QLabel" name="aboutMessage">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>4</width>
+ <height>4</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
<item>
<widget class="QDialogButtonBox" name="okButton">
<property name="orientation">
<item>
<widget class="QCheckBox" name="bitcoinAtStartup">
<property name="toolTip">
- <string>Automatically start Bitcoin after logging in to the system.</string>
+ <string>Automatically start Bitcoin Core after logging in to the system.</string>
</property>
<property name="text">
- <string>&Start Bitcoin on system login</string>
+ <string>&Start Bitcoin Core on system login</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="minimizeOnClose">
<property name="toolTip">
- <string>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</string>
+ <string>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</string>
</property>
<property name="text">
<string>M&inimize on close</string>
<item>
<widget class="QValueComboBox" name="lang">
<property name="toolTip">
- <string>The user interface language can be set here. This setting will take effect after restarting Bitcoin.</string>
+ <string>The user interface language can be set here. This setting will take effect after restarting Bitcoin Core.</string>
</property>
</widget>
</item>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RPCConsole</class>
- <widget class="QDialog" name="RPCConsole">
+ <widget class="QWidget" name="RPCConsole">
<property name="geometry">
<rect>
<x>0</x>
<item row="15" column="0">
<widget class="QPushButton" name="openDebugLogfileButton">
<property name="toolTip">
- <string>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</string>
+ <string>Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files.</string>
</property>
<property name="text">
<string>&Open</string>
</property>
</widget>
</item>
- <item row="14" column="1">
+ <item row="14" column="0">
+ <widget class="QLabel" name="label_timeoffset">
+ <property name="text">
+ <string>Time Offset</string>
+ </property>
+ </widget>
+ </item>
+ <item row="14" column="2">
+ <widget class="QLabel" name="timeoffset">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="15" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
- <item>
- <widget class="QPushButton" name="buttonMinimizeFee">
- <property name="toolTip">
- <string>collapse fee-settings</string>
- </property>
- <property name="text">
- <string>Minimize</string>
- </property>
- </widget>
- </item>
</layout>
</item>
<item>
</property>
</spacer>
</item>
+ <item>
+ <widget class="QPushButton" name="buttonMinimizeFee">
+ <property name="toolTip">
+ <string>collapse fee-settings</string>
+ </property>
+ <property name="text">
+ <string>Minimize</string>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
<item>
<item>
<widget class="QRadioButton" name="radioCustomPerKilobyte">
<property name="toolTip">
- <string>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.</string>
+ <string>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.</string>
</property>
<property name="text">
<string>per kilobyte</string>
<iconset resource="../bitcoin.qrc">
<normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
</property>
+ <property name="iconSize">
+ <size>
+ <width>22</width>
+ <height>22</height>
+ </size>
+ </property>
<property name="shortcut">
<string>Alt+A</string>
</property>
<iconset resource="../bitcoin.qrc">
<normaloff>:/icons/editpaste</normaloff>:/icons/editpaste</iconset>
</property>
+ <property name="iconSize">
+ <size>
+ <width>22</width>
+ <height>22</height>
+ </size>
+ </property>
<property name="shortcut">
<string>Alt+P</string>
</property>
<iconset resource="../bitcoin.qrc">
<normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
</property>
+ <property name="iconSize">
+ <size>
+ <width>22</width>
+ <height>22</height>
+ </size>
+ </property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="1">
- <widget class="BitcoinAmountField" name="payAmount"/>
+ <layout class="QHBoxLayout" name="horizontalLayoutAmount" stretch="0,1">
+ <item>
+ <widget class="BitcoinAmountField" name="payAmount"/>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkboxSubtractFeeFromAmount">
+ <property name="toolTip">
+ <string>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</string>
+ </property>
+ <property name="text">
+ <string>S&ubtract fee from amount</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="messageLabel">
<item>
<widget class="QLabel" name="infoLabel_SM">
<property name="text">
- <string>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</string>
+ <string>You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
<item>
<widget class="QLabel" name="infoLabel_VM">
<property name="text">
- <string>Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack.</string>
+ <string>Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-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.
#ifndef BITCOIN_QT_GUICONSTANTS_H
/* Maximum allowed URI length */
static const int MAX_URI_LENGTH = 255;
-/* Maximum somewhat-sane size of a payment request file */
-static const int MAX_PAYMENT_REQUEST_SIZE = 50000; // bytes
-
/* QRCodeDialog -- size of exported QR Code image */
#define EXPORT_IMAGE_SIZE 256
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "guiutil.h"
#include "qvalidatedlineedit.h"
#include "walletmodel.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "init.h"
#include "main.h"
#include "protocol.h"
#if BOOST_FILESYSTEM_VERSION >= 3
#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
#endif
+#include <boost/scoped_array.hpp>
#include <QAbstractItemView>
#include <QApplication>
#if defined(Q_OS_MAC)
extern double NSAppKitVersionNumber;
+#if !defined(NSAppKitVersionNumber10_8)
+#define NSAppKitVersionNumber10_8 1187
+#endif
#if !defined(NSAppKitVersionNumber10_9)
#define NSAppKitVersionNumber10_9 1265
#endif
QDesktopServices::openUrl(QUrl::fromLocalFile(boostPathToQString(pathDebug)));
}
-void SubstituteFonts()
+void SubstituteFonts(const QString& language)
{
#if defined(Q_OS_MAC)
// Background:
// If this fallback is not properly loaded, some characters may fail to
// render correctly.
//
+// The same thing happened with 10.10. .Helvetica Neue DeskInterface is now default.
+//
// Solution: If building with the 10.7 SDK or lower and the user's platform
// is 10.9 or higher at runtime, substitute the correct font. This needs to
// happen before the QApplication is created.
#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
- if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_9)
- QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande");
+ if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_8)
+ {
+ if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9)
+ /* On a 10.9 - 10.9.x system */
+ QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande");
+ else
+ {
+ /* 10.10 or later system */
+ if (language == "zh_CN" || language == "zh_TW" || language == "zh_HK") // traditional or simplified Chinese
+ QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Heiti SC");
+ else if (language == "ja") // Japanesee
+ QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Songti SC");
+ else
+ QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Lucida Grande");
+ }
+ }
#endif
#endif
}
#ifdef WIN32
boost::filesystem::path static StartupShortcutPath()
{
+ if (GetBoolArg("-testnet", false))
+ return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (testnet).lnk";
+ else if (GetBoolArg("-regtest", false))
+ return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (regtest).lnk";
+
return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk";
}
bool GetStartOnSystemStartup()
{
- // check for Bitcoin.lnk
+ // check for Bitcoin*.lnk
return boost::filesystem::exists(StartupShortcutPath());
}
// Get a pointer to the IShellLink interface.
IShellLink* psl = NULL;
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
- CLSCTX_INPROC_SERVER, IID_IShellLink,
- reinterpret_cast<void**>(&psl));
+ CLSCTX_INPROC_SERVER, IID_IShellLink,
+ reinterpret_cast<void**>(&psl));
if (SUCCEEDED(hres))
{
TCHAR pszExePath[MAX_PATH];
GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
- TCHAR pszArgs[5] = TEXT("-min");
+ // Start client minimized
+ QString strArgs = "-min";
+ // Set -testnet /-regtest options
+ strArgs += QString::fromStdString(strprintf(" -testnet=%d -regtest=%d", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false)));
+
+#ifdef UNICODE
+ boost::scoped_array<TCHAR> args(new TCHAR[strArgs.length() + 1]);
+ // Convert the QString to TCHAR*
+ strArgs.toWCharArray(args.get());
+ // Add missing '\0'-termination to string
+ args[strArgs.length()] = '\0';
+#endif
// Set the path to the shortcut target
psl->SetPath(pszExePath);
PathRemoveFileSpec(pszExePath);
psl->SetWorkingDirectory(pszExePath);
psl->SetShowCmd(SW_SHOWMINNOACTIVE);
- psl->SetArguments(pszArgs);
+#ifndef UNICODE
+ psl->SetArguments(strArgs.toStdString().c_str());
+#else
+ psl->SetArguments(args.get());
+#endif
// Query IShellLink for the IPersistFile interface for
// saving the shortcut in persistent storage.
IPersistFile* ppf = NULL;
- hres = psl->QueryInterface(IID_IPersistFile,
- reinterpret_cast<void**>(&ppf));
+ hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&ppf));
if (SUCCEEDED(hres))
{
WCHAR pwsz[MAX_PATH];
}
return true;
}
-
#elif defined(Q_OS_LINUX)
// Follow the Desktop Application Autostart Spec:
-// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
+// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
boost::filesystem::path static GetAutostartDir()
{
// Write a bitcoin.desktop file to the autostart directory:
optionFile << "[Desktop Entry]\n";
optionFile << "Type=Application\n";
- optionFile << "Name=Bitcoin\n";
- optionFile << "Exec=" << pszExePath << " -min\n";
+ if (GetBoolArg("-testnet", false))
+ optionFile << "Name=Bitcoin (testnet)\n";
+ else if (GetBoolArg("-regtest", false))
+ optionFile << "Name=Bitcoin (regtest)\n";
+ else
+ optionFile << "Name=Bitcoin\n";
+ optionFile << "Exec=" << pszExePath << strprintf(" -min -testnet=%d -regtest=%d\n", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false));
optionFile << "Terminal=false\n";
optionFile << "Hidden=false\n";
optionFile.close();
LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(listSnapshot, i);
UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes;
CFURLRef currentItemURL = NULL;
- LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL);
+
+#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED >= 10100
+ if(&LSSharedFileListItemCopyResolvedURL)
+ currentItemURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, NULL);
+#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED < 10100
+ else
+ LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL);
+#endif
+#else
+ LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL);
+#endif
+
if(currentItemURL && CFEqual(currentItemURL, findUrl)) {
// found
CFRelease(currentItemURL);
return dPingTime == 0 ? QObject::tr("N/A") : QString(QObject::tr("%1 ms")).arg(QString::number((int)(dPingTime * 1000), 10));
}
+QString formatTimeOffset(int64_t nTimeOffset)
+{
+ return QString(QObject::tr("%1 s")).arg(QString::number((int)nTimeOffset, 10));
+}
+
} // namespace GUIUtil
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_GUIUTIL_H
void openDebugLogfile();
// Replace invalid default fonts with known good ones
- void SubstituteFonts();
+ void SubstituteFonts(const QString& language);
/** Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text
representation if needed. This assures that Qt can word-wrap long tooltip messages.
/* Format a CNodeCombinedStats.dPingTime into a user-readable string or display N/A, if 0*/
QString formatPingTime(double dPingTime);
-
+
+ /* Format a CNodeCombinedStats.nTimeOffset into a user-readable string. */
+ QString formatTimeOffset(int64_t nTimeOffset);
+
#if defined(Q_OS_MAC) && QT_VERSION >= 0x050000
// workaround for Qt OSX Bug:
// https://bugreports.qt-project.org/browse/QTBUG-15631
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "intro.h"
#include "ui_intro.h"
#include "guiutil.h"
+#include "scicon.h"
#include "util.h"
replyMessage = tr("Path already exists, and is not a directory.");
}
}
- } catch(fs::filesystem_error &e)
+ } catch (const fs::filesystem_error&)
{
/* Parent directory does not exist or is not accessible */
replyStatus = ST_ERROR;
/* If current default data directory does not exist, let the user choose one */
Intro intro;
intro.setDataDirectory(dataDir);
- intro.setWindowIcon(QIcon(":icons/bitcoin"));
+ intro.setWindowIcon(SingleColorIcon(":icons/bitcoin"));
while(true)
{
try {
TryCreateDirectory(GUIUtil::qstringToBoostPath(dataDir));
break;
- } catch(fs::filesystem_error &e) {
+ } catch (const fs::filesystem_error&) {
QMessageBox::critical(0, tr("Bitcoin Core"),
tr("Error: Specified data directory \"%1\" cannot be created.").arg(dataDir));
/* fall through, back to choosing screen */
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_INTRO_H
-<TS language="ach" version="2.1">
+<TS language="ach" version="2.0">
<context>
<name>AddressBookPage</name>
</context>
-<TS language="af_ZA" version="2.1">
+<TS language="af_ZA" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Bedrag</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Adres</translation>
- </message>
<message>
<source>Date</source>
<translation>Datum</translation>
-<TS language="ar" version="2.1">
+<TS language="ar" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>المبلغ</translation>
</message>
- <message>
- <source>Address</source>
- <translation>عنوان</translation>
- </message>
<message>
<source>Date</source>
<translation>التاريخ</translation>
<source>high</source>
<translation>عالي</translation>
</message>
+ <message>
+ <source>medium-high</source>
+ <translation>متوسط-مرتفع</translation>
+ </message>
<message>
<source>low</source>
<translation>منخفض</translation>
<source>&Main</source>
<translation>&الرئيسي</translation>
</message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>ادفع &رسوم المعاملة</translation>
- </message>
<message>
<source>MB</source>
<translation>م ب</translation>
-<TS language="be_BY" version="2.1">
+<TS language="be_BY" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Колькасць</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Адрас</translation>
- </message>
<message>
<source>Date</source>
<translation>Дата</translation>
-<TS language="bg" version="2.1">
+<TS language="bg" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Сума</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Адрес</translation>
- </message>
<message>
<source>Date</source>
<translation>Дата</translation>
<source>&Main</source>
<translation>&Основни</translation>
</message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>&Такса за изходяща трансакция</translation>
- </message>
<message>
<source>&Start Bitcoin on system login</source>
<translation>&Пускане на Биткоин при вход в системата</translation>
-<TS language="bs" version="2.1">
+<TS language="bs" version="2.0">
<context>
<name>AddressBookPage</name>
</context>
-<TS language="ca" version="2.1">
+<TS language="ca" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Selecció de l'adreça de control de monedes</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Quantitat:</translation>
<source>Amount</source>
<translation>Quantitat</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Adreça</translation>
- </message>
<message>
<source>Date</source>
<translation>Data</translation>
<source>&Main</source>
<translation>&Principal</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Comissió opcional de transacció per kB que ajuda a assegurar que les transaccions es processen ràpidament. La majoria de transaccions són d'1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Paga &comissió de transacció</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Inicia automàticament el Bitcoin després de l'inici de sessió del sistema.</translation>
<source>Allow incoming connections</source>
<translation>Permet connexions entrants</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Connecta a través d'un proxy SOCKS (proxy per defecte):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
<translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation>
</message>
- <message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>Distribuït sota la llicència de programari MIT/X11. Vegeu el fitxer acompanyant COPYING o <http://www.opensource.org/licenses/mit-license.php>.</translation>
- </message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation>
-<TS language="ca@valencia" version="2.1">
+<TS language="ca@valencia" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Selecció de l'adreça de control de monedes</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Quantitat:</translation>
<source>Amount</source>
<translation>Quantitat</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Adreça</translation>
- </message>
<message>
<source>Date</source>
<translation>Data</translation>
<source>&Main</source>
<translation>&Principal</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Comissió opcional de transacció per kB que ajuda a assegurar que les transaccions es processen ràpidament. La majoria de transaccions són d'1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Paga &comissió de transacció</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Inicia automàticament el Bitcoin després de l'inici de sessió del sistema.</translation>
<source>Allow incoming connections</source>
<translation>Permet connexions entrants</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Connecta a través d'un proxy SOCKS (proxy per defecte):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
<translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation>
</message>
- <message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>Distribuït sota la llicència de programari MIT/X11. Vegeu el fitxer acompanyant COPYING o <http://www.opensource.org/licenses/mit-license.php>.</translation>
- </message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation>
-<TS language="ca_ES" version="2.1">
+<TS language="ca_ES" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Selecció de l'adreça de control de monedes</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Quantitat:</translation>
<source>Amount</source>
<translation>Quantitat</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Adreça</translation>
- </message>
<message>
<source>Date</source>
<translation>Data</translation>
<source>&Main</source>
<translation>&Principal</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Comissió opcional de transacció per kB que ajuda a assegurar que les transaccions es processen ràpidament. La majoria de transaccions són d'1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Paga &comissió de transacció</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Inicia automàticament el Bitcoin després de l'inici de sessió del sistema.</translation>
<source>Allow incoming connections</source>
<translation>Permet connexions entrants</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Connecta a la xarxa Bitcoin a través d'un proxy SOCKS.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Connecta a través d'un proxy SOCKS (proxy per defecte):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Adreça IP del proxy (p. ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
<translation>Crea fitxers nous amb els permisos per defecte del sistema, en comptes de l'umask 077 (només efectiu amb la funcionalitat de moneder inhabilitada)</translation>
</message>
- <message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>Distribuït sota la llicència de programari MIT/X11. Vegeu el fitxer acompanyant COPYING o <http://www.opensource.org/licenses/mit-license.php>.</translation>
- </message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Error: ha fallat escoltar les connexions entrants (l'escoltament ha retornat l'error %s)</translation>
-<TS language="cmn" version="2.1">
+<TS language="cmn" version="2.0">
<context>
<name>AddressBookPage</name>
</context>
-<TS language="cs" version="2.1">
+<TS language="cs" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Volba adres v rámci ruční správy mincí</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Počet:</translation>
<source>Amount</source>
<translation>Částka</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Adresa</translation>
- </message>
<message>
<source>Date</source>
<translation>Datum</translation>
<source>&Main</source>
<translation>&Hlavní</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Dobrovolný transakční poplatek za každý započatý kB dopomáhá k rychlému zpracování tvých transakcí. Většina transakcí má do 1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Platit &transakční poplatek</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Automaticky spustí Bitcoin po přihlášení do systému.</translation>
<source>Allow incoming connections</source>
<translation>Přijímat příchozí spojení</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Připojí se do Bitcoinové sítě přes SOCKS proxy.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Připojit přes SOCKS proxy (výchozí proxy):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>IP adresa proxy (např. IPv4: 127.0.0.1/IPv6: ::1)</translation>
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
<translation>Vytvářet nové soubory s výchozími systémovými právy namísto umask 077 (uplatní se, pouze pokud je vypnutá funkce peněženky)</translation>
</message>
- <message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>Šířen pod licencí MIT/X11, viz přiložený soubor COPYING nebo <http://www.opensource.org/licenses/mit-license.php>.</translation>
- </message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Chyba: Nelze naslouchat příchozí spojení (listen vrátil chybu %s)</translation>
-<TS language="cy" version="2.1">
+<TS language="cy" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Address</source>
- <translation>Cyfeiriad</translation>
- </message>
<message>
<source>Date</source>
<translation>Dyddiad</translation>
-<TS language="da" version="2.1">
+<TS language="da" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<context>
<name>CoinControlDialog</name>
<message>
- <source>Coin Control Address Selection</source>
- <translation>Adressevalg for coin-styring</translation>
+ <source>Coin Selection</source>
+ <translation>Coin-styring</translation>
</message>
<message>
<source>Quantity:</source>
<translation>Beløb</translation>
</message>
<message>
- <source>Address</source>
- <translation>Adresse</translation>
+ <source>Received with label</source>
+ <translation>Modtaget med mærke</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Modtaget med adresse</translation>
</message>
<message>
<source>Date</source>
<source>&Main</source>
<translation>&Generelt</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Valgfrit transaktionsgebyr pr. kB, der hjælper dine transaktioner med at blive behandlet hurtigt. De fleste transaktioner er på 1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Betal transaktions&gebyr</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Start Bitcoin automatisk, når der logges ind på systemet.</translation>
<source>Allow incoming connections</source>
<translation>Tillad indkommende forbindelser</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Forbind til Bitcoin-netværket gennem en SOCKS-proxy.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Forbind gennem SOCKS-proxy (standard-proxy):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>IP-adresse for proxyen (fx IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Map port using &UPnP</source>
<translation>Konfigurér port vha. &UPnP</translation>
</message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Forbind til Bitcoin-netværket gennem en SOCKS5-proxy.</translation>
+ </message>
+ <message>
+ <source>&Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&Forbind gennem SOCKS5-proxy (standard-proxy):</translation>
+ </message>
<message>
<source>Proxy &IP:</source>
<translation>Proxy-&IP:</translation>
<source>Custom change address</source>
<translation>Tilpasset byttepengeadresse</translation>
</message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Transaktionsgebyr:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Vælg …</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>sammenfold gebyropsætning</translation>
+ </message>
+ <message>
+ <source>Minimize</source>
+ <translation>Minimér</translation>
+ </message>
+ <message>
+ <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>Hvis det brugertilpassede gebyr er sat til 1000 satoshis, og transaktionen kun fylder 250 byte, betaler "pr. kilobyte" kun 250 satoshis i gebyr, mens "mindst" betaler 1000 satoshis. For transaktioner større end en kilobyte betaler begge pr. kilobyte.</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>pr. kilobyte</translation>
+ </message>
+ <message>
+ <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>Hvis det brugertilpassede gebyr er sat til 1000 satoshis, og transaktionen kun fylder 250 byte, betaler "pr. kilobyte" kun 250 satoshis i gebyr, mens "total mindst" betaler 1000 satoshis. For transaktioner større end en kilobyte betaler begge pr. kilobyte.</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>total mindst</translation>
+ </message>
+ <message>
+ <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>Det er helt fint kun at betale det minimale gebyr, så længe den totale transaktionsvolumen er mindre end den plads, der er tilgængelig i blokkene. Men vær opmærksom på, at dette kan ende ud i transaktioner, der aldrig bliver bekræftet, når der bliver større forespørgsel efter bitcoin-transaktioner, end hvad netværket kan bearbejde.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(læs værktøjstippet)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Anbefalet:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Brugertilpasset:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Smart-gebyr er ikke initialiseret endnu. Dette tager typisk nogle få blokke …)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Bekræftelsestid:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>hurtig</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Send som nul-gebyr-transaktion hvis muligt</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(bekræftelse kan tage længere)</translation>
+ </message>
<message>
<source>Send to multiple recipients at once</source>
<translation>Send til flere modtagere på en gang</translation>
<source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
<translation>Transaktionen blev afvist! Dette kan ske, hvis nogle af dine bitcoins i din tegnebog allerede er brugt, som hvis du brugte en kopi af wallet.dat og dine bitcoins er blevet brugt i kopien, men ikke er markeret som brugt her.</translation>
</message>
+ <message>
+ <source>A fee higher than %1 is considered an insanely high fee.</source>
+ <translation>Et gebyr højere end %1 anses som et vanvittigt højt gebyr.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Betal kun det minimale gebyr på %1</translation>
+ </message>
+ <message>
+ <source>Estimated to begin confirmation within %1 block(s).</source>
+ <translation>Bekræftelse vurderes at begynde inden for %1 blok(ke).</translation>
+ </message>
<message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Advarsel: Ugyldig Bitcoin-adresse</translation>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Slet alle transaktioner i tegnebogen og genskab kun disse dele af blokkæden gennem -rescan under opstart</translation>
</message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
+ <translation>Distribueret under MIT-softwarelicensen; se den vedlagte fil COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation>
+ </message>
<message>
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
<translation>Start regressionstesttilstand, som bruger en speciel kæde, hvor blokke kan løses med det samme.</translation>
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
<translation>Opret nye filer med systemstandard for rettigheder i stedet for umask 077 (kun virksomt med tegnebogsfunktionalitet slået fra)</translation>
</message>
- <message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>Distribueret under MIT/X11-softwarelicensen. Se medfølgende fil COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation>
- </message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Fejl: Lytning efter indkommende forbindelser mislykkedes (lytning resultarede i fejl %s)</translation>
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
<translation>Gebyrer (i BTC/Kb) mindre end dette opfattes som nulgebyr for oprettelse af transaktion (standard: %s)</translation>
</message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maksimal størrelse på data i transaktioner til dataoverførsel, som vi videresender og miner (standard: %u)</translation>
+ </message>
<message>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation>Forespørgsel</translation>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Sæt maksimumstørrelse for højprioritet/lavgebyr-transaktioner i byte (standard: %d)</translation>
</message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Sæt antaller af tråde for coin-generering, hvis aktiveret (-1 = alle kerner, standard: %d)</translation>
+ </message>
<message>
<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>Dette produkt indeholder software, der er udviklet af OpenSSL-projektet for brug i OpenSSL-værktøjskassen <https://www.openssl.org/>, samt kryptografisk software, der er skrevet af Eric Young, samt UPnP-software, der er skrevet af Thomas Bernard.</translation>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Send sporings-/fejlsøgningsinformation til konsollen i stedet for debug.log filen</translation>
</message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Send transaktioner som nul-gebyr-transaktioner hvis muligt (standard: %u)</translation>
+ </message>
<message>
<source>Show all debugging options (usage: --help -help-debug)</source>
<translation>Vis alle tilvalg for fejlsøgning (brug: --help -help-debug)</translation>
<source>Output debugging information (default: %u, supplying <category> is optional)</source>
<translation>Udskriv fejlsøgningsinformation (standard: %u, angivelse af <kategori> er valgfri)</translation>
</message>
- <message>
- <source>Set the processor limit for when generation is on (-1 = unlimited, default: %d)</source>
- <translation>Sæt processorbegrænsning for når generering er slået til (-1 = ubegrænset, standard: %d)</translation>
- </message>
<message>
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
<translation>Brug separat SOCS5-proxy for at nå andre knuder via Tor skjulte tjenester (standard: %s)</translation>
-<TS language="de" version="2.1">
+<TS language="de" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<context>
<name>CoinControlDialog</name>
<message>
- <source>Coin Control Address Selection</source>
- <translation>"Coin Control"-Adressauswahl</translation>
+ <source>Coin Selection</source>
+ <translation>Münzauswahl ("Coin Control")</translation>
</message>
<message>
<source>Quantity:</source>
<translation>Betrag</translation>
</message>
<message>
- <source>Address</source>
- <translation>Adresse</translation>
+ <source>Received with label</source>
+ <translation>Empfangen über Bezeichnung</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Empfangen über Adresse</translation>
</message>
<message>
<source>Date</source>
<source>&Main</source>
<translation>&Allgemein</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Optionale Transaktionsgebühr pro kB, die sicherstellt, dass Ihre Transaktionen schnell bearbeitet werden. Die meisten Transaktionen sind 1 kB groß.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Transaktions&gebühr bezahlen</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Bitcoin nach der Anmeldung am System automatisch ausführen.</translation>
<source>Allow incoming connections</source>
<translation>Erlaubt eingehende Verbindungen</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Über einen SOCKS-Proxy mit dem Bitcoin-Netzwerk verbinden.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>Über einen SOCKS-Proxy &verbinden (Standardproxy):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>IP-Adresse des Proxies (z.B. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Map port using &UPnP</source>
<translation>Portweiterleitung via &UPnP</translation>
</message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Über einen SOCKS5-Proxy mit dem Bitcoin-Netzwerk verbinden.</translation>
+ </message>
+ <message>
+ <source>&Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>Über einen SOCKS5-Proxy &verbinden (Standardproxy):</translation>
+ </message>
<message>
<source>Proxy &IP:</source>
<translation>Proxy-&IP:</translation>
<source>Custom change address</source>
<translation>Benutzerdefinierte Wechselgeld-Adresse</translation>
</message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Transaktionsgebühr:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Auswählen...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>Transaktionsgebühreneinstellungen ausblenden</translation>
+ </message>
+ <message>
+ <source>Minimize</source>
+ <translation>Minimieren</translation>
+ </message>
+ <message>
+ <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>Wenn die benutzerdefinierte Gebühr 1000 Satoshis beträgt und die Transaktion nur 250 Byte groß ist, wird bei Auswahl von "pro Kilobyte" eine Gebühr in Höhe von 250 Satoshis, bei Auswahl von "Mindestbetrag" eine Gebühr in Höhe von 1000 Satoshis bezahlt. Bei Transaktionen die Größer als ein Kilobyte sind, werden bei beiden Optionen die Gebühren pro Kilobyte bezahlt.</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>pro Kilobyte</translation>
+ </message>
+ <message>
+ <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>Wenn die benutzerdefinierte Gebühr 1000 Satoshis beträgt und die Transaktion nur 250 Byte groß ist, wird bei Auswahl von "pro Kilobyte" eine Gebühr in Höhe von 250 Satoshis, bei Auswahl von "Mindestbetrag" eine Gebühr in Höhe von 1000 Satoshis bezahlt. Bei Transaktionen die Größer als ein Kilobyte sind, werden bei beiden Optionen die Gebühren pro Kilobyte bezahlt.</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>Mindestbetrag</translation>
+ </message>
+ <message>
+ <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>Nur die minimale Gebühr zu bezahlen ist so lange in Ordnung, wie weniger Transaktionsvolumen als Platz in den Blöcken vorhanden ist. Aber Vorsicht, diese Option kann dazu führen, dass Transaktionen nicht bestätigt werden, wenn mehr Bedarf an Bitcoin-Transaktionen besteht als das Netzwerk verarbeiten kann.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(den Hinweistext lesen)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Empfehlungen:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Benutzerdefiniert:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Intelligente Gebührenlogik ist noch nicht verfügbar. Normalerweise dauert dies einige Blöcke lang...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Bestätigungszeit:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>schnell</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Wenn möglich als gebührenfreie Transaktion senden</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(Bestätigung kann länger dauern)</translation>
+ </message>
<message>
<source>Send to multiple recipients at once</source>
<translation>An mehrere Empfänger auf einmal überweisen</translation>
<source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
<translation>Die Transaktion wurde abgelehnt! Dies kann passieren, wenn einige Bitcoins aus Ihrer Wallet bereits ausgegeben wurden. Beispielsweise weil Sie eine Kopie Ihrer wallet.dat genutzt, die Bitcoins dort ausgegeben haben und dies daher in der derzeit aktiven Wallet nicht vermerkt ist.</translation>
</message>
+ <message>
+ <source>A fee higher than %1 is considered an insanely high fee.</source>
+ <translation>Eine höhere Gebühr als %1 wird als unsinnig hohe Gebühr angesehen.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Nur die minimale Gebühr in Höhe von %1 zahlen</translation>
+ </message>
+ <message>
+ <source>Estimated to begin confirmation within %1 block(s).</source>
+ <translation>Voraussichtlicher Beginn der Bestätigung innerhalb von %1 Blöcken.</translation>
+ </message>
<message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Warnung: Ungültige Bitcoin-Adresse</translation>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Alle Wallet-Transaktionen löschen und nur diese Teilbereiche der Blockkette durch -rescan beim Starten wiederherstellen</translation>
</message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
+ <translation>Veröffentlicht unter der MIT-Softwarelizenz, siehe beiligende Datei COPYING oder <http://www.opensource.org/licenses/mit-license.php>.</translation>
+ </message>
<message>
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
<translation>Regressionstest-Modus aktivieren, der eine spezielle Blockkette nutzt, in der Blöcke sofort gelöst werden können.</translation>
<source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
<translation>Warnung: wallet.dat beschädigt, Datenrettung erfolgreich! Original wallet.dat wurde als wallet.{Zeitstempel}.dat in %s gespeichert. Falls Ihr Kontostand oder Transaktionen nicht korrekt sind, sollten Sie von einer Datensicherung wiederherstellen.</translation>
</message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Gegenstellen die sich von der angegebenen Netzmaske oder IP-Adresse aus verbinden immer zulassen. Kann mehrmals angegeben werden.</translation>
+ </message>
<message>
<source>(default: 1)</source>
<translation>(Standard: 1)</translation>
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
<translation>Neue Dateien mit Standard-Systemrechten erzeugen, anstatt mit umask 077 (nur mit deaktivierter Walletfunktion nutzbar)</translation>
</message>
- <message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>Veröffentlicht unter der MIT/X11-Softwarelizenz, siehe beiligende Datei COPYING oder <http://www.opensource.org/licenses/mit-license.php>.</translation>
- </message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Fehler: Abhören nach eingehenden Verbindungen fehlgeschlagen (listen meldete Fehler %s)</translation>
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
<translation>Niedrigere Gebühren (in BTC/Kb) als diese werden bei der Transaktionserstellung als gebührenfrei angesehen (Standard: %s)</translation>
</message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maximale Datengröße in "Data Carrier"-Transaktionen die weitergeleitet und erarbeitet werden (Standard: %u)</translation>
+ </message>
<message>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation>Adressen von Gegenstellen via DNS-Namensauflösung finden, falls zu wenige Adressen verfügbar sind (Standard: 1, außer bei -connect)</translation>
</message>
<message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
- <translation>Maximale Größe in Byte von Transaktionen hoher Priorität/mit niedrigen Gebühren festlegen (Standard: %d)</translation>
+ <translation>Maximale Größe in Byte von "high-priority/low-fee"-Transaktionen festlegen (Standard: %d)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Maximale Anzahl an Threads zur Bitcoinerzeugung, wenn aktiviert, festlegen (-1 = alle Kerne, Standard: %d)</translation>
</message>
<message>
<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>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Rückverfolgungs- und Debuginformationen an die Konsole senden, anstatt sie in debug.log zu schreiben</translation>
</message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Transaktionen, wenn möglich, als gebührenfreie Transaktion senden (Standard: %u)</translation>
+ </message>
<message>
<source>Show all debugging options (usage: --help -help-debug)</source>
<translation>Zeige alle Debuggingoptionen (Benutzung: --help -help-debug)</translation>
<source>Error loading wallet.dat: Wallet corrupted</source>
<translation>Fehler beim Laden von wallet.dat: Wallet beschädigt</translation>
</message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = TX-Metadaten wie z.B. Accountbesitzer und Zahlungsanforderungsinformationen behalten, 2 = TX-Metadaten verwerfen)</translation>
+ </message>
<message>
<source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source>
<translation>Datenbankaktivitäten vom Arbeitsspeicher-Pool alle <n> Megabyte auf den Datenträger schreiben (Standard: %u)</translation>
<source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
<translation>Legt fest, wie gründlich die Blockverifikation von -checkblocks ist (0-4, Standard: %u)</translation>
</message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source>
+ <translation>Wenn keine Transaktionsgebühr festgelegt wurde eine Gebühr einbeziehen, sodass Transaktionen im Schnitt innerhalb von <n> Blöcken bestätigt werden (Standard: %u)</translation>
+ </message>
<message>
<source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
<translation>Transaktionspriorität und Gebühr pro kB beim Erzeugen von Blöcken protokollieren (Standard: %u)</translation>
<source>Output debugging information (default: %u, supplying <category> is optional)</source>
<translation>Debugginginformationen ausgeben (Standard: %u, <category> anzugeben ist optional)</translation>
</message>
- <message>
- <source>Set the processor limit for when generation is on (-1 = unlimited, default: %d)</source>
- <translation>Legt ein Prozessor-/CPU-Kernlimit fest, wenn CPU-Mining aktiviert ist (-1 = unbegrenzt, Standard: %d)</translation>
- </message>
<message>
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
<translation>Separaten SOCKS5-Proxy verwenden, um Gegenstellen über versteckte Tor-Dienste zu erreichen (Standard: %s)</translation>
<source>Acceptable ciphers (default: %s)</source>
<translation>Zulässige Chiffren (Standard: %s)</translation>
</message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Adressen von Gegenstellen immer über DNS-Namensauflösung abfragen (Standard: %u)</translation>
+ </message>
<message>
<source>Disable safemode, override a real safe mode event (default: %u)</source>
<translation>Sicherheitsmodus deaktivieren, übergeht ein echtes Sicherheitsmodusereignis (Standard: %u)</translation>
<source>Spend unconfirmed change when sending transactions (default: %u)</source>
<translation>Unbestätigtes Wechselgeld darf beim Senden von Transaktionen ausgegeben werden (Standard: %u)</translation>
</message>
+ <message>
+ <source>Stop running after importing blocks from disk (default: %u)</source>
+ <translation>Beenden, nachdem Blöcke vom Datenträger importiert wurden (Standard: %u)</translation>
+ </message>
<message>
<source>Threshold for disconnecting misbehaving peers (default: %u)</source>
<translation>Schwellenwert, um Verbindungen zu sich nicht konform verhaltenden Gegenstellen zu beenden (Standard: %u)</translation>
-<TS language="el_GR" version="2.1">
+<TS language="el_GR" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</message>
<message>
<source>Create a new address</source>
- <translation>Î\94ημιοÏ\8dÏ\81γηÏ\83ε νÎα διεÏ\8dθÏ\85νÏ\83η</translation>
+ <translation>Î\94ημιοÏ\85Ï\81γία νÎαÏ\82 διεÏ\8dθÏ\85νÏ\83ηÏ\82</translation>
</message>
<message>
<source>&New</source>
<source>Choose the address to receive coins with</source>
<translation>Επιλογή διεύθυνσης απ' όπου θα ληφθούν νομίσματα</translation>
</message>
+ <message>
+ <source>C&hoose</source>
+ <translation>Ε&πιλογή</translation>
+ </message>
<message>
<source>Sending addresses</source>
<translation>Διευθύνσεις αποστολής</translation>
<source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
<translation>Αυτές είναι οι Bitcoin διευθύνσεις σας για να λαμβάνετε πληρωμές. Δίνοντας μία ξεχωριστή διεύθυνση σε κάθε αποστολέα, θα μπορείτε να ελέγχετε ποιος σας πληρώνει.</translation>
</message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>Αυτές είναι οι Bitcoin διευθύνσεις σας για να λαμβάνετε πληρωμές. Δίνοντας μία ξεχωριστή διεύθυνση σε κάθε αποστολέα, θα μπορείτε να ελέγχετε ποιος σας πληρώνει.</translation>
+ </message>
<message>
<source>Copy &Label</source>
<translation>Αντιγραφή &επιγραφής</translation>
<source>Exporting Failed</source>
<translation>Η εξαγωγή απέτυχε</translation>
</message>
- </context>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>Παρουσιάστηκε σφάλμα κατά την αποθήκευση της λίστας πορτοφολιών στο %1. Παρακαλώ δοκιμάστε ξανά</translation>
+ </message>
+</context>
<context>
<name>AddressTableModel</name>
<message>
</message>
<message>
<source>New passphrase</source>
- <translation>Νέος κωδικός πρόσβασης</translation>
+ <translation>&Αλλαγή κωδικού</translation>
</message>
<message>
<source>Repeat new passphrase</source>
</message>
<message>
<source>Encrypt wallet</source>
- <translation>Κρυπτογράφησε το πορτοφόλι</translation>
+ <translation>&Κρυπτογράφηση πορτοφολιού</translation>
</message>
<message>
<source>This operation needs your wallet passphrase to unlock the wallet.</source>
<source>Wallet encrypted</source>
<translation>Κρυπτογραφημενο πορτοφολι</translation>
</message>
+ <message>
+ <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>Εισάγετε τον νέο κωδικό πρόσβασης στον πορτοφόλι <br/> Παρακαλώ χρησιμοποιείστε ένα κωδικό με <b> 10 ή περισσότερους τυχαίους χαρακτήρες</b> ή <b> οχτώ ή παραπάνω λέξεις</b>.</translation>
+ </message>
<message>
<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 θα κλεισει τώρα για να τελειώσει την διαδικασία κρυπτογραφησης. Θυμησου ότι κρυπτογραφώντας το πορτοφολι σου δεν μπορείς να προστατέψεις πλήρως τα bitcoins σου από κλοπή στην περίπτωση όπου μολυνθεί ο υπολογιστής σου με κακόβουλο λογισμικό.</translation>
<source>&Overview</source>
<translation>&Επισκόπηση</translation>
</message>
+ <message>
+ <source>Node</source>
+ <translation>Κόμβος</translation>
+ </message>
<message>
<source>Show general overview of wallet</source>
<translation>Εμφάνισε τη γενική εικόνα του πορτοφολιού</translation>
<source>&Change Passphrase...</source>
<translation>&Άλλαξε κωδικο πρόσβασης</translation>
</message>
+ <message>
+ <source>&Sending addresses...</source>
+ <translation>Διευθύνσεις αποστολής</translation>
+ </message>
+ <message>
+ <source>&Receiving addresses...</source>
+ <translation>Διευθύνσεις λήψης</translation>
+ </message>
+ <message>
+ <source>Open &URI...</source>
+ <translation>'Ανοιγμα &URI</translation>
+ </message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Εφαρμογή Bitcoin Core</translation>
+ </message>
<message>
<source>Importing blocks from disk...</source>
<translation>Εισαγωγή μπλοκ από τον σκληρο δίσκο ... </translation>
<source>&Receive</source>
<translation>&Παραλαβή </translation>
</message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Σχετικά με το Bitcoin Core</translation>
+ </message>
<message>
<source>&Show / Hide</source>
<translation>&Εμφάνισε/Κρύψε</translation>
<source>Show the list of used receiving addresses and labels</source>
<translation>Προβολή της λίστας των χρησιμοποιημένων διευθύνσεων και ετικετών λήψεως</translation>
</message>
+ <message>
+ <source>Open a bitcoin: URI or payment request</source>
+ <translation>Άνοιγμα bitcoin: URI αίτησης πληρωμής</translation>
+ </message>
+ <message>
+ <source>&Command-line options</source>
+ <translation>&Επιλογές γραμμής εντολών</translation>
+ </message>
+ <message>
+ <source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
+ <translation>Εμφανιση του Bitcoin-Qt μήνυματος βοήθειας για να πάρετε μια λίστα με τις πιθανές επιλογές Bitcoin γραμμής εντολών.</translation>
+ </message>
<message numerus="yes">
<source>%n active connection(s) to Bitcoin network</source>
<translation><numerusform>%n ενεργή σύνδεση στο δίκτυο Bitcoin</numerusform><numerusform>%n ενεργές συνδέσεις στο δίκτυο Βitcoin</numerusform></translation>
</context>
<context>
<name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>Επιλογή κερμάτων</translation>
+ </message>
<message>
<source>Quantity:</source>
<translation>Ποσότητα:</translation>
<source>Priority:</source>
<translation>Προτεραιότητα:</translation>
</message>
+ <message>
+ <source>Fee:</source>
+ <translation>Ταρίφα</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Σκόνη</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Ταρίφα αλλαγής</translation>
+ </message>
<message>
<source>Change:</source>
<translation>Ρέστα:</translation>
<source>(un)select all</source>
<translation>(από)επιλογή όλων</translation>
</message>
+ <message>
+ <source>Tree mode</source>
+ <translation>Εμφάνιση τύπου δέντρο</translation>
+ </message>
+ <message>
+ <source>List mode</source>
+ <translation>Λίστα εντολών</translation>
+ </message>
<message>
<source>Amount</source>
<translation>Ποσό</translation>
</message>
<message>
- <source>Address</source>
- <translation>Διεύθυνση</translation>
+ <source>Received with label</source>
+ <translation>Παραλήφθηκε με επιγραφή</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Παραλείφθηκε με την εξής διεύθυνση</translation>
</message>
<message>
<source>Date</source>
<source>Copy transaction ID</source>
<translation>Αντιγραφη του ID Συναλλαγής</translation>
</message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>Κλείδωμα αξόδευτων</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>Ξεκλείδωμα αξόδευτων</translation>
+ </message>
<message>
<source>Copy quantity</source>
<translation>Αντιγραφή ποσότητας</translation>
</message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Αντιγραφή ταρίφας</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Αντιγραφή ταρίφας</translation>
+ </message>
<message>
<source>Copy bytes</source>
<translation>Αντιγραφή των byte</translation>
<source>Copy priority</source>
<translation>Αντιγραφή προτεραιότητας</translation>
</message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Αντιγραφή 'σκόνης'</translation>
+ </message>
<message>
<source>Copy change</source>
<translation>Αντιγραφή των ρέστων</translation>
<source>This label turns red, if the transaction size is greater than 1000 bytes.</source>
<translation>Η ετικετα γινετε κοκκινη , αν το μεγεθος της συναλαγης ειναι μεγαλητερο απο 1000 bytes.</translation>
</message>
+ <message>
+ <source>This means a fee of at least %1 per kB is required.</source>
+ <translation>Ελάχιστο χρεώσιμο ποσό τουλάχιστο %1 ανα kB</translation>
+ </message>
+ <message>
+ <source>Transactions with higher priority are more likely to get included into a block.</source>
+ <translation>Συναλλαγές με υψηλότερη προτεραιότητα είναι πιο πιθανό να περιλαμβάνονται σε ένα μπλοκ.</translation>
+ </message>
+ <message>
+ <source>This label turns red, if the priority is smaller than "medium".</source>
+ <translation>Η ετικέτα γίνεται κόκκινη , αν το μέγεθος της συναλαγής είναι μεγαλύτερο απο το ",μεσαίο",</translation>
+ </message>
+ <message>
+ <source>This label turns red, if any recipient receives an amount smaller than %1.</source>
+ <translation>Η ετικέτα γίνεται κόκκινη , αν ο παραλήπτης παραλάβει ένα ποσό μικρότερο απο %1.</translation>
+ </message>
<message>
<source>(no label)</source>
<translation>(χωρίς ετικέτα)</translation>
<source>The label associated with this address list entry</source>
<translation>Η ετικέτα που συνδέεται με αυτήν την καταχώρηση στο βιβλίο διευθύνσεων</translation>
</message>
+ <message>
+ <source>The address associated with this address list entry. This can only be modified for sending addresses.</source>
+ <translation>Η διεύθυνση σχετίζεται με αυτή την καταχώρηση του βιβλίου διευθύνσεων. Μπορεί να τροποποιηθεί μόνο για τις διευθύνσεις αποστολής.</translation>
+ </message>
<message>
<source>&Address</source>
<translation>&Διεύθυνση</translation>
<source>name</source>
<translation>όνομα</translation>
</message>
+ <message>
+ <source>Directory already exists. Add %1 if you intend to create a new directory here.</source>
+ <translation>Κατάλογος ήδη υπάρχει. Προσθήκη %1, αν σκοπεύετε να δημιουργήσετε έναν νέο κατάλογο εδώ.</translation>
+ </message>
+ <message>
+ <source>Path already exists, and is not a directory.</source>
+ <translation>Η διαδρομή υπάρχει ήδη αλλά δεν είναι φάκελος</translation>
+ </message>
<message>
<source>Cannot create data directory here.</source>
<translation>Δεν μπορεί να δημιουργηθεί φάκελος δεδομένων εδώ.</translation>
<source>Start minimized</source>
<translation>Έναρξη ελαχιστοποιημένο</translation>
</message>
+ <message>
+ <source>Set SSL root certificates for payment request (default: -system-)</source>
+ <translation>Ορίστε SSL root certificates για αίτηση πληρωμής (default: -system-)</translation>
+ </message>
<message>
<source>Show splash screen on startup (default: 1)</source>
<translation>Εμφάνισε την οθόνη εκκίνησης κατά την εκκίνηση(προεπιλογή:1)</translation>
</message>
- </context>
+ <message>
+ <source>Choose data directory on startup (default: 0)</source>
+ <translation>Επιλογή καταλόγου</translation>
+ </message>
+</context>
<context>
<name>Intro</name>
<message>
<source>As this is the first time the program is launched, you can choose where Bitcoin Core will store its data.</source>
<translation>Καθώς αυτή είναι η πρώτη φορά που εκκινείται το πρόγραμμα, μπορείτε να διαλέξετε πού θα αποθηκεύει το Bitcoin Core τα δεδομένα του.</translation>
</message>
+ <message>
+ <source>Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory.</source>
+ <translation>O πυρήνας Bitcoin θα κατεβάσει και να αποθηκεύσει ένα αντίγραφο της αλυσίδας μπλοκ Bitcoin. Τουλάχιστον %1GB δεδομένων θα αποθηκευτούν σε αυτόν τον κατάλογο, και θα αυξηθεί με την πάροδο του χρόνου. Το πορτοφόλι θα αποθηκευτεί σε αυτόν τον κατάλογο.</translation>
+ </message>
<message>
<source>Use the default data directory</source>
<translation>Χρήση του προεπιλεγμένου φακέλου δεδομένων</translation>
<source>Bitcoin Core</source>
<translation>Bitcoin Core</translation>
</message>
+ <message>
+ <source>Error: Specified data directory "%1" cannot be created.</source>
+ <translation>Σφάλμα: Ο καθορισμένος φάκελος δεδομένων "%1" δεν μπορεί να δημιουργηθεί.</translation>
+ </message>
<message>
<source>Error</source>
<translation>Σφάλμα</translation>
</context>
<context>
<name>OpenURIDialog</name>
- </context>
+ <message>
+ <source>Open URI</source>
+ <translation>'Ανοιγμα &URI</translation>
+ </message>
+ <message>
+ <source>Open payment request from URI or file</source>
+ <translation>Ανοιχτό αίτημα πληρωμής από URI ή απο αρχείο</translation>
+ </message>
+ <message>
+ <source>URI:</source>
+ <translation>URI:</translation>
+ </message>
+ <message>
+ <source>Select payment request file</source>
+ <translation>Επιλέξτε πληρωμή αρχείου αίτησης</translation>
+ </message>
+ <message>
+ <source>Select payment request file to open</source>
+ <translation>Επιλέξτε αρχείο πληρωμής για άνοιγμα.</translation>
+ </message>
+</context>
<context>
<name>OptionsDialog</name>
<message>
<source>&Main</source>
<translation>&Κύριο</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Η προαιρετική αμοιβή για κάθε kB επισπεύδει την επεξεργασία των συναλλαγών σας. Οι περισσότερες συναλλαγές είναι 1 kB. </translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Αμοιβή &συναλλαγής</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Αυτόματη εκκίνηση του Bitcoin μετά την εισαγωγή στο σύστημα</translation>
<source>&Start Bitcoin on system login</source>
<translation>&Έναρξη του Βιtcoin κατά την εκκίνηση του συστήματος</translation>
</message>
+ <message>
+ <source>Size of &database cache</source>
+ <translation>Μέγεθος κρυφής μνήμης βάσης δεδομένων.</translation>
+ </message>
<message>
<source>MB</source>
<translation>MB</translation>
</message>
+ <message>
+ <source>Number of script &verification threads</source>
+ <translation>Αριθμός script και γραμμές επαλήθευσης </translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>Αποδοχή συνδέσεων απο έξω</translation>
+ </message>
+ <message>
+ <source>Allow incoming connections</source>
+ <translation>Αποδοχή εισερχόμενων συναλλαγών</translation>
+ </message>
+ <message>
+ <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
+ <translation>Διεύθυνση IP του διαμεσολαβητή (π.χ. 127.0.0.1 / IPv6: ::1)</translation>
+ </message>
+ <message>
+ <source>Third party transaction URLs</source>
+ <translation>Διευθύνσεις τρίτων συναλλαγών.</translation>
+ </message>
<message>
<source>Reset all client options to default.</source>
<translation>Επαναφορα όλων των επιλογων του πελάτη σε default.</translation>
<source>&Network</source>
<translation>&Δίκτυο</translation>
</message>
+ <message>
+ <source>W&allet</source>
+ <translation>Π&ορτοφόλι</translation>
+ </message>
<message>
<source>Expert</source>
<translation>Έμπειρος</translation>
</message>
+ <message>
+ <source>Enable coin &control features</source>
+ <translation>Επιλογή κατα πόσο να αναδείχνονται οι δυνατότητες ελέγχου κερμάτων.</translation>
+ </message>
<message>
<source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
<translation>Αυτόματο άνοιγμα των θυρών Bitcoin στον δρομολογητή. Λειτουργεί μόνο αν ο δρομολογητής σας υποστηρίζει τη λειτουργία UPnP.</translation>
<source>Map port using &UPnP</source>
<translation>Απόδοση θυρών με χρήστη &UPnP</translation>
</message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Σύνδεση στο Bitcoin δίκτυο μέσω διαμεσολαβητή SOCKS5 (π.χ. για σύνδεση μέσω Tor)</translation>
+ </message>
+ <message>
+ <source>&Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&Σύνδεση μέσω διαμεσολαβητή SOCKS5 (προεπιλεγμένος)</translation>
+ </message>
<message>
<source>Proxy &IP:</source>
<translation>&IP διαμεσολαβητή:</translation>
<source>Choose the default subdivision unit to show in the interface and when sending coins.</source>
<translation>Διαλέξτε την προεπιλεγμένη υποδιαίρεση που θα εμφανίζεται όταν στέλνετε νομίσματα.</translation>
</message>
+ <message>
+ <source>Whether to show coin control features or not.</source>
+ <translation>Επιλογή κατα πόσο να αναδείχνονται οι δυνατότητες ελέγχου κερμάτων.</translation>
+ </message>
<message>
<source>&OK</source>
<translation>&ΟΚ</translation>
<source>Client restart required to activate changes.</source>
<translation>Χρειάζεται επανεκκίνηση του προγράμματος για να ενεργοποιηθούν οι αλλαγές.</translation>
</message>
+ <message>
+ <source>Client will be shutdown, do you want to proceed?</source>
+ <translation>Η εφαρμογή θα τερματιστεί. Θέλετε να προχωρήσετε;</translation>
+ </message>
+ <message>
+ <source>This change would require a client restart.</source>
+ <translation>Η αλλαγή αυτή θα χρειαστεί επανεκκίνηση του προγράμματος</translation>
+ </message>
<message>
<source>The supplied proxy address is invalid.</source>
<translation>Δεν είναι έγκυρη η διεύθυνση διαμεσολαβητή</translation>
<source>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source>
<translation>Οι πληροφορίες που εμφανίζονται μπορεί να είναι ξεπερασμένες. Το πορτοφόλι σας συγχρονίζεται αυτόματα με το δίκτυο Bitcoin μετά από μια σύνδεση, αλλά αυτή η διαδικασία δεν έχει ακόμη ολοκληρωθεί. </translation>
</message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Επίβλεψη μόνο:</translation>
+ </message>
<message>
<source>Available:</source>
<translation>Διαθέσιμο:</translation>
<source>Your current spendable balance</source>
<translation>Το τρέχον διαθέσιμο υπόλοιπο</translation>
</message>
+ <message>
+ <source>Pending:</source>
+ <translation>Εκκρεμούν:</translation>
+ </message>
<message>
<source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
<translation>Το άθροισμα των συναλλαγών που δεν έχουν ακόμα επιβεβαιωθεί και δεν προσμετρώνται στο τρέχον διαθέσιμο υπόλοιπό σας</translation>
<source>Mined balance that has not yet matured</source>
<translation>Εξορυγμενο υπόλοιπο που δεν έχει ακόμα ωριμάσει </translation>
</message>
+ <message>
+ <source>Balances</source>
+ <translation>Υπόλοιπο:</translation>
+ </message>
<message>
<source>Total:</source>
<translation>Σύνολο:</translation>
<source>Your current total balance</source>
<translation>Το τρέχον συνολικό υπόλοιπο</translation>
</message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Ξοδεμένα:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Πρόσφατες συναλλαγές</translation>
+ </message>
<message>
<source>out of sync</source>
<translation>εκτός συγχρονισμού</translation>
<source>Invalid payment address %1</source>
<translation>Μη έγκυρη διεύθυνση πληρωμής %1</translation>
</message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>Η αίτηση πληρωμής έχει αρνηθεί.</translation>
+ </message>
+ <message>
+ <source>Payment request has expired.</source>
+ <translation>Η αίτηση πληρωμής έχει λήξει.</translation>
+ </message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Η αίτηση πληρωμής δεν έχει αρχίζει ακόμα.</translation>
+ </message>
<message>
<source>Payment request error</source>
<translation>Σφάλμα αιτήματος πληρωμής</translation>
<source>Cannot start bitcoin: click-to-pay handler</source>
<translation>Δεν είναι δυνατή η εκκίνηση του Bitcoin: click-to-pay handler</translation>
</message>
+ <message>
+ <source>Payment request fetch URL is invalid: %1</source>
+ <translation>Η διεύθυνση πληρωμής (URL) δεν είναι έγκυρη: %1</translation>
+ </message>
+ <message>
+ <source>Payment request file handling</source>
+ <translation>Επιλέξτε αρχείο πληρωμής για άνοιγμα.</translation>
+ </message>
+ <message>
+ <source>Refund from %1</source>
+ <translation>Επιστροφή ποσού από %1</translation>
+ </message>
<message>
<source>Payment acknowledged</source>
<translation>Πληρωμή αναγνωρίστηκε</translation>
</context>
<context>
<name>PeerTableModel</name>
- </context>
+ <message>
+ <source>Address/Hostname</source>
+ <translation>Διεύθυθνση/Όνομα υπολογιστή</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Χρόνος καθυστέρησης</translation>
+ </message>
+</context>
<context>
<name>QObject</name>
<message>
<source>Amount</source>
<translation>Ποσό</translation>
</message>
+ <message>
+ <source>Enter a Bitcoin address (e.g. %1)</source>
+ <translation>Εισάγετε μια διεύθυνση Bitcoin (π.χ. %1)</translation>
+ </message>
+ <message>
+ <source>%1 d</source>
+ <translation>%1 d</translation>
+ </message>
<message>
<source>%1 h</source>
<translation>%1 ώ</translation>
<source>%1 m</source>
<translation>%1 λ</translation>
</message>
+ <message>
+ <source>%1 s</source>
+ <translation>%1 s</translation>
+ </message>
+ <message>
+ <source>NETWORK</source>
+ <translation>Δίκτυο</translation>
+ </message>
+ <message>
+ <source>UNKNOWN</source>
+ <translation>Άγνωστο(α)</translation>
+ </message>
+ <message>
+ <source>None</source>
+ <translation>Κανένα</translation>
+ </message>
<message>
<source>N/A</source>
<translation>Μη διαθέσιμο</translation>
</message>
- </context>
+ <message>
+ <source>%1 ms</source>
+ <translation>%1 ms</translation>
+ </message>
+</context>
<context>
<name>QRImageWidget</name>
<message>
<source>Current number of blocks</source>
<translation>Τρέχον αριθμός μπλοκ</translation>
</message>
+ <message>
+ <source>Received</source>
+ <translation>Παραλήφθησαν</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation>Έκδοση</translation>
+ </message>
+ <message>
+ <source>Services</source>
+ <translation>Υπηρεσίες</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Χρόνος καθυστέρησης</translation>
+ </message>
<message>
<source>Last block time</source>
<translation>Χρόνος τελευταίου μπλοκ</translation>
<source>%1 GB</source>
<translation>%1 GB</translation>
</message>
+ <message>
+ <source>via %1</source>
+ <translation>μέσω %1</translation>
+ </message>
+ <message>
+ <source>never</source>
+ <translation>ποτέ</translation>
+ </message>
+ <message>
+ <source>Inbound</source>
+ <translation>Εισερχόμενα</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Εξερχόμενα</translation>
+ </message>
+ <message>
+ <source>Unknown</source>
+ <translation>Άγνωστο(α)</translation>
+ </message>
</context>
<context>
<name>ReceiveCoinsDialog</name>
<source>QR Code</source>
<translation>Κώδικας QR</translation>
</message>
+ <message>
+ <source>Copy &URI</source>
+ <translation>Αντιγραφη της επιλεγμενης διεύθυνσης στο πρόχειρο του συστηματος</translation>
+ </message>
<message>
<source>&Save Image...</source>
<translation>&Αποθήκευση εικόνας...</translation>
<source>Payment information</source>
<translation>Πληροφορίες πληρωμής</translation>
</message>
+ <message>
+ <source>URI</source>
+ <translation>URI:</translation>
+ </message>
<message>
<source>Address</source>
<translation>Διεύθυνση</translation>
<source>Send Coins</source>
<translation>Αποστολή νομισμάτων</translation>
</message>
+ <message>
+ <source>Coin Control Features</source>
+ <translation>Χαρακτηρηστικά επιλογής κερμάτων</translation>
+ </message>
<message>
<source>automatically selected</source>
<translation>επιλεγμένο αυτόματα</translation>
<source>Priority:</source>
<translation>Προτεραιότητα:</translation>
</message>
+ <message>
+ <source>Fee:</source>
+ <translation>Ταρίφα</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Ταρίφα αλλαγής</translation>
+ </message>
<message>
<source>Change:</source>
<translation>Ρέστα:</translation>
</message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Τέλος συναλλαγής:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Επιλογή...</translation>
+ </message>
+ <message>
+ <source>Minimize</source>
+ <translation>Ελαχιστοποίηση</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>Γρήγορο</translation>
+ </message>
<message>
<source>Send to multiple recipients at once</source>
<translation>Αποστολή σε πολλούς αποδέκτες ταυτόχρονα</translation>
<source>Clear all fields of the form.</source>
<translation>Καθαρισμός όλων των πεδίων της φόρμας.</translation>
</message>
+ <message>
+ <source>Dust:</source>
+ <translation>Σκόνη</translation>
+ </message>
<message>
<source>Clear &All</source>
<translation>Καθαρισμός &Όλων</translation>
<source>Copy amount</source>
<translation>Αντιγραφή ποσού</translation>
</message>
+ <message>
+ <source>Copy fee</source>
+ <translation>Αντιγραφή ταρίφας</translation>
+ </message>
+ <message>
+ <source>Copy after fee</source>
+ <translation>Αντιγραφή μετα-ταρίφας</translation>
+ </message>
<message>
<source>Copy bytes</source>
<translation>Αντιγραφή των byte</translation>
<source>(no label)</source>
<translation>(χωρίς ετικέτα)</translation>
</message>
+ <message>
+ <source>Copy dust</source>
+ <translation>Αντιγραφή 'σκόνης'</translation>
+ </message>
<message>
<source>Are you sure you want to send?</source>
<translation>Είστε βέβαιοι για την αποστολή;</translation>
<source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
<translation>Μπορείτε να υπογράφετε μηνύματα με τις διευθύνσεις σας, ώστε ν' αποδεικνύετε πως αυτές σας ανήκουν. Αποφεύγετε να υπογράφετε κάτι αόριστο καθώς ενδέχεται να εξαπατηθείτε. Υπογράφετε μόνο πλήρης δηλώσεις με τις οποίες συμφωνείτε.</translation>
</message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Διεύθυνση Bitcoin που θα σταλεί το μήνυμα</translation>
+ </message>
<message>
<source>Choose previously used address</source>
<translation>Επιλογή διεύθυνσης που έχει ήδη χρησιμοποιηθεί</translation>
<source>Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack.</source>
<translation>Πληκτρολογήστε την υπογραφή διεύθυνσης, μήνυμα (βεβαιωθείτε ότι έχετε αντιγράψει τις αλλαγές γραμμής, κενά, tabs, κ.λπ. ακριβώς) και την υπογραφή παρακάτω, για να ελέγξει το μήνυμα. Να είστε προσεκτικοί για να μην διαβάσετε περισσότερα στην υπογραφή ό, τι είναι στην υπογραφή ίδιο το μήνυμα , για να μην εξαπατηθούν από έναν άνθρωπο -in - the-middle επίθεση.</translation>
</message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Διεύθυνση Bitcoin η οποία το μήνυμα έχει υπογραφεί</translation>
+ </message>
<message>
<source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
<translation>Υπογράψτε ένα μήνυμα για ν' αποδείξετε πως υπογραφθηκε απο μια συγκεκριμένη διεύθυνση Bitcoin</translation>
<source>Open until %1</source>
<translation>Ανοιχτό μέχρι %1</translation>
</message>
+ <message>
+ <source>conflicted</source>
+ <translation>σύγκρουση</translation>
+ </message>
<message>
<source>%1/offline</source>
<translation>%1/χωρίς σύνδεση;</translation>
<source>own address</source>
<translation> δική σας διεύθυνση </translation>
</message>
+ <message>
+ <source>watch-only</source>
+ <translation>Επίβλεψη μόνο:</translation>
+ </message>
<message>
<source>label</source>
<translation>eπιγραφή</translation>
<source>Debit</source>
<translation>Debit</translation>
</message>
+ <message>
+ <source>Total debit</source>
+ <translation>Σύνολο χρέωσης</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Συνολική πίστωση</translation>
+ </message>
<message>
<source>Transaction fee</source>
<translation>Τέλος συναλλαγής </translation>
<source>Merchant</source>
<translation>Έμπορος</translation>
</message>
+ <message>
+ <source>Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source>
+ <translation>Πρέπει να περιμένετε %1 μπλοκ πριν μπορέσετε να χρησιμοποιήσετε τα νομίσματα που έχετε δημιουργήσει. Το μπλοκ που δημιουργήσατε μεταδόθηκε στο δίκτυο για να συμπεριληφθεί στην αλυσίδα των μπλοκ. Αν δεν μπει σε αυτή θα μετατραπεί σε "μη αποδεκτό" και δε θα μπορεί να καταναλωθεί. Αυτό συμβαίνει σπάνια όταν κάποιος άλλος κόμβος δημιουργήσει ένα μπλοκ λίγα δευτερόλεπτα πριν από εσάς.</translation>
+ </message>
<message>
<source>Debug information</source>
<translation>Πληροφορίες αποσφαλμάτωσης</translation>
<source>Unconfirmed</source>
<translation>Ανεπιβεβαίωτες</translation>
</message>
+ <message>
+ <source>Conflicted</source>
+ <translation>Σύγκρουση</translation>
+ </message>
<message>
<source>Received with</source>
<translation>Παραλαβή με</translation>
<source>Mined</source>
<translation>Εξόρυξη</translation>
</message>
+ <message>
+ <source>watch-only</source>
+ <translation>Επίβλεψη μόνο:</translation>
+ </message>
<message>
<source>(n/a)</source>
<translation>(δ/α)</translation>
<source>Export Transaction History</source>
<translation>Εξαγωγή Ιστορικού Συναλλαγών</translation>
</message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Επίβλεψη μόνο:</translation>
+ </message>
<message>
<source>Exporting Failed</source>
<translation>Η Εξαγωγή Απέτυχε</translation>
<source>Error opening block database</source>
<translation>Σφάλμα φορτωσης της βασης δεδομενων των μπλοκ</translation>
</message>
+ <message>
+ <source>Error: A fatal internal error occured, see debug.log for details</source>
+ <translation>Σφάλμα: Παρουσιάστηκε ανεπανόρθωτο εσωτερικό σφάλμα, δείτε debug.log για λεπτομέρειες</translation>
+ </message>
<message>
<source>Error: Disk space is low!</source>
<translation>Προειδοποίηση: Χαμηλός χώρος στο δίσκο </translation>
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
<translation>ταλαιπωρηθειτε για να ακούσετε σε οποιαδήποτε θύρα. Χρήση - ακούστε = 0 , αν θέλετε αυτό.</translation>
</message>
+ <message>
+ <source>Importing...</source>
+ <translation>ΕΙσαγωγή...</translation>
+ </message>
<message>
<source>Invalid -onion address: '%s'</source>
<translation>Άκυρη διεύθυνση -onion : '%s'</translation>
<source>Rebuild block chain index from current blk000??.dat files</source>
<translation>Εισαγωγή μπλοκ από εξωτερικό αρχείο blk000?.dat</translation>
</message>
+ <message>
+ <source>Specify wallet file (within data directory)</source>
+ <translation>Επιλέξτε αρχείο πορτοφολιού (μέσα απο κατάλογο δεδομένων)</translation>
+ </message>
<message>
<source>Verifying blocks...</source>
<translation>Επαλήθευση των μπλοκ... </translation>
<source>Imports blocks from external blk000??.dat file</source>
<translation>Εισαγωγή μπλοκ από εξωτερικό αρχείο blk000?.dat</translation>
</message>
+ <message>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running.</source>
+ <translation>Αδυναμία κλειδώματος του φακέλου δεδομένων %s. Πιθανώς το Bitcoin να είναι ήδη ενεργό.</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Σύνδεση μέσω διαμεσολαβητή SOCKS5</translation>
+ </message>
+ <message>
+ <source>Could not parse -rpcbind value %s as network address</source>
+ <translation>Δεν μπόρεσε να αναλυθεί η παράμετρος -rpcbind value %s ως διεύθυνση δικτύου</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Σφάλμα φόρτωσης wallet.dat: Το Πορτοφόλι απαιτεί μια νεότερη έκδοση του Bitcoin</translation>
+ </message>
+ <message>
+ <source>Error: Unsupported argument -tor found, use -onion.</source>
+ <translation>Σφάλμα: Μη συμβατή παράμετρος -tor. Χρησιμοποιήσε την παράμετρο -onion</translation>
+ </message>
<message>
<source>Information</source>
<translation>Πληροφορία</translation>
<source>Invalid amount for -mintxfee=<amount>: '%s'</source>
<translation>Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s'</translation>
</message>
+ <message>
+ <source>RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>Ρυθμίσεις SSL: (ανατρέξτε στο Bitcoin Wiki για οδηγίες ρυθμίσεων SSL)</translation>
+ </message>
<message>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Αποστολή πληροφοριών εντοπισμού σφαλμάτων στην κονσόλα αντί του αρχείου debug.log</translation>
<source>Signing transaction failed</source>
<translation>Η υπογραφή συναλλαγής απέτυχε </translation>
</message>
+ <message>
+ <source>This is experimental software.</source>
+ <translation>Η εφαρμογή είναι σε πειραματικό στάδιο.</translation>
+ </message>
<message>
<source>Transaction amount too small</source>
<translation>Το ποσό της συναλλαγής είναι πολύ μικρο </translation>
<source>Warning: This version is obsolete, upgrade required!</source>
<translation>Προειδοποίηση: Αυτή η έκδοση είναι ξεπερασμένη, απαιτείται αναβάθμιση </translation>
</message>
+ <message>
+ <source>Zapping all transactions from wallet...</source>
+ <translation>Μεταφορά όλων των συναλλαγών απο το πορτοφόλι</translation>
+ </message>
<message>
<source>on startup</source>
<translation>κατά την εκκίνηση</translation>
<source>Error loading wallet.dat: Wallet corrupted</source>
<translation>Σφάλμα φόρτωσης wallet.dat: Κατεστραμμένο Πορτοφόλι</translation>
</message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Πόσο εξονυχιστική να είναι η επιβεβαίωση του μπλοκ (0-4, προεπιλογή: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Διατηρήση ένος πλήρες ευρετήριου συναλλαγών (προεπιλογή: %u) </translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Δευτερόλεπτα πριν επιτραπεί ξανά η σύνδεση των προβληματικών peers (προεπιλογή: %u)</translation>
+ </message>
<message>
<source>Error loading wallet.dat</source>
<translation>Σφάλμα φόρτωσης αρχείου wallet.dat</translation>
</message>
+ <message>
+ <source>Force safe mode (default: %u)</source>
+ <translation>Επιβολή ασφαλής λειτουργίας (προεπιλογή: %u)</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Δημιουργία νομισμάτων (προκαθορισμος: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Πόσα μπλοκ να ελέγχθουν κατά την εκκίνηση (προεπιλογή: %u, 0 = όλα)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Να συμπεριληφθεί η διεύθυνση IP στην αναφορά? (προεπιλογή: %u)</translation>
+ </message>
<message>
<source>Invalid -proxy address: '%s'</source>
<translation>Δεν είναι έγκυρη η διεύθυνση διαμεσολαβητή: '%s'</translation>
</message>
+ <message>
+ <source>Print block tree on startup (default: %u)</source>
+ <translation>Εκτύπωση μπλοκ δέντρου κατά την εκκίνηση (προεπιλογή: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Αρχείο πιστοποιητικού του διακομιστή (προεπιλογή: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Ορισμός λήξης χρονικού ορίου σε χιλιοστά του δευτερολέπτου(προεπιλογή: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Ορίστε αρχείο pid (προεπιλογή: %s)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Όριο αποσύνδεσης προβληματικών peers (προεπιλογή: %u)</translation>
+ </message>
<message>
<source>Unknown network specified in -onlynet: '%s'</source>
<translation>Άγνωστo δίκτυο ορίζεται σε onlynet: '%s'</translation>
-<TS language="eo" version="2.1">
+<TS language="eo" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Sumo</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Adreso</translation>
- </message>
<message>
<source>Date</source>
<translation>Dato</translation>
<source>&Main</source>
<translation>Ĉ&efa</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Nedeviga krompago por ĉiu kB, kiu helpas plirapidigi la traktadon de via transakcio. Plej multaj transakcioj grandas je 1kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Krompago</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Aŭtomate lanĉi Bitmonon post ensaluto al la sistemo.</translation>
-<TS language="es" version="2.1">
+<TS language="es" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<context>
<name>CoinControlDialog</name>
<message>
- <source>Coin Control Address Selection</source>
- <translation>Selección de direcciones bajo Coin Control</translation>
+ <source>Coin Selection</source>
+ <translation>Selección de la moneda</translation>
</message>
<message>
<source>Quantity:</source>
<translation>Cantidad</translation>
</message>
<message>
- <source>Address</source>
- <translation>Dirección</translation>
+ <source>Received with label</source>
+ <translation>Recibido con etiqueta</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Recibido con dirección</translation>
</message>
<message>
<source>Date</source>
<source>&Main</source>
<translation>&Principal</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Comisión de transacción opcional por kB que ayuda a asegurar que sus transacciones sean procesadas rápidamente. La mayoría de transacciones son de 1kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Pagar comisión de &transacción</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Iniciar Bitcoin automáticamente al encender el sistema.</translation>
<source>Allow incoming connections</source>
<translation>Aceptar conexiones entrantes</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Conectarse a la red Bitcoin a través de un proxy SOCKS.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Conectarse a través de proxy SOCKS (proxy predeterminado):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Dirección IP del proxy (p. ej. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Map port using &UPnP</source>
<translation>Mapear el puerto mediante &UPnP</translation>
</message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Conectarse a la red Bitcoin a través de un proxy SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&Conectarse a través de proxy SOCKS5 (proxy predeterminado):</translation>
+ </message>
<message>
<source>Proxy &IP:</source>
<translation>Dirección &IP del proxy:</translation>
<source>Custom change address</source>
<translation>Dirección propia</translation>
</message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Comisión de Transacción:</translation>
+ </message>
+ <message>
+ <source>Minimize</source>
+ <translation>Minimizar</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>por kilobyte</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>total por lo menos</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Recomendado:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Personalizado:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Tarifa inteligente no inicializado aún. Esto generalmente lleva a pocos bloques...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Tiempo de confirmación:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>rápido</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(confirmación puede tardar más tiempo)</translation>
+ </message>
<message>
<source>Send to multiple recipients at once</source>
<translation>Enviar a múltiples destinatarios de una vez</translation>
<source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
<translation>¡La transacción fue rechazada! Esto puede haber ocurrido si alguno de los bitcoins de su monedero ya estaba gastado o si ha usado una copia de wallet.dat y los bitcoins estaban gastados en la copia pero no se habían marcado como gastados aqui.</translation>
</message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Paga sólo la cuota mínima de %1</translation>
+ </message>
+ <message>
+ <source>Estimated to begin confirmation within %1 block(s).</source>
+ <translation>Estimado para comenzar confirmación dentro de %1 bloque(s)</translation>
+ </message>
<message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Alerta: Dirección de Bitcoin inválida</translation>
<source>Type of transaction.</source>
<translation>Tipo de transacción.</translation>
</message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Sea o no una dirección sólo está involucrada en esta transacción.</translation>
+ </message>
<message>
<source>Destination address of transaction.</source>
<translation>Dirección de destino de la transacción.</translation>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Borrar todas las transacciones del monedero y sólo recuperar aquellas partes de la cadena de bloques por medio de -rescan on startup.</translation>
</message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
+ <translation>Distribuido bajo la licencia de software MIT, vea la copia del archivo adjunto o <http://www.opensource.org/licenses/mit-license.php>.</translation>
+ </message>
<message>
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
<translation>Ingresar en el modo de prueba de regresión, que utiliza una cadena especial en la que los bloques se pueden resolver instantáneamente.</translation>
<source>Imports blocks from external blk000??.dat file</source>
<translation>Importa los bloques desde un archivo blk000??.dat externo</translation>
</message>
+ <message>
+ <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>Permitir conexiones JSON-RPC de origen especificado. Válido para son una sola IP (por ejemplo 1.2.3.4), una red/máscara de red (por ejemplo 1.2.3.4/255.255.255.0) o una red/CIDR (e.g. 1.2.3.4/24). Esta opción se puede especificar varias veces</translation>
+ </message>
<message>
<source>An error occurred while setting up the RPC address %s port %u for listening: %s</source>
<translation>Ocurrió un error al configurar la dirección de RPC %s puerto %u para escuchar en: %s</translation>
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
<translation>Crear nuevos archivos con permisos por defecto del sistema, en lugar de umask 077 (sólo efectivo con la funcionalidad de monedero desactivada)</translation>
</message>
- <message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>Distribuido bajo la licencia de software MIT/X11, vea la copia del archivo adjunto o <http://www.opensource.org/licenses/mit-license.php>.</translation>
- </message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Error: la escucha para conexiones entrantes falló (la escucha regresó el error %s)</translation>
</message>
+ <message>
+ <source>Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.</source>
+ <translation>Error: Unsupported argumento -socks encontrados. SOCKS versión ajuste ya no es posible, sólo SOCKS5 proxies son compatibles.</translation>
+ </message>
<message>
<source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
<translation>Ejecutar un comando cuando se reciba una alerta importante o cuando veamos un fork demasiado largo (%s en cmd se reemplazará por el mensaje)</translation>
</message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
+ <translation>Tarifas (en BTC/Kb) más pequeños que esto se consideran cero cuota de reinstalación (por defecto: %s)</translation>
+ </message>
+ <message>
+ <source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
+ <translation>Tarifas (en BTC/Kb) más pequeños que esto se consideran cero cuota para la creación de la transacción (por defecto: %s)</translation>
+ </message>
+ <message>
+ <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
+ <translation>Consulta de direcciones pares mediante búsqueda de DNS, si bajo en direcciones (por defecto: 1 a menos que - conectar)</translation>
+ </message>
<message>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Establecer tamaño máximo de las transacciones de alta prioridad/baja comisión en bytes (predeterminado: %d)</translation>
<source>Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly.</source>
<translation>Aviso: ¡Comprueba la fecha y hora de tu ordenador y verifica si es correcta! Si no es correcta Bitcoin Core no funcionará adecuadamente.</translation>
</message>
+ <message>
+ <source>Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway</source>
+ <translation>A los equipos en lista blanca no se les pueden prohibir los ataques DoS y sus transacciones siempre son retransmitidas, incluso si ya están en el mempool, es útil por ejemplo para un gateway.</translation>
+ </message>
<message>
<source>Connect through SOCKS5 proxy</source>
<translation>Conectar usando SOCKS5 proxy</translation>
<source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
<translation>Error al cargar wallet.dat: El monedero requiere una versión más reciente de Bitcoin Core</translation>
</message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Cuota (in BTC/kB) para añadir a las transacciones que envíes (por defecto: %s)</translation>
+ </message>
<message>
<source>Information</source>
<translation>Información</translation>
</message>
+ <message>
+ <source>Initialization sanity check failed. Bitcoin Core is shutting down.</source>
+ <translation>La inicialización de la verificación de validez falló. Se está apagando Bitcoin Core.</translation>
+ </message>
<message>
<source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source>
<translation>Cantidad inválida para -minrelaytxfee=<amount>: '%s'</translation>
<source>Invalid amount for -mintxfee=<amount>: '%s'</source>
<translation>Cantidad inválida para -mintxfee=<amount>: '%s'</translation>
</message>
+ <message>
+ <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source>
+ <translation>Cantidad inválida para -paytxfee=<amount>: '%s' (debe ser por lo menos %s)</translation>
+ </message>
+ <message>
+ <source>Invalid netmask specified in -whitelist: '%s'</source>
+ <translation>Máscara de red inválida especificada en -whitelist: '%s'</translation>
+ </message>
+ <message>
+ <source>Keep at most <n> unconnectable blocks in memory (default: %u)</source>
+ <translation>Mantener como máximo <n> bloques no conectables en memoria (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source>
+ <translation>Mantener como máximo <n> transacciones no conectables en memoria (por defecto: %u)</translation>
+ </message>
+ <message>
+ <source>Need to specify a port with -whitebind: '%s'</source>
+ <translation>Necesita especificar un puerto con -whitebind: '%s'</translation>
+ </message>
<message>
<source>Node relay options:</source>
<translation>Opciones de nodos de retransmisión:</translation>
<source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
<translation>Registrar prioridad de las transacciones y cuota por kB cuando se minen bloques (por defecto: %u)</translation>
</message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Mantener el índice completo de transacciones, usado por la llamada rpc de getrawtransaction (por defecto: %u)</translation>
+ </message>
<message>
<source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
<translation>Número de segundos en que se evita la reconexión de pares con mal comportamiento (predeterminado: %u)</translation>
<source>Print block tree on startup (default: %u)</source>
<translation>Imprimir árbol de bloques al iniciar (predeterminado: %u)</translation>
</message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Retransmitir y minar transacciones de transporte de datos (por defecto: %u)</translation>
+ </message>
<message>
<source>Run a thread to flush wallet periodically (default: %u)</source>
<translation>Ejecutar un hilo para limpiar de la memoria el monedero periódicamente (predeterminado: %u)</translation>
</message>
<message>
<source>Done loading</source>
- <translation>Generado pero no aceptado</translation>
+ <translation>Se terminó de cargar</translation>
</message>
<message>
<source>To use the %s option</source>
-<TS language="es_CL" version="2.1">
+<TS language="es_CL" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Cantidad</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Dirección</translation>
- </message>
<message>
<source>Date</source>
<translation>Fecha</translation>
<source>&Main</source>
<translation>&Principal</translation>
</message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Comisión de &transacciónes</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Inicia Bitcoin automáticamente despues de encender el computador</translation>
-<TS language="es_DO" version="2.1">
+<TS language="es_DO" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Selección de la dirección de control de la moneda</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Cantidad:</translation>
<source>Amount</source>
<translation>Cantidad</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Dirección</translation>
- </message>
<message>
<source>Date</source>
<translation>Fecha</translation>
<source>&Main</source>
<translation>&Principal</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Tarifa de transacción opcional por kB que ayuda a asegurar que sus transacciones sean procesadas rápidamente. La mayoría de transacciones son de 1kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Comisión de &transacciones</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Iniciar Bitcoin automáticamente al encender el sistema.</translation>
<source>MB</source>
<translation>MB</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Conéctese a la red Bitcoin través de un proxy SOCKS.</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Dirección IP del proxy (ej. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
-<TS language="es_MX" version="2.1">
+<TS language="es_MX" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Monto</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Domicilio</translation>
- </message>
<message>
<source>Date</source>
<translation>Fecha</translation>
-<TS language="es_UY" version="2.1">
+<TS language="es_UY" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Address</source>
- <translation>Direccion </translation>
- </message>
<message>
<source>Date</source>
<translation>Fecha</translation>
-<TS language="et" version="2.1">
+<TS language="et" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Kogus</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Aadress</translation>
- </message>
<message>
<source>Date</source>
<translation>Kuupäev</translation>
<source>Options</source>
<translation>Valikud</translation>
</message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Tasu tehingu &fee</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Käivita Bitcoin süsteemi logimisel.</translation>
-<TS language="eu_ES" version="2.1">
+<TS language="eu_ES" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Kopurua</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Helbidea</translation>
- </message>
<message>
<source>Date</source>
<translation>Data</translation>
-<TS language="fa" version="2.1">
+<TS language="fa" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>مبلغ</translation>
</message>
- <message>
- <source>Address</source>
- <translation>نشانی</translation>
- </message>
<message>
<source>Date</source>
<translation>تاریخ</translation>
<source>&Main</source>
<translation>&عمومی</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>کارمزد اختیاریِ هر کیلوبایت برای انتقال سریعتر تراکنش. اکثر تراکنشها ۱ کیلوبایتی هستند.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>پرداخت &کارمزد تراکنش</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>اجرای خودکار بیتکوین در زمان ورود به سیستم.</translation>
-<TS language="fa_IR" version="2.1">
+<TS language="fa_IR" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>میزان</translation>
</message>
- <message>
- <source>Address</source>
- <translation>حساب</translation>
- </message>
<message>
<source>Date</source>
<translation>تاریخ</translation>
-<TS language="fi" version="2.1">
+<TS language="fi" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Kolikkokontrollin osoitteen valinta</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Määrä:</translation>
<source>Amount</source>
<translation>Määrä</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Osoite</translation>
- </message>
<message>
<source>Date</source>
<translation>Aika</translation>
<source>&Main</source>
<translation>&Yleiset</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Valinnainen rahansiirtopalkkio per kB auttaa varmistamaan että rahansiirtosi prosessoidaan nopeasti. Useimmat rahansiirrot ovat alle 1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Maksa rahansiirtopalkkio</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Käynnistä Bitcoin kirjautumisen yhteydessä.</translation>
<source>Allow incoming connections</source>
<translation>Hyväksy sisääntulevia yhteyksiä</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Yhdistä Bitcoin-verkkoon SOCKS proxyn kautta.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Yhdistä SOCKS proxyn kautta (oletus proxy):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>IP osoite proxille (esim. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
-<TS language="fr" version="2.1">
+<TS language="fr" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Up to date</source>
<translation>À jour</translation>
</message>
+ <message numerus="yes">
+ <source>Processed %n blocks of transaction history.</source>
+ <translation><numerusform>%n bloc de l'historique transactionnel a été traité</numerusform><numerusform>%n blocs de l'historique transactionnel ont été traités</numerusform></translation>
+ </message>
<message>
<source>Catching up...</source>
<translation>Rattrapage en cours…</translation>
<context>
<name>CoinControlDialog</name>
<message>
- <source>Coin Control Address Selection</source>
- <translation>Sélection de l'adresse de contrôle des pièces</translation>
+ <source>Coin Selection</source>
+ <translation>Sélection des pièces</translation>
</message>
<message>
<source>Quantity:</source>
<translation>Montant</translation>
</message>
<message>
- <source>Address</source>
- <translation>Adresse</translation>
+ <source>Received with label</source>
+ <translation>Reçu avec une étiquette</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Reçu avec une adresse</translation>
</message>
<message>
<source>Date</source>
<source>Error</source>
<translation>Erreur</translation>
</message>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n Go d'espace libre disponible</numerusform><numerusform>%n Go d'espace libre disponibles</numerusform></translation>
+ </message>
</context>
<context>
<name>OpenURIDialog</name>
<source>&Main</source>
<translation>Réglages &principaux</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Frais de transaction optionnel par ko qui aident à garantir un traitement rapide des transactions. La plupart des transactions utilisent 1 ko.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Payer des &frais de transaction</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Démarrer Bitcoin automatiquement après avoir ouvert une session sur l'ordinateur.</translation>
<source>Allow incoming connections</source>
<translation>Permettre les transactions entrantes</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Se connecter au réseau Bitcoin par un mandataire SOCKS.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>Se &connecter par un mandataire SOCKS (mandataire par défaut) :</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Adresse IP du mandataire (par ex. IPv4 : 127.0.0.1 / IPv6 : ::1)</translation>
<source>Map port using &UPnP</source>
<translation>Mapper le port avec l'&UPnP</translation>
</message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Se connecter au réseau Bitcoin par un mandataire SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>Se &connecter par un mandataire SOCKS5 (mandataire par défaut) :</translation>
+ </message>
<message>
<source>Proxy &IP:</source>
<translation>&IP du serveur mandataire :</translation>
</message>
<message>
<source>Spendable:</source>
- <translation>Disponible:</translation>
+ <translation>Disponible :</translation>
</message>
<message>
<source>Recent transactions</source>
<source>Custom change address</source>
<translation>Adresse personnalisée de monnaie rendue</translation>
</message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Frais de transaction :</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Choisir...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>réduire les paramètres des frais</translation>
+ </message>
+ <message>
+ <source>Minimize</source>
+ <translation>Minimiser</translation>
+ </message>
+ <message>
+ <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>Si les frais personnalisés sont définis à 1 000 satoshis et que la transaction est seulement de 250 octets, donc le « par kilo-octet » ne paiera que 250 satoshis de frais, alors que le « au moins » paiera 1 000 satoshis. Pour des transactions supérieures à un kilo-octet, les deux paieront par kilo-octets.</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>par kilo-octet</translation>
+ </message>
+ <message>
+ <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>Si les frais personnalisés sont définis à 1 000 satoshis et que la transaction est seulement de 250 octets, donc le « par kilo-octet » ne paiera que 250 satoshis de frais, alors que le « total au moins » paiera 1 000 satoshis. Pour des transactions supérieures à un kilo-octet, les deux paieront par kilo-octets.</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>total au moins</translation>
+ </message>
+ <message>
+ <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>Il est correct de payer les frais minimum tant que le volume transactionnel est inférieur à l'espace dans les blocs. Mais soyez conscient que ceci pourrait résulter en une transaction n'étant jamais confirmée une fois qu'il y aura plus de transactions que le réseau ne pourra en traiter.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(lire l'infobulle)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Recommandés :</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Personnalisés : </translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Les frais intelligents ne sont pas encore initialisés. Ceci prend habituellement quelques blocs...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Temps de confirmation :</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>rapide</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Envoyer si possible une transaction sans frais</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(la confirmation pourrait prendre plus longtemps)</translation>
+ </message>
<message>
<source>Send to multiple recipients at once</source>
<translation>Envoyer à plusieurs destinataires à la fois</translation>
<source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
<translation>La transaction a été rejetée ! Ceci peut arriver si certaines pièces de votre portefeuille étaient déjà dépensées, par exemple si vous avez utilisé une copie de wallet.dat et que des pièces ont été dépensées dans la copie sans être marquées comme telles ici.</translation>
</message>
+ <message>
+ <source>A fee higher than %1 is considered an insanely high fee.</source>
+ <translation>Des frais supérieurs à %1 sont considérés comme follement élevés.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Payer seulement les frais minimum de %1</translation>
+ </message>
+ <message>
+ <source>Estimated to begin confirmation within %1 block(s).</source>
+ <translation>Début de confirmation estimé à %1 bloc(s).</translation>
+ </message>
<message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Avertissement : adresse Bitcoin invalide</translation>
</message>
<message>
<source>Whether or not a watch-only address is involved in this transaction.</source>
- <translation>Détermine si une adresse de type watch-only est impliquée dans cette transaction.</translation>
+ <translation>Une adresse juste-regarder est-elle impliquée dans cette transaction.</translation>
</message>
<message>
<source>Destination address of transaction.</source>
<source>Export Transaction History</source>
<translation>Exporter l'historique des transactions</translation>
</message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Juste-regarder :</translation>
+ </message>
<message>
<source>Exporting Failed</source>
<translation>L'exportation a échoué</translation>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Supprimer toutes les transactions du portefeuille et ne récupérer que ces parties de la chaîne de bloc avec -rescan au démarrage</translation>
</message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
+ <translation>Distribué sous la licence MIT d'utilisation d'un logiciel. Consultez le fichier joint COPYING ou <http://www.opensource.org/licenses/mit-license.php>.</translation>
+ </message>
<message>
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
<translation>Passer en mode de test de régression qui utilise une chaîne spéciale dans laquelle les blocs sont résolus instantanément.</translation>
<source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
<translation>Avertissement : wallet.dat corrompu, données récupérées ! Le fichier wallet.dat original a été enregistré en tant que wallet.{timestamp}.bak dans %s ; si votre solde ou transactions sont incorrects vous devriez effectuer une restauration depuis une sauvegarde.</translation>
</message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Pairs de la liste blanche se connectant à partir du masque réseau ou de l'IP donné. Peut être spécifié plusieurs fois.</translation>
+ </message>
<message>
<source>(default: 1)</source>
<translation>(par défaut : 1)</translation>
</message>
<message>
<source>Error: A fatal internal error occured, see debug.log for details</source>
- <translation>Erreur: Une erreur fatale s'est produite, voir debug.log pour plus de détails</translation>
+ <translation>Erreur : une erreur interne fatale s'est produite. Voir debug.log pour des détails</translation>
</message>
<message>
<source>Error: Disk space is low!</source>
</message>
<message>
<source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source>
- <translation>Se connecter uniquement aux nœuds du réseau <net> (IPv4, IPv6 ou Tor)</translation>
+ <translation>Seulement se connecter aux nœuds du réseau <net> (IPv4, IPv6 ou oignon)</translation>
</message>
<message>
<source>Rebuild block chain index from current blk000??.dat files</source>
<source>This is intended for regression testing tools and app development.</source>
<translation>Ceci est à l'intention des outils de test de régression et du développement applicatif.</translation>
</message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Utiliser l'UPnP pour mapper le port d'écoute (par défaut : %u)</translation>
+ </message>
<message>
<source>Verifying blocks...</source>
<translation>Vérification des blocs en cours...</translation>
<translation>Impossible d’obtenir un verrou sur le répertoire de données %s. Bitcoin Core fonctionne probablement déjà.</translation>
</message>
<message>
- <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
- <translation>Créer de nouveaux fichiers avec les permissions système par défaut, au lieu de umask 077 (effectif seulement avec la fonction du portefeuille désactivée)</translation>
+ <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source>
+ <translation>Limiter continuellement les transactions gratuites à <n>*1000 octets par minute (par défaut : %u)</translation>
</message>
<message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>Distribué sous la licence logiciel MIT/X11, consultez le fichier joint COPYING ou <http://www.opensource.org/licenses/mit-license.php>.</translation>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Créer de nouveaux fichiers avec les permissions système par défaut, au lieu de umask 077 (effectif seulement avec la fonction du portefeuille désactivée)</translation>
</message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
<translation>Les frais (en BTC/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour la création de transactions (par défaut : %s)</translation>
</message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Quantité maximale de données dans les transactions du porteur de données que nous relayons et minons (par défaut : %u)</translation>
+ </message>
<message>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation>Demander les adresses des pairs par recherche DNS si l'on manque d'adresses (par défaut : 1 sauf si -connect)</translation>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Définir la taille maximale en octets des transactions prioritaires/à frais modiques (par défaut : %d)</translation>
</message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Définir le nombre de fils de génération de pièces, si elle est activée (-1 = tous les cœurs, par défaut : %d)</translation>
+ </message>
<message>
<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>Ce produit comprend des logiciels développés par le projet OpenSSL pour être utilisés dans la boîte à outils OpenSSL <https://www.openssl.org/> et un logiciel cryptographique écrit par Eric Young, ainsi qu'un logiciel UPnP écrit par Thomas Bernard.</translation>
</message>
<message>
<source>Keep at most <n> unconnectable transactions in memory (default: %u)</source>
- <translation>Garder au plus <n> blocs non connectables en mémoire (par défaut : %u)</translation>
+ <translation>Garder au plus <n> transactions non connectables en mémoire (par défaut : %u)</translation>
</message>
<message>
<source>Need to specify a port with -whitebind: '%s'</source>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log</translation>
</message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Envoyer si possible les transactions comme étant sans frais (par défaut : %u)</translation>
+ </message>
<message>
<source>Show all debugging options (usage: --help -help-debug)</source>
<translation>Montrer toutes les options de débogage (utilisation : --help --help-debug)</translation>
</message>
<message>
<source>Use UPnP to map the listening port (default: 1 when listening)</source>
- <translation>Utiliser l'UPnP pour rediriger le port d'écoute (par défaut : 1 lors de l'écoute)</translation>
+ <translation>Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 lors de l'écoute)</translation>
</message>
<message>
<source>Username for JSON-RPC connections</source>
<source>Error loading wallet.dat: Wallet corrupted</source>
<translation>Erreur lors du chargement de wallet.dat : portefeuille corrompu</translation>
</message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = conserver les métadonnées de transmission, par ex. les informations du propriétaire du compte et de la demande de paiement, 2 = abandonner les métadonnées de transmission)</translation>
+ </message>
+ <message>
+ <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source>
+ <translation>Purger l’activité de la base de données de la zone de mémoire vers le journal sur disque tous les <n> mégaoctets (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Degré de profondeur de la vérification des blocs -checkblocks (0-4, par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source>
+ <translation>Si paytxfee n'est pas défini, inclure des frais suffisants afin que les transactions soient confirmées en moyenne en n blocs (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
+ <translation>Lors du minage, journaliser la priorité des transactions et les frais par ko (par défaut : %u) </translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Maintenir un index complet des transactions, utilisé par l'appel RPC getrawtransaction (obtenir la transaction brute) (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Délai en secondes de refus de reconnexion pour les pairs présentant un mauvais comportement (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying <category> is optional)</source>
+ <translation>Extraire les informations de débogage (par défaut : %u, fournir <category> est optionnel)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Utiliser un serveur mandataire SOCKS5 séparé pour atteindre les pairs par les services cachés de Tor (par défaut : %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(par défaut : %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Chiffrements acceptables (par défaut : %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Toujours demander les adresses des pairs par recherche DNS (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Disable safemode, override a real safe mode event (default: %u)</source>
+ <translation>Désactiver le mode sans échec, passer outre un événement sans échec réel (par défaut : %u)</translation>
+ </message>
<message>
<source>Error loading wallet.dat</source>
<translation>Erreur lors du chargement de wallet.dat</translation>
</message>
+ <message>
+ <source>Force safe mode (default: %u)</source>
+ <translation>Forcer le mode sans échec (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Générer des pièces (défaut : %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Nombre de blocs à vérifier au démarrage (par défaut : %u, 0 = tous)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Inclure les adresses IP à la sortie de débogage (par défaut : %u)</translation>
+ </message>
<message>
<source>Invalid -proxy address: '%s'</source>
<translation>Adresse -proxy invalide : « %s »</translation>
</message>
+ <message>
+ <source>Limit size of signature cache to <n> entries (default: %u)</source>
+ <translation>Limiter la taille du cache des signatures à <n> entrées (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source>
+ <translation>Écouter les connexions JSON-RPC sur <port> (par défaut : %u ou tesnet : %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on <port> (default: %u or testnet: %u)</source>
+ <translation>Écouter les connexions sur <port> (par défaut : %u ou tesnet : %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most <n> connections to peers (default: %u)</source>
+ <translation>Garder au plus <n> connexions avec les pairs (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source>
+ <translation>Tampon maximal de réception par connexion, <n>*1000 octets (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source>
+ <translation>Tampon maximal d'envoi par connexion », <n>*1000 octets (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
+ <translation>N'accepter qu'une chaîne de blocs correspondant aux points de vérification intégrés (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Ajouter l'horodatage au début de la sortie de débogage (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Print block tree on startup (default: %u)</source>
+ <translation>Imprimer l'arborescence des blocs au démarrage (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Relayer et miner les transactions du porteur de données (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Relayer les multisignatures non-P2SH (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Run a thread to flush wallet periodically (default: %u)</source>
+ <translation>Exécuter une tâche pour purger le portefeuille périodiquement (par défaut : %u) </translation>
+ </message>
+ <message>
+ <source>Set key pool size to <n> (default: %u)</source>
+ <translation>Définir la taille de la réserve de clefs à <n> (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Définir la taille de bloc minimale en octets (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
+ <translation>Définit le drapeau DB_PRIVATE dans l'environnement de la BD du portefeuille (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Spécifier le fichier de configuration (par défaut : %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Spécifier le délai d'expiration de la connexion en millisecondes (minimum : 1, par défaut : %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Spécifier le fichier pid (par défaut : %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Dépenser la monnaie non confirmée lors de l'envoi de transactions (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Stop running after importing blocks from disk (default: %u)</source>
+ <translation>Cesser l'exécution après l'importation des blocs du disque (par défaut : %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Seuil de déconnexion des pairs présentant un mauvais comportement (par défaut : %u)</translation>
+ </message>
<message>
<source>Unknown network specified in -onlynet: '%s'</source>
<translation>Réseau inconnu spécifié sur -onlynet : « %s »</translation>
-<TS language="fr_CA" version="2.1">
+<TS language="fr_CA" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Address</source>
- <translation>Addresse</translation>
- </message>
<message>
<source>(no label)</source>
<translation>(pas de record)</translation>
-<TS language="gl" version="2.1">
+<TS language="gl" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Cantidade</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Dirección</translation>
- </message>
<message>
<source>Date</source>
<translation>Data</translation>
<source>&Main</source>
<translation>&Principal</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Tarifa por kB de transacción opcional que axuda a asegurar que as túas transaccións son procesadas rapidamente. A maioría das transaccións son 1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Pagar &tarifa da transacción</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Comezar Bitcoin automáticamente despois de loguearse no sistema.</translation>
-<TS language="gu_IN" version="2.1">
+<TS language="gu_IN" version="2.0">
<context>
<name>AddressBookPage</name>
</context>
-<TS language="he" version="2.1">
+<TS language="he" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>בחירת כתובת שליטה במטבעות</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>כמות:</translation>
<source>Amount</source>
<translation>כמות</translation>
</message>
- <message>
- <source>Address</source>
- <translation>כתובת</translation>
- </message>
<message>
<source>Date</source>
<translation>תאריך</translation>
<source>&Main</source>
<translation>&ראשי</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>עמלת העברה כרשות לכל ק״ב תבטיח שההעברה שלך תעובד בזריזות. רוב ההעברות הן בנפח של ק״ב אחד.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>תשלום &עמלת העברה</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>הפעלת ביטקוין אוטומטית לאחר כניסה למערכת.</translation>
<source>Allow incoming connections</source>
<translation>לאפשר חיבורים נכנסים</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>התחברות לרשת ביטקוין דרך מתווך SOCKS.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>הת&חברות באמצעות מתווך SOCKS (מתווך בררת מחדל):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>כתובת ה־IP של המתווך (לדוגמה IPv4: 127.0.0.1 / IPv6: ::1)</translation>
-<TS language="hi_IN" version="2.1">
+<TS language="hi_IN" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>राशि</translation>
</message>
- <message>
- <source>Address</source>
- <translation>पता</translation>
- </message>
<message>
<source>Date</source>
<translation>taareek</translation>
-<TS language="hr" version="2.1">
+<TS language="hr" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Iznos</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Adresa</translation>
- </message>
<message>
<source>Date</source>
<translation>Datum</translation>
<source>&Main</source>
<translation>&Glavno</translation>
</message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Plati &naknadu za transakciju</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Automatski pokreni Bitcoin kad se uključi računalo</translation>
-<TS language="hu" version="2.1">
+<TS language="hu" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Ellenőrző cím kiválasztása</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Mennyiség:</translation>
<source>Amount</source>
<translation>Összeg</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Cím</translation>
- </message>
<message>
<source>Date</source>
<translation>Dátum</translation>
<source>&Main</source>
<translation>&Fő</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Opcionális, kB-onkénti tranzakciós díj a tranzakcióid minél gyorsabb feldolgozásának elősegítésére. A legtöbb tranzakció 1 kB-os.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Tranzakciós &díj fizetése</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Induljon el a Bitcoin a számítógép bekapcsolásakor</translation>
<source>MB</source>
<translation>MB</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>SOCKS proxyn keresztüli csatlakozás a Bitcoin hálózatához.</translation>
- </message>
<message>
<source>Reset all client options to default.</source>
<translation>Minden kliensbeállítás alapértelmezettre állítása.</translation>
-<TS language="id_ID" version="2.1">
+<TS language="id_ID" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Pilihan alamat pengaturan koin</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Kuantitas:</translation>
<source>Amount</source>
<translation>Nilai</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Alamat</translation>
- </message>
<message>
<source>Date</source>
<translation>Tanggal</translation>
<source>&Main</source>
<translation>&Utama</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Biaya transaksi untuk setiap kB yang membantu transaksi Andi diproses cepat (biayanya opsional). Ukuran transaksi biasanya 1kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Bayar &biaya transaksi</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Menyalakan Bitcoin secara otomatis setelah masuk ke dalam sistem.</translation>
<source>MB</source>
<translation>MB</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Menghubungkan jaringan Bitcoin lewat proxy SOCKS.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Hubungkan melalui proxy SOCKS (proxy biasa):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Alamat IP proxy (cth. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
-<TS language="it" version="2.1">
+<TS language="it" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Up to date</source>
<translation>Aggiornato</translation>
</message>
+ <message numerus="yes">
+ <source>Processed %n blocks of transaction history.</source>
+ <translation><numerusform>Processati %n blocchi dello storico transazioni.</numerusform><numerusform>Processati %n blocchi dello storico delle transazioni.</numerusform></translation>
+ </message>
<message>
<source>Catching up...</source>
<translation>In aggiornamento...</translation>
<context>
<name>CoinControlDialog</name>
<message>
- <source>Coin Control Address Selection</source>
- <translation>Selezione Indirizzo Coin Control</translation>
+ <source>Coin Selection</source>
+ <translation>Seleziona Moneta
+</translation>
</message>
<message>
<source>Quantity:</source>
<translation>Importo</translation>
</message>
<message>
- <source>Address</source>
- <translation>Indirizzo</translation>
+ <source>Received with label</source>
+ <translation>Ricevuto con etichetta</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Ricevuto con l'indirizzo</translation>
</message>
<message>
<source>Date</source>
<source>&Main</source>
<translation>&Principale</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Commissione di transazione per kB: è opzionale e contribuisce ad assicurare che le transazioni siano elaborate velocemente. La maggior parte della transazioni ha dimensioni pari a 1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Paga la &commissione</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Avvia automaticamente Bitcoin una volta effettuato l'accesso al sistema.</translation>
<source>Allow incoming connections</source>
<translation>Permetti connessioni in entrata</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Connessione alla rete Bitcoin attraverso un proxy SOCKS.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Connessione attraverso proxy SOCKS (proxy predefinito):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Indirizzo IP del proxy (es: IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Map port using &UPnP</source>
<translation>Mappa le porte tramite &UPnP</translation>
</message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Connessione alla rete Bitcoin attraverso un proxy SOCKS5.</translation>
+ </message>
+ <message>
+ <source>&Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&Connessione attraverso proxy SOCKS5 (proxy predefinito):</translation>
+ </message>
<message>
<source>Proxy &IP:</source>
<translation>&IP del proxy:</translation>
<source>Unconfirmed transactions to watch-only addresses</source>
<translation>Transazioni non confermate su indirizzi di sola lettura</translation>
</message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>l'equilibrio estratto solo nello sguardo degli indirizzi non è ancora maturo </translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Saldo corrente totale negli indirizzi watch-only</translation>
+ </message>
<message>
<source>out of sync</source>
<translation>non sincronizzato</translation>
<source>Starting Height</source>
<translation>Blocco di partenza</translation>
</message>
+ <message>
+ <source>Sync Height</source>
+ <translation>valore di sincronizzazione</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>divieto di segnalazione </translation>
+ </message>
<message>
<source>Connection Time</source>
<translation>Tempo di connessione</translation>
<source>Unknown</source>
<translation>Sconosciuto</translation>
</message>
- </context>
+ <message>
+ <source>Fetching...</source>
+ <translation>attraente</translation>
+ </message>
+</context>
<context>
<name>ReceiveCoinsDialog</name>
<message>
<source>Custom change address</source>
<translation>Personalizza indirizzo di resto</translation>
</message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Tasse di Transazione</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Scegli...</translation>
+ </message>
+ <message>
+ <source>Minimize</source>
+ <translation>Minimizza</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilobyte</translation>
+ </message>
+ <message>
+ <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>Pagando solo la tariffa minima è bene finché c'è meno volume di transazioni di spazio nei blocchi. Ma essere consapevoli che questo può finire in una transazione non confermando ancora una volta non vi è più richiesta per le transazioni Bitcoin di rete in grado di elaborare.</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Raccomandati:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Personalizza:</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Tempo di conferma:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normale</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>veloce</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Invia una transazione a zero commissioni se possibile</translation>
+ </message>
<message>
<source>Send to multiple recipients at once</source>
<translation>Invia a diversi beneficiari in una volta sola</translation>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Imposta la dimensione massima in byte delle transazioni ad alta-priorità/basse-commissioni (predefinita: %d)</translation>
</message>
+ <message>
+ <source>Cannot resolve -whitebind address: '%s'</source>
+ <translation>Impossibile risolvere -whitebind address: '%s'</translation>
+ </message>
+ <message>
+ <source>Connect through SOCKS5 proxy</source>
+ <translation>Connetti attraverso SOCKS5 proxy</translation>
+ </message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Errore caricamento wallet.dat: il wallet richiede una versione nuova di Bitcoin Core</translation>
+ </message>
+ <message>
+ <source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
+ <translation>Commissione (in BTC/kB) da aggiungere alla transazione che invii (default: %s)</translation>
+ </message>
<message>
<source>Information</source>
<translation>Informazioni</translation>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Invia le informazioni di trace/debug alla console invece che al file debug.log</translation>
</message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Invia transazioni a zero commissioni se possibile (default: %u)</translation>
+ </message>
<message>
<source>Show all debugging options (usage: --help -help-debug)</source>
<translation>Mostra tutte le opzioni di debug (utilizzo: --help -help-debug)</translation>
<source>Error loading wallet.dat</source>
<translation>Errore caricamento wallet.dat</translation>
</message>
+ <message>
+ <source>Force safe mode (default: %u)</source>
+ <translation>Forza modalità provvisoria (dafault: %u)</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Genera coins (default: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Quanti blocchi da controllare all'avvio (dafault: %u, 0 = tutti)</translation>
+ </message>
<message>
<source>Invalid -proxy address: '%s'</source>
<translation>Indirizzo -proxy non valido: '%s'</translation>
</message>
+ <message>
+ <source>Maintain at most <n> connections to peers (default: %u)</source>
+ <translation>Mantieni al massimo <n> connessioni ai peers (default: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Pretendi output di debug con timestamp (default: %u)</translation>
+ </message>
+ <message>
+ <source>Print block tree on startup (default: %u)</source>
+ <translation>Stampa l'albero dei blocchi all'avvio (default: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>File certificato del server (default: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Chiave privata del server (default: %s)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Specifica il file di configurazione (default: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Specifica il timeout di connessione in millisecondi (minimo:1, default: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Specifica il file pid (default: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Spendi il resto non confermato quando si inviano transazioni (default: %u)</translation>
+ </message>
+ <message>
+ <source>Stop running after importing blocks from disk (default: %u)</source>
+ <translation>Interrompi dopo aver importato i blocchi dal disco (default: %u)</translation>
+ </message>
<message>
<source>Unknown network specified in -onlynet: '%s'</source>
<translation>Rete sconosciuta specificata in -onlynet: '%s'</translation>
-<TS language="ja" version="2.1">
+<TS language="ja" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
<translation>これらは支払いを送信するためのあなたの Bitcoin アドレスです。コインを送信する前に、常に額と受信アドレスを確認してください。</translation>
</message>
+ <message>
+ <source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
+ <translation>これらは支払いを受け取るためのビットコインアドレスです。トランザクションごとに新しい受け取り用アドレスを作成することが推奨されます。</translation>
+ </message>
<message>
<source>Copy &Label</source>
<translation>ラベルをコピー (&L)</translation>
<source>Exporting Failed</source>
<translation>エクスポート失敗</translation>
</message>
- </context>
+ <message>
+ <source>There was an error trying to save the address list to %1. Please try again.</source>
+ <translation>トランザクション履歴を %1 へ保存する際にエラーが発生しました。再試行してください。</translation>
+ </message>
+</context>
<context>
<name>AddressTableModel</name>
<message>
<source>Wallet encrypted</source>
<translation>ウォレットは暗号化されました</translation>
</message>
+ <message>
+ <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>ウォレットの新しいパスフレーズを入力してください。<br/><b>10文字以上のランダムな文字</b>で構成されたものか、<b>8単語以上の単語</b>で構成されたパスフレーズを使用してください。</translation>
+ </message>
<message>
<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 は暗号化プロセスを終了するために今すぐ終了します。あなたのコンピュータがマルウェアに感染してコインを盗まれることもあるので、暗号化してもあなたのウォレットを完全に保護できないことを覚えていてください。</translation>
<source>Open &URI...</source>
<translation>URI を開く (&U)...</translation>
</message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoinコア クライアント</translation>
+ </message>
<message>
<source>Importing blocks from disk...</source>
<translation>ディスクからブロックをインポートしています...</translation>
<source>&Receive</source>
<translation>受信 (&R)</translation>
</message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Bitcoinコアに関する情報を表示</translation>
+ </message>
<message>
<source>&Show / Hide</source>
<translation>見る/隠す (&S)</translation>
<source>Bitcoin Core</source>
<translation>Bitcoin のコア</translation>
</message>
+ <message>
+ <source>Request payments (generates QR codes and bitcoin: URIs)</source>
+ <translation>支払いを要求する (QRコードとbitcoin:ではじまるURIを生成する)</translation>
+ </message>
<message>
<source>&About Bitcoin Core</source>
<translation>ビットコインコアについて (&A)</translation>
</message>
+ <message>
+ <source>Show the list of used sending addresses and labels</source>
+ <translation>使用済みの送金用アドレスとラベルの一覧を表示する</translation>
+ </message>
<message>
<source>Show the list of used receiving addresses and labels</source>
<translation>支払いを受け取るアドレスとラベルのリストを表示する</translation>
</context>
<context>
<name>CoinControlDialog</name>
+ <message>
+ <source>Coin Selection</source>
+ <translation>コイン選択</translation>
+ </message>
<message>
<source>Quantity:</source>
<translation>数量:</translation>
<source>Amount</source>
<translation>総額</translation>
</message>
- <message>
- <source>Address</source>
- <translation>アドレス</translation>
- </message>
<message>
<source>Date</source>
<translation>日付</translation>
<source>Copy transaction ID</source>
<translation>取引 ID をコピー</translation>
</message>
+ <message>
+ <source>Lock unspent</source>
+ <translation>未使用トランザクションをロックする</translation>
+ </message>
+ <message>
+ <source>Unlock unspent</source>
+ <translation>未使用トランザクションをアンロックする</translation>
+ </message>
<message>
<source>Copy quantity</source>
<translation>数量をコピーする</translation>
<source>version</source>
<translation>バージョン</translation>
</message>
+ <message>
+ <source>About Bitcoin Core</source>
+ <translation>Bitcoinコアについて</translation>
+ </message>
<message>
<source>Command-line options</source>
<translation>コマンドライン オプション</translation>
<source>Error</source>
<translation>エラー</translation>
</message>
- </context>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GBの空き容量が利用可能</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(%n GB必要)</numerusform></translation>
+ </message>
+</context>
<context>
<name>OpenURIDialog</name>
<message>
<source>&Main</source>
<translation>メイン (&M)</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>あたなの取引が早く処理されるように任意で kB 毎の取引手数料を設定します。ほとんどの取引は 1 kB です。</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>支払う取引手数料 (&f)</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>システムにログインした時に自動的に Bitcoin を起動します。</translation>
<source>MB</source>
<translation>MB</translation>
</message>
+ <message>
+ <source>Number of script &verification threads</source>
+ <translation>スクリプト検証用スレッド数 (&V)</translation>
+ </message>
+ <message>
+ <source>Accept connections from outside</source>
+ <translation>外部からの接続を許可する</translation>
+ </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>プロキシのIPアドレス (例えば IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Your current total balance</source>
<translation>あなたの現在の残高</translation>
</message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>最近のトランザクション</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>ウォッチオンリーアドレスの採掘された残高のうち、成熟していないもの</translation>
+ </message>
<message>
<source>out of sync</source>
<translation>同期していない</translation>
<source>Invalid payment address %1</source>
<translation>支払いのアドレス「%1」は無効です</translation>
</message>
+ <message>
+ <source>Payment request rejected</source>
+ <translation>支払い要求は拒否されました</translation>
+ </message>
+ <message>
+ <source>Payment request has expired.</source>
+ <translation>支払いのリクエストは期限切れです</translation>
+ </message>
<message>
<source>Payment request error</source>
<translation>支払いのリクエストのエラーです</translation>
</context>
<context>
<name>PeerTableModel</name>
+ <message>
+ <source>User Agent</source>
+ <translation>ユーザエージェント</translation>
+ </message>
</context>
<context>
<name>QObject</name>
<source>Current number of blocks</source>
<translation>現在のブロック数</translation>
</message>
+ <message>
+ <source>User Agent</source>
+ <translation>ユーザエージェント</translation>
+ </message>
<message>
<source>Last block time</source>
<translation>最終ブロックの日時</translation>
<source>&Message:</source>
<translation>メッセージ (&M):</translation>
</message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>全ての入力項目をクリア</translation>
+ </message>
<message>
<source>Clear</source>
<translation>クリア</translation>
<source>Show</source>
<translation>表示</translation>
</message>
+ <message>
+ <source>Remove the selected entries from the list</source>
+ <translation>リストから選択項目を削除</translation>
+ </message>
<message>
<source>Copy label</source>
<translation>ラベルをコピーする</translation>
<source>Add &Recipient</source>
<translation>受取人を追加 (&R)</translation>
</message>
+ <message>
+ <source>Clear all fields of the form.</source>
+ <translation>全ての入力項目をクリア</translation>
+ </message>
<message>
<source>Clear &All</source>
<translation>すべてクリア (&A)</translation>
</context>
<context>
<name>ShutdownWindow</name>
- </context>
+ <message>
+ <source>Bitcoin Core is shutting down...</source>
+ <translation>Bitcoin Coreをシャットダウンしています。</translation>
+ </message>
+ <message>
+ <source>Do not shut down the computer until this window disappears.</source>
+ <translation>このウィンドウが消えるまでコンピュータをシャットダウンしないで下さい。</translation>
+ </message>
+</context>
<context>
<name>SignVerifyMessageDialog</name>
<message>
</context>
<context>
<name>WalletFrame</name>
- </context>
+ <message>
+ <source>No wallet has been loaded.</source>
+ <translation>ウォレットがロードされていません</translation>
+ </message>
+</context>
<context>
<name>WalletModel</name>
<message>
-<TS language="ka" version="2.1">
+<TS language="ka" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>მონეტების კონტროლის მისამართის არჩევა</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>რაოდენობა:</translation>
<source>Amount</source>
<translation>თანხა</translation>
</message>
- <message>
- <source>Address</source>
- <translation>მისამართი</translation>
- </message>
<message>
<source>Date</source>
<translation>თარიღი</translation>
<source>&Main</source>
<translation>&მთავარი</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>დამატებითი საკომისიო თითო კილობაიტზე; აჩქარებს ტრანსაქციის შესრულებას. ტრანსაქციების უმეტესობა არის 1 კბ.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>ტრანსაქციის სა&ფასურის გადახდა</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>სისტემაში შესვლის შემდეგ Bitcoin-ის ავტომატური გაშვება.</translation>
<source>Number of script &verification threads</source>
<translation>სკრიპტის &ვერიფიცირების ნაკადების რაოდენობა</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Bitcoin-ქსელზე მიერთება SOCKS-პროქსით.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>SO&CKS (ნაგულისხმევი) პროქსი მიერთებისათვის:</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>პროქსის IP-მისამართი (მაგ.: IPv4: 127.0.0.1 / IPv6: ::1)</translation>
-<TS language="kk_KZ" version="2.1">
+<TS language="kk_KZ" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Create a new address</source>
<translation>Жаңа адрес енгізу</translation>
</message>
+ <message>
+ <source>&New</source>
+ <translation>Жаңа</translation>
+ </message>
<message>
<source>Copy the currently selected address to the system clipboard</source>
<translation>Таңдаған адресті тізімнен жою</translation>
</message>
+ <message>
+ <source>C&lose</source>
+ <translation>Жабу</translation>
+ </message>
+ <message>
+ <source>&Export</source>
+ <translation>Экспорт</translation>
+ </message>
<message>
<source>&Delete</source>
<translation>Жою</translation>
</context>
<context>
<name>BitcoinGUI</name>
+ <message>
+ <source>&Transactions</source>
+ <translation>&Транзакциялар</translation>
+ </message>
+ <message>
+ <source>E&xit</source>
+ <translation>Шығу</translation>
+ </message>
+ <message>
+ <source>&Options...</source>
+ <translation>Параметрлері</translation>
+ </message>
+ <message>
+ <source>&Backup Wallet...</source>
+ <translation>Әмиянды жасыру</translation>
+ </message>
+ <message>
+ <source>&Change Passphrase...</source>
+ <translation>Құпия сөзді өзгерту</translation>
+ </message>
+ <message>
+ <source>Bitcoin</source>
+ <translation>Биткоин</translation>
+ </message>
+ <message>
+ <source>Wallet</source>
+ <translation>Әмиян</translation>
+ </message>
+ <message>
+ <source>&Send</source>
+ <translation>Жіберу</translation>
+ </message>
+ <message>
+ <source>&Receive</source>
+ <translation>Алу</translation>
+ </message>
+ <message>
+ <source>&File</source>
+ <translation>Файл</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>Көмек</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n сағат</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n күн</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n апта</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 and %2</source>
+ <translation>%1 немесе %2</translation>
+ </message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n жыл</numerusform></translation>
+ </message>
+ <message>
+ <source>%1 behind</source>
+ <translation>%1 қалмады</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>қате</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Ескерту</translation>
+ </message>
+ <message>
+ <source>Information</source>
+ <translation>Информация</translation>
+ </message>
+ <message>
+ <source>Up to date</source>
+ <translation>Жаңартылған</translation>
+ </message>
</context>
<context>
<name>ClientModel</name>
<context>
<name>CoinControlDialog</name>
<message>
- <source>Address</source>
- <translation>Адрес</translation>
+ <source>Amount:</source>
+ <translation>Саны</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Басымдық</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Комиссия</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Шаң</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Комиссия алу кейін</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Саны</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Күні</translation>
+ </message>
+ <message>
+ <source>Confirmations</source>
+ <translation>Растау саны</translation>
+ </message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Растық</translation>
+ </message>
+ <message>
+ <source>Priority</source>
+ <translation>Басымдық</translation>
+ </message>
+ <message>
+ <source>no</source>
+ <translation>жоқ</translation>
</message>
<message>
<source>(no label)</source>
</context>
<context>
<name>EditAddressDialog</name>
+ <message>
+ <source>&Address</source>
+ <translation>Адрес</translation>
+ </message>
</context>
<context>
<name>FreespaceChecker</name>
</context>
<context>
<name>Intro</name>
+ <message>
+ <source>Error</source>
+ <translation>қате</translation>
+ </message>
</context>
<context>
<name>OpenURIDialog</name>
</context>
<context>
<name>QObject</name>
+ <message>
+ <source>Amount</source>
+ <translation>Саны</translation>
+ </message>
</context>
<context>
<name>QRImageWidget</name>
<source>Address</source>
<translation>Адрес</translation>
</message>
+ <message>
+ <source>Amount</source>
+ <translation>Саны</translation>
+ </message>
<message>
<source>Label</source>
<translation>таңба</translation>
</context>
<context>
<name>RecentRequestsTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Күні</translation>
+ </message>
<message>
<source>Label</source>
<translation>таңба</translation>
</message>
+ <message>
+ <source>Amount</source>
+ <translation>Саны</translation>
+ </message>
<message>
<source>(no label)</source>
<translation>(таңбасыз)</translation>
</context>
<context>
<name>SendCoinsDialog</name>
+ <message>
+ <source>Amount:</source>
+ <translation>Саны</translation>
+ </message>
+ <message>
+ <source>Priority:</source>
+ <translation>Басымдық</translation>
+ </message>
+ <message>
+ <source>Fee:</source>
+ <translation>Комиссия:</translation>
+ </message>
+ <message>
+ <source>After Fee:</source>
+ <translation>Комиссия алу кейін:</translation>
+ </message>
+ <message>
+ <source>Dust:</source>
+ <translation>Шаң</translation>
+ </message>
<message>
<source>(no label)</source>
<translation>(таңбасыз)</translation>
</context>
<context>
<name>TransactionDesc</name>
+ <message>
+ <source>Date</source>
+ <translation>Күні</translation>
+ </message>
+ <message>
+ <source>Amount</source>
+ <translation>Саны</translation>
+ </message>
</context>
<context>
<name>TransactionDescDialog</name>
</context>
<context>
<name>TransactionTableModel</name>
+ <message>
+ <source>Date</source>
+ <translation>Күні</translation>
+ </message>
<message>
<source>Address</source>
<translation>Адрес</translation>
<source>Comma separated file (*.csv)</source>
<translation>Үтірмен бөлінген файл (*.csv)</translation>
</message>
+ <message>
+ <source>Confirmed</source>
+ <translation>Растық</translation>
+ </message>
+ <message>
+ <source>Date</source>
+ <translation>Күні</translation>
+ </message>
<message>
<source>Label</source>
<translation>таңба</translation>
</context>
<context>
<name>WalletView</name>
+ <message>
+ <source>&Export</source>
+ <translation>Экспорт</translation>
+ </message>
</context>
<context>
<name>bitcoin-core</name>
+ <message>
+ <source>Information</source>
+ <translation>Информация</translation>
+ </message>
<message>
<source>Transaction amount too small</source>
<translation>Транзакция өте кішкентай</translation>
<source>Transaction too large</source>
<translation>Транзакция өте үлкен</translation>
</message>
- </context>
+ <message>
+ <source>Warning</source>
+ <translation>Ескерту</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>қате</translation>
+ </message>
+</context>
</TS>
\ No newline at end of file
-<TS language="ko_KR" version="2.1">
+<TS language="ko_KR" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>코인 컨트롤 주소 선택</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>수량:</translation>
<source>Amount</source>
<translation>거래량</translation>
</message>
- <message>
- <source>Address</source>
- <translation>주소</translation>
- </message>
<message>
<source>Date</source>
<translation>날짜</translation>
<source>&Main</source>
<translation>메인(&M)</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>당신의 거래가 더욱 빠르게 처리될 수 있도록 선택적으로 kBd당 거래 수수료를 지정합니다. 참고로 대부분의 거래들은 1kB입니다.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>송금 수수료(&F)</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>시스템 로그인후에 비트코인을 자동으로 시작합니다.</translation>
<source>Allow incoming connections</source>
<translation>연결 요청을 허용합니다.</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>SOCKS 프록시를 통해 비트코인 네트워크 연결</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>SOCKS 프록시를 거쳐 연결합니다 (기본값 프록시):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>프록시 아이피 주소(예. IPv4:127.0.0.1 / IPv6: ::1)</translation>
<source>Enter a label for this address to add it to the list of used addresses</source>
<translation>사용된 주소 목록에 새 주소를 추가하기 위해 제목을 입력합니다. </translation>
</message>
+ <message>
+ <source>A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source>
+ <translation>비트코인에 첨부된 메시지: 참고용으로 거래와 함께 저장될 URI. 메모: 이 메시지는 비트코인 네트워크로 전송되지 않습니다.</translation>
+ </message>
<message>
<source>This is an unverified payment request.</source>
<translation>지급요청 미확인입니다</translation>
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
<translation>어떤 포트도 반응하지 않습니다. 사용자 반응=0 만약 원한다면</translation>
</message>
+ <message>
+ <source>If <category> is not supplied, output all debugging information.</source>
+ <translation><카테고리>가 제공되지 않을 경우, 모든 디버깅 정보를 출력</translation>
+ </message>
<message>
<source>Importing...</source>
<translation>들여오기 중...</translation>
-<TS language="ky" version="2.1">
+<TS language="ky" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Address</source>
- <translation>Дарек</translation>
- </message>
<message>
<source>Date</source>
<translation>Дата</translation>
-<TS language="la" version="2.1">
+<TS language="la" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Quantitas</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Inscriptio</translation>
- </message>
<message>
<source>Date</source>
<translation>Dies</translation>
<source>&Main</source>
<translation>&Princeps</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Optionalis merces transactionum singulis kB quae adiuvat curare tuas transactiones processas esse celeriter. Plurimi transactiones 1kB sunt.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Solve &mercedem transactionis</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Pelle Bitcoin per se postquam in systema inire.</translation>
-<TS language="lt" version="2.1">
+<TS language="lt" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Suma</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Adresas</translation>
- </message>
<message>
<source>Date</source>
<translation>Data</translation>
<source>&Main</source>
<translation>&Pagrindinės</translation>
</message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>&Mokėti sandorio mokestį</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Automatiškai paleisti Bitkoin programą įjungus sistemą.</translation>
-<TS language="lv_LV" version="2.1">
+<TS language="lv_LV" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Open &URI...</source>
<translation>Atvērt &URI...</translation>
</message>
+ <message>
+ <source>Bitcoin Core client</source>
+ <translation>Bitcoin Core klients</translation>
+ </message>
<message>
<source>Importing blocks from disk...</source>
<translation>Importē blokus no diska...</translation>
</message>
<message>
<source>&Receive</source>
- <translation>Saņe&mt</translation>
+ <translation>&Saņemt</translation>
+ </message>
+ <message>
+ <source>Show information about Bitcoin Core</source>
+ <translation>Parādīt informāciju par Bitcoin Core</translation>
</message>
<message>
<source>&Show / Hide</source>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Bitcoin Kontroles Adrešu Atlase</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Daudzums:</translation>
<source>Amount</source>
<translation>Daudzums</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Adrese</translation>
- </message>
<message>
<source>Date</source>
<translation>Datums</translation>
<source>&Main</source>
<translation>&Galvenais</translation>
</message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>&Maksāt par transakciju</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Automātiski sākt Bitcoin pēc pieteikšanās sistēmā.</translation>
<source>Number of script &verification threads</source>
<translation>Skriptu &pārbaudes pavedienu skaits</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Savienoties ar Bitcoin tīklu caur SOCKS starpniekserveri.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Savienoties caur SOCKS starpniekserveri (noklusējuma starpniekserveris)</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Starpniekservera IP adrese (piem. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
-<TS language="mn" version="2.1">
+<TS language="mn" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Хэмжээ</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Хаяг</translation>
- </message>
<message>
<source>Date</source>
<translation>Огноо</translation>
<source>MB</source>
<translation>МБ</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Биткойны сүлжээрүү SOCKS проксигоор холбогдох.</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>проксигийн IP хаяг (жишээ нь: IPv4: 127.0.0.1 / IPv6: ::1)</translation>
-<TS language="ms_MY" version="2.1">
+<TS language="ms_MY" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Address</source>
- <translation>Alamat</translation>
- </message>
</context>
<context>
<name>EditAddressDialog</name>
-<TS language="nb" version="2.1">
+<TS language="nb" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<context>
<name>CoinControlDialog</name>
<message>
- <source>Coin Control Address Selection</source>
- <translation>Myntkontroll Adresse Valg</translation>
+ <source>Coin Selection</source>
+ <translation>Mynt Valg</translation>
</message>
<message>
<source>Quantity:</source>
<translation>Beløp</translation>
</message>
<message>
- <source>Address</source>
- <translation>Adresse</translation>
+ <source>Received with label</source>
+ <translation>Mottatt med merkelapp</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Mottatt med adresse</translation>
</message>
<message>
<source>Date</source>
<source>&Main</source>
<translation>&Hoved</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Valgfritt transaksjonsgebyr per kB som sikrer at dine transaksjoner blir raskt prosessert. De fleste transaksjoner er 1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Betal &transaksjonsgebyr</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Start Bitcoin automatisk etter innlogging.</translation>
<source>Allow incoming connections</source>
<translation>Tillatt innkommende tilkoblinger</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Koble til Bitcoin-nettverket gjennom en SOCKS proxy.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Koble til gjennom SOCKS proxy (standardvalg proxy):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>IP-adressen til proxyen (f.eks. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Map port using &UPnP</source>
<translation>Sett opp port ved hjelp av &UPnP</translation>
</message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Koble til Bitcoin-nettverket gjennom en SOCKS5 proxy.</translation>
+ </message>
+ <message>
+ <source>&Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&Koble til gjennom SOCKS5 proxy (standardvalg proxy):</translation>
+ </message>
<message>
<source>Proxy &IP:</source>
<translation>Proxy &IP:</translation>
<source>Custom change address</source>
<translation>Egendefinert adresse for veksel</translation>
</message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Transaksjonsgebyr:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Velg...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>Legg ned gebyrinnstillinger</translation>
+ </message>
+ <message>
+ <source>Minimize</source>
+ <translation>Minimer</translation>
+ </message>
+ <message>
+ <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>Hvis den egendefinerte avgiften er satt til 1000 satoshis og transaksjonen bare er 250 bytes, da vil "per kilobyte" bare betale 250 satoshis i gebyr, mens "minst" betaler 1000 satoshis. For transaksjoner større enn en kilobyte vil begge betale for antall kilobyte.</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilobyte</translation>
+ </message>
+ <message>
+ <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>Hvis den egendefinerte avgiften er satt til 1000 satoshis og transaksjonen bare er 250 bytes, da vil "per kilobyte" bare betale 250 satoshis i gebyr, mens "minstebeløp" betaler 1000 satoshis. For transaksjoner større enn en kilobyte vil begge betale for antall kilobyte.</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>minstebeløp</translation>
+ </message>
+ <message>
+ <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>Betaling av bare minimumsavgiften går helt fint så lenge det er mindre transaksjonsvolum enn plass i blokkene. Men vær klar over at dette kan ende opp i en transaksjon som aldri blir bekreftet når det er mer etterspørsel etter Bitcoin-transaksjoner enn nettverket kan behandle.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(les verktøytipset)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Anbefalt:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Egendefinert:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Smartgebyr ikke innført ennå. Dette tar vanligvis noen blokker...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Bekreftelsestid:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>rask</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Send uten transaksjonsgebyr hvis mulig</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(bekreftelse kan ta lengre tid)</translation>
+ </message>
<message>
<source>Send to multiple recipients at once</source>
<translation>Send til flere enn en mottaker</translation>
<source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
<translation>Transaksjonen ble avvist! Dette kan skje hvis noen av myntene i lommeboken allerede er brukt, som hvis du kopierte wallet.dat og mynter ble brukt i kopien uten å bli markert som brukt her.</translation>
</message>
+ <message>
+ <source>A fee higher than %1 is considered an insanely high fee.</source>
+ <translation>Et gebyr høyere enn %1 er ansett som et sinnsykt høyt gebyr.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Betal kun minimumsgebyret på %1</translation>
+ </message>
+ <message>
+ <source>Estimated to begin confirmation within %1 block(s).</source>
+ <translation>Beregner å begynne bekreftelse innen %1 blokk(er).</translation>
+ </message>
<message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Advarsel: Ugyldig Bitcoin-adresse</translation>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Slett alle transaksjoner i lommeboken og gjenopprett kun de delene av blokkjeden gjennom -rescan ved oppstart</translation>
</message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
+ <translation>Distribuert under MIT programvarelisensen, se medfølgende fil COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation>
+ </message>
<message>
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
<translation>Gå til modus for regresjonstesting, som bruker en spesiell blokkjede der blokker kan bli løst momentant.</translation>
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
<translation>Opprett nye filer med standardtillatelser i systemet, i stedet for umask 077 (kun virksom med lommebokfunksjonalitet slått av)</translation>
</message>
- <message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>Distribuert under MIT/X11 programvarelisensen, se medfølgende fil COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation>
- </message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Feil: Lytting etter innkommende tilkoblinger feilet (lytting returnerte feil %s)</translation>
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
<translation>Gebyrer (i BTC/Kb) mindre enn dette anses som null gebyr for laging av transaksjoner (standardverdi: %s)</translation>
</message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maksimal størrelse på data i databærende transaksjoner vi videresender og ufører graving på (standardverdi: %u)</translation>
+ </message>
<message>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation>Søk etter nodeadresser via DNS-oppslag, hvis vi har få adresser å koble til (standard: 1 med mindre -connect)</translation>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Sett maksimum størrelse for transaksjoner med høy prioritet / lavt gebyr, i bytes (standardverdi: %d)</translation>
</message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Angi antall tråder for mynt generering hvis aktivert (-1 = alle kjerner, standardverdi: %d)</translation>
+ </message>
<message>
<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>Dette produktet inneholder programvare utviklet av OpenSSL Project for bruk i OpenSSL Toolkit <https://www.openssl.org/> og kryptografisk programvare skrevet av Eric Young og UPnP-programvare skrevet av Thomas Bernard.</translation>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Send spor-/feilsøkingsinformasjon til konsollen istedenfor filen debug.log</translation>
</message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Send transaksjoner uten transaksjonsgebyr hvis mulig (standardverdi: %u)</translation>
+ </message>
<message>
<source>Show all debugging options (usage: --help -help-debug)</source>
<translation>Vis alle feilsøkingsvalg (bruk: --help -help-debug)</translation>
<source>Output debugging information (default: %u, supplying <category> is optional)</source>
<translation>Ta ut feilsøkingsinformasjon (standardverdi: %u, bruk av <category> er valgfritt)</translation>
</message>
- <message>
- <source>Set the processor limit for when generation is on (-1 = unlimited, default: %d)</source>
- <translation>Sett prosessorgrensen for når blokkutvinning er på (-1 = ubegrenset, standardverdi: %d)</translation>
- </message>
<message>
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
<translation>Bruk separate SOCKS5 proxyer for å nå noder via Tor skjulte tjenester (standardverdi: %s)</translation>
-<TS language="nl" version="2.1">
+<TS language="nl" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</message>
<message>
<source>These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.</source>
- <translation>Dit zijn uw Bitcoinadressen om betalingen mee te verzenden. Check altijd het bedrag en het ontvangende adres voordat u uw bitcoins verzendt.</translation>
+ <translation>Dit zijn uw Bitcoinadressen om betalingen mee te verzenden. Controleer altijd het bedrag en het ontvangende adres voordat u uw bitcoins verzendt.</translation>
</message>
<message>
<source>These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.</source>
<source>Wallet encrypted</source>
<translation>Portemonnee versleuteld</translation>
</message>
+ <message>
+ <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>Vul een nieuw </translation>
+ </message>
<message>
<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 zal nu afsluiten om het versleutelingsproces te voltooien. Onthoud dat het versleutelen van uw portemonnee u niet volledig kan beschermen: Malware kan uw computer infecteren en uw bitcoins stelen.</translation>
<source>Up to date</source>
<translation>Bijgewerkt</translation>
</message>
+ <message numerus="yes">
+ <source>Processed %n blocks of transaction history.</source>
+ <translation><numerusform>%n Blok verwerkt van transactie geschiedenis.</numerusform><numerusform>%n Blokken verwerkt van transactie geschiedenis.</numerusform></translation>
+ </message>
<message>
<source>Catching up...</source>
<translation>Aan het bijwerken...</translation>
<context>
<name>CoinControlDialog</name>
<message>
- <source>Coin Control Address Selection</source>
- <translation>Coin controle adres selectie</translation>
+ <source>Coin Selection</source>
+ <translation>Munt Selectie</translation>
</message>
<message>
<source>Quantity:</source>
<translation>Bedrag</translation>
</message>
<message>
- <source>Address</source>
- <translation>Adres</translation>
+ <source>Received with label</source>
+ <translation>Ontvangen met label</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Ontvangen met adres</translation>
</message>
<message>
<source>Date</source>
<source>%n GB of free space available</source>
<translation><numerusform>%n GB aan vrije oplsagruimte beschikbaar</numerusform><numerusform>%n GB aan vrije oplsagruimte beschikbaar</numerusform></translation>
</message>
- </context>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(van %n GB nodig)</numerusform><numerusform>(van %n GB nodig)</numerusform></translation>
+ </message>
+</context>
<context>
<name>OpenURIDialog</name>
<message>
<source>&Main</source>
<translation>&Algemeen</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Optionele transactiekosten per kB. Transactiekosten helpen ervoor te zorgen dat uw transacties snel verwerkt worden. De meeste transacties zijn 1kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Betaal &transactiekosten</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Start Bitcoin automatisch na inloggen in het systeem</translation>
<source>Allow incoming connections</source>
<translation>Sta inkomende verbindingen toe</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Verbind met het Bitcoin-netwerk via een SOCKS-proxy.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Verbind via een SOCKS-proxy (standaardproxy):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>IP-adres van de proxy (bijv. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Map port using &UPnP</source>
<translation>Portmapping via &UPnP</translation>
</message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Verbind met het Bitcoin netwerk via een SOCKS5 proxy.</translation>
+ </message>
+ <message>
+ <source>&Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&Verbind via een SOCKS5-proxy (standaardproxy):</translation>
+ </message>
<message>
<source>Proxy &IP:</source>
<translation>Proxy &IP:</translation>
<source>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source>
<translation>De weergegeven informatie kan verouderd zijn. Uw portemonnee synchroniseert automaticsh met het Bitcoinnetwerk nadat een verbinding is gelegd, maar dit proces is nog niet voltooid.</translation>
</message>
+ <message>
+ <source>Watch-only:</source>
+ <translation>Alleen-bekijkbaar:</translation>
+ </message>
<message>
<source>Available:</source>
<translation>Beschikbaar:</translation>
<source>Mined balance that has not yet matured</source>
<translation>Gedolven saldo dat nog niet tot wasdom is gekomen</translation>
</message>
+ <message>
+ <source>Balances</source>
+ <translation>Saldi</translation>
+ </message>
<message>
<source>Total:</source>
<translation>Totaal:</translation>
<source>Your current total balance</source>
<translation>Uw totale saldo</translation>
</message>
+ <message>
+ <source>Your current balance in watch-only addresses</source>
+ <translation>Uw huidige balans in alleen-bekijkbare adressen</translation>
+ </message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Besteedbaar:</translation>
+ </message>
<message>
<source>Recent transactions</source>
<translation>Recente transacties</translation>
</message>
+ <message>
+ <source>Unconfirmed transactions to watch-only addresses</source>
+ <translation>Onbevestigde transacties naar alleen-bekijkbare adressen</translation>
+ </message>
+ <message>
+ <source>Mined balance in watch-only addresses that has not yet matured</source>
+ <translation>Ontgonnen saldo dat nog niet tot wasdom is gekomen</translation>
+ </message>
+ <message>
+ <source>Current total balance in watch-only addresses</source>
+ <translation>Huidige balans in alleen-bekijkbare adressen.</translation>
+ </message>
<message>
<source>out of sync</source>
<translation>niet gesynchroniseerd</translation>
<source>Payment request rejected</source>
<translation>Betalingsverzoek geweigerd</translation>
</message>
+ <message>
+ <source>Payment request network doesn't match client network.</source>
+ <translation>Betalingsaanvraagnetwerk komt niet overeen met klantennetwerk.</translation>
+ </message>
<message>
<source>Payment request has expired.</source>
<translation>Betalingsverzoek is verlopen.</translation>
</message>
+ <message>
+ <source>Payment request is not initialized.</source>
+ <translation>Betalingsaanvraag is niet geïnitialiseerd.</translation>
+ </message>
<message>
<source>Requested payment amount of %1 is too small (considered dust).</source>
<translation>Het gevraagde betalingsbedrag van %1 is te weinig (beschouwd als stof).</translation>
<source>Payment request fetch URL is invalid: %1</source>
<translation>URL om betalingsverzoek te verkrijgen is ongeldig: %1</translation>
</message>
+ <message>
+ <source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
+ <translation>URI kan niet verwerkt worden! Dit kan het gevolg zijn van een ongeldig Bitcoin adres of misvormde URI parameters.</translation>
+ </message>
<message>
<source>Payment request file handling</source>
<translation>Betalingsverzoek bestandsafhandeling</translation>
</message>
+ <message>
+ <source>Payment request file cannot be read! This can be caused by an invalid payment request file.</source>
+ <translation>Betalingsverzoek-bestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoek-bestand.</translation>
+ </message>
<message>
<source>Unverified payment requests to custom payment scripts are unsupported.</source>
<translation>Niet-geverifieerde betalingsverzoeken naar aangepaste betaling scripts worden niet ondersteund.</translation>
<source>Error communicating with %1: %2</source>
<translation>Fout bij communiceren met %1: %2</translation>
</message>
+ <message>
+ <source>Payment request cannot be parsed!</source>
+ <translation>Betalingsverzoek kan niet juist worden ontleed of verwerkt!</translation>
+ </message>
<message>
<source>Bad response from server %1</source>
<translation>Ongeldige respons van server %1</translation>
<source>User Agent</source>
<translation>User Agent</translation>
</message>
- </context>
+ <message>
+ <source>Address/Hostname</source>
+ <translation>Adres/Hostnaam</translation>
+ </message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping tijd</translation>
+ </message>
+</context>
<context>
<name>QObject</name>
<message>
<source>Using OpenSSL version</source>
<translation>Gebruikt OpenSSL versie</translation>
</message>
+ <message>
+ <source>Using BerkeleyDB version</source>
+ <translation>Gebruikt BerkeleyDB versie</translation>
+ </message>
<message>
<source>Startup time</source>
<translation>Opstarttijd</translation>
<source>Sent</source>
<translation>Verstuurd</translation>
</message>
+ <message>
+ <source>&Peers</source>
+ <translation>&Peers</translation>
+ </message>
+ <message>
+ <source>Select a peer to view detailed information.</source>
+ <translation>Selecteer een peer om gedetailleerde informatie te bekijken.</translation>
+ </message>
<message>
<source>Direction</source>
<translation>Directie</translation>
<source>Services</source>
<translation>Services</translation>
</message>
+ <message>
+ <source>Starting Height</source>
+ <translation>Aanvangshoogte</translation>
+ </message>
+ <message>
+ <source>Sync Height</source>
+ <translation>Synchronisatiehoogte</translation>
+ </message>
+ <message>
+ <source>Ban Score</source>
+ <translation>Ban score</translation>
+ </message>
<message>
<source>Connection Time</source>
<translation>Connectie tijd</translation>
<source>Bytes Received</source>
<translation>Bytes Ontvangen</translation>
</message>
+ <message>
+ <source>Ping Time</source>
+ <translation>Ping Tijd</translation>
+ </message>
<message>
<source>Last block time</source>
<translation>Tijd laatste blok</translation>
<source>never</source>
<translation>nooit</translation>
</message>
+ <message>
+ <source>Inbound</source>
+ <translation>Inkomend</translation>
+ </message>
+ <message>
+ <source>Outbound</source>
+ <translation>Uitgaand</translation>
+ </message>
<message>
<source>Unknown</source>
<translation>Onbekend</translation>
</message>
- </context>
+ <message>
+ <source>Fetching...</source>
+ <translation>Ophalen...</translation>
+ </message>
+</context>
<context>
<name>ReceiveCoinsDialog</name>
<message>
<source>Custom change address</source>
<translation>Aangepast wisselgeldadres</translation>
</message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Transactiekosten:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Kies...</translation>
+ </message>
+ <message>
+ <source>Minimize</source>
+ <translation>Minimaliseer</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilobyte</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>totaal ten minste</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Aanbevolen:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Handmatig:</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Bevestigings tijd:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normaal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>snel</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(bevestiging kan langer duren)</translation>
+ </message>
<message>
<source>Send to multiple recipients at once</source>
<translation>Verstuur aan verschillende ontvangers ineens</translation>
<source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
<translation>De transactie was afgewezen. Dit kan gebeuren als u eerder uitgegeven munten opnieuw wilt versturen, zoals wanneer u een kopie van uw wallet.dat heeft gebruikt en in de kopie deze munten zijn gemarkeerd als uitgegeven, maar in de huidige nog niet.</translation>
</message>
+ <message>
+ <source>A fee higher than %1 is considered an insanely high fee.</source>
+ <translation>Transactiekosten hoger dan %1 worden gezien als waanzinnig hoog.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Betaal alleen de minimale transactiekosten van %1</translation>
+ </message>
+ <message>
+ <source>Estimated to begin confirmation within %1 block(s).</source>
+ <translation>Beginnen van bevesting geschat binnen %1 blok(ken).</translation>
+ </message>
<message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Waarschuwing: Ongeldig Bitcoin adres</translation>
<source>This is a normal payment.</source>
<translation>Dit is een normale betaling.</translation>
</message>
+ <message>
+ <source>The Bitcoin address to send the payment to</source>
+ <translation>Het Bitcoin adres om betaling aan te voldoen</translation>
+ </message>
<message>
<source>Alt+A</source>
<translation>Alt+A</translation>
<source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
<translation>U kunt berichten ondertekenen met een van uw adressen om te bewijzen dat u dit adres bezit. Pas op dat u geen onduidelijke dingen ondertekent, want phishingaanvallen zouden u kunnen misleiden om zo uw identiteit te stelen. Onderteken alleen berichten waarmee u het volledig eens bent.</translation>
</message>
+ <message>
+ <source>The Bitcoin address to sign the message with</source>
+ <translation>Het Bitcoin adres om bericht mee te ondertekenen</translation>
+ </message>
<message>
<source>Choose previously used address</source>
<translation>Kies een eerder gebruikt adres</translation>
<source>Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack.</source>
<translation>Voer het ondertekenende adres, bericht en handtekening hieronder in (let erop dat u nieuwe regels, spaties en tabs juist overneemt) om de handtekening te verifiëren. Let erop dat u niet meer uit het bericht interpreteert dan er daadwerkelijk staat, om te voorkomen dat u wordt misleid in een man-in-the-middle-aanval.</translation>
</message>
+ <message>
+ <source>The Bitcoin address the message was signed with</source>
+ <translation>Het Bitcoin adres waarmee het bericht ondertekend is</translation>
+ </message>
<message>
<source>Verify the message to ensure it was signed with the specified Bitcoin address</source>
<translation>Controleer een bericht om te verifiëren dat het gespecificeerde Bitcoinadres het bericht heeft ondertekend.</translation>
<source>own address</source>
<translation>eigen adres</translation>
</message>
+ <message>
+ <source>watch-only</source>
+ <translation>alleen-bekijkbaar</translation>
+ </message>
<message>
<source>label</source>
<translation>label</translation>
<source>Debit</source>
<translation>Debet</translation>
</message>
+ <message>
+ <source>Total debit</source>
+ <translation>Totaal debit</translation>
+ </message>
+ <message>
+ <source>Total credit</source>
+ <translation>Totaal credit</translation>
+ </message>
<message>
<source>Transaction fee</source>
<translation>Transactiekosten</translation>
<source>Mined</source>
<translation>Gedolven</translation>
</message>
+ <message>
+ <source>watch-only</source>
+ <translation>alleen-bekijkbaar</translation>
+ </message>
<message>
<source>(n/a)</source>
<translation>(nvt)</translation>
<source>Export Transaction History</source>
<translation>Exporteer Transactieverleden</translation>
</message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Alleen-bekijkbaar</translation>
+ </message>
<message>
<source>Exporting Failed</source>
<translation>Export Mislukt</translation>
</context>
<context>
<name>UnitDisplayStatusBarControl</name>
- </context>
+ <message>
+ <source>Unit to show amounts in. Click to select another unit.</source>
+ <translation>Eenheid om bedragen uit te drukken. Klik om een andere eenheid te selecteren.</translation>
+ </message>
+</context>
<context>
<name>WalletFrame</name>
<message>
<source>This is intended for regression testing tools and app development.</source>
<translation>Dit is bedoeld voor regressie test toepassingen en applicatie onwikkeling.</translation>
</message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Gebruik UPnP om de luisterende poort te mappen (standaard: %u)</translation>
+ </message>
<message>
<source>Verifying blocks...</source>
<translation>Blokken aan het controleren...</translation>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Stel maximumgrootte in bytes in voor hoge-prioriteits-/lage-transactiekosten-transacties (standaard: %d)</translation>
</message>
+ <message>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin Core</source>
+ <translation>Fout bij laden wallet.dat: Portemonnee vereist een nieuwere versie van Bitcoin Core</translation>
+ </message>
<message>
<source>Information</source>
<translation>Informatie</translation>
<source>Invalid amount for -mintxfee=<amount>: '%s'</source>
<translation>Ongeldig bedrag voor -mintxfee=<bedrag>: '%s'</translation>
</message>
+ <message>
+ <source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source>
+ <translation>Ongeldig bedrag voor -paytxfee=<bedrag>: '%s' (Minimum %s)</translation>
+ </message>
+ <message>
+ <source>Keep at most <n> unconnectable blocks in memory (default: %u)</source>
+ <translation>Houd maximaal <n> onverbonden blokken in geheugen (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source>
+ <translation>Houd maximaal <n> onverbonden transacties in geheugen (standaard: %u)</translation>
+ </message>
<message>
<source>Print block on startup, if found in block index</source>
<translation>Toon block bij opstarten, wanneer gevonden in block index</translation>
<source>Error loading wallet.dat: Wallet corrupted</source>
<translation>Fout bij laden wallet.dat: Portemonnee corrupt</translation>
</message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Onderhoud een volledige transactieindex, gebruikt door de getrawtransaction rpc call (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Aantal seconden dat zich misdragende peers niet opnieuw kunnen verbinden (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying <category> is optional)</source>
+ <translation>Output extra debugginginformatie (standaard: %u, het leveren van <category> is optioneel)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Gebruik een aparte SOCKS5 proxy om 'Tor hidden services' te bereiken (standaard: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Vind anderen door middel van een DNS-naslag (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Disable safemode, override a real safe mode event (default: %u)</source>
+ <translation>Veilige modus uitschakelen, hef een echte veilige modus gebeurtenis uit (default: %u)</translation>
+ </message>
<message>
<source>Error loading wallet.dat</source>
<translation>Fout bij laden wallet.dat</translation>
</message>
+ <message>
+ <source>Force safe mode (default: %u)</source>
+ <translation>Forceer veilige modus (default: %u)</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Genereer munten (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Aantal te checken blokken bij het opstarten (standaard: %u, 0 = allemaal)</translation>
+ </message>
<message>
<source>Invalid -proxy address: '%s'</source>
<translation>Ongeldig -proxy adres: '%s'</translation>
</message>
+ <message>
+ <source>Limit size of signature cache to <n> entries (default: %u)</source>
+ <translation>Limiteer grootte van de handtekening cache tot <n> entries (default: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source>
+ <translation>Luister naar JSON-RPC-verbindingen op poort <port> (standaard: %u of testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on <port> (default: %u or testnet: %u)</source>
+ <translation>Luister naar verbindingen op <poort> (standaard: %u of testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most <n> connections to peers (default: %u)</source>
+ <translation>Onderhoud maximaal <n> verbindingen naar peers (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source>
+ <translation>Maximum per-connectie ontvangstbuffer, <n>*1000 bytes (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source>
+ <translation>Maximum per-connectie zendbuffer, <n>*1000 bytes (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
+ <translation>Accepteer alleen blokkenketen die overeenkomt met de ingebouwde checkpoints (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Prepend debug output met tijdstempel (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Print block tree on startup (default: %u)</source>
+ <translation>Toon block structuur bij opstarten (default: %u)</translation>
+ </message>
+ <message>
+ <source>Run a thread to flush wallet periodically (default: %u)</source>
+ <translation>Draai een proces om de wallet periodiek te flushen (default: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Certificaat-bestand voor server (standaard: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Geheime sleutel voor server (standaard: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to <n> (default: %u)</source>
+ <translation>Stel sleutelpoelgrootte in op <&> (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Stel minimum blokgrootte in in bytes (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Stel het aantal threads in om RPC-aanvragen mee te bedienen (standaard: %d)</translation>
+ </message>
+ <message>
+ <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
+ <translation>Plaatst de DB_PRIVATE vlag in de wallet db omgeving (default: %u)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Specificeer configuratie bestand (standaard: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Specificeer de time-out tijd in milliseconden (minimum: 1, standaard: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Specificeer pid-bestand (standaard: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Besteed onbevestigd wisselgeld bij het versturen van transacties (standaard: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Drempel om verbinding te verbreken naar zich misdragende peers (standaard: %u)</translation>
+ </message>
<message>
<source>Unknown network specified in -onlynet: '%s'</source>
<translation>Onbekend netwerk gespecificeerd in -onlynet: '%s'</translation>
-<TS language="pam" version="2.1">
+<TS language="pam" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Alaga</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Address</translation>
- </message>
<message>
<source>Date</source>
<translation>Kaaldauan</translation>
<source>&Main</source>
<translation>&Pun</translation>
</message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Mamayad &bayad para king transaksion </translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Umpisan yang antimu ing Bitcoin kaibat mekapag-log in king sistema.</translation>
-<TS language="pl" version="2.1">
+<TS language="pl" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Kwota</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Adres</translation>
- </message>
<message>
<source>Date</source>
<translation>Data</translation>
<source>&Main</source>
<translation>Główne</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Opcjonalna prowizja za transakcje za kB, wspomaga ona szybkość przebiegu transakcji. Większość transakcji jest 1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Płać prowizję za transakcje</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Automatycznie uruchamia Bitcoin po zalogowaniu do systemu.</translation>
<source>Allow incoming connections</source>
<translation>Zezwól na połączenia przychodzące</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Połącz się z siecią Bitcoin poprzez SOCKS proxy.</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Adres IP serwera proxy (np. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
-<TS language="pt_BR" version="2.1">
+<TS language="pt_BR" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Coin Control Address Selection</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Quantidade:</translation>
<source>Amount</source>
<translation>Quantidade</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Endereço</translation>
- </message>
<message>
<source>Date</source>
<translation>Data</translation>
<source>Error</source>
<translation>Erro</translation>
</message>
- </context>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB de espaço livre disponível</numerusform><numerusform>%n GB de espaço livre disponível</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(de %n GB necessário)</numerusform><numerusform>(de %n GB necessário)</numerusform></translation>
+ </message>
+</context>
<context>
<name>OpenURIDialog</name>
<message>
<source>&Main</source>
<translation>Principal</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Taxa de transação opcional por kB que ajuda a garantir que suas transações sejam processadas rapidamente. A maioria das transações são de 1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Pagar taxa de &transação</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Iniciar Bitcoin automaticamente após se logar no sistema.</translation>
<source>Allow incoming connections</source>
<translation>Permitir conexões de entrada</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Conectado na rede do Bitcoin através de proxy SOCKS.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Conectado via proxy SOCKS (padrão proxy):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Endereço de IP do proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Mined balance that has not yet matured</source>
<translation>Saldo minerado que ainda não maturou</translation>
</message>
+ <message>
+ <source>Balances</source>
+ <translation>Saldos</translation>
+ </message>
<message>
<source>Total:</source>
<translation>Total:</translation>
<source>Your current balance in watch-only addresses</source>
<translation>Sua balança atual em endereços apenas visualizados</translation>
</message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Transações recentes</translation>
+ </message>
<message>
<source>out of sync</source>
<translation>fora de sincronia</translation>
-<TS language="pt_PT" version="2.1">
+<TS language="pt_PT" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Seleção de Endereço Coin Control</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Quantidade:</translation>
<source>Amount</source>
<translation>Quantia</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Endereço</translation>
- </message>
<message>
<source>Date</source>
<translation>Data</translation>
<source>&Main</source>
<translation>&Principal</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Taxa de transação opcional por KB que ajuda a assegurar que as suas transações serão processadas rapidamente. A maioria das transações tem 1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Pagar &taxa de transação</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Começar o Bitcoin automaticamente ao iniciar sessão no sistema.</translation>
<source>Number of script &verification threads</source>
<translation>Número de processos de &verificação de scripts</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Ligar à rede Bitcoin através de um proxy SOCKS.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>Ligar através de um proxy SO&CKS (proxy por defeito):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Endereço IP do proxy (p.ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
-<TS language="ro_RO" version="2.1">
+<TS language="ro_RO" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Selectare Adresă de Comandă Monedă</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Cantitate:</translation>
<source>Amount</source>
<translation>Sumă</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Adresă</translation>
- </message>
<message>
<source>Date</source>
<translation>Data</translation>
<source>version</source>
<translation>versiunea</translation>
</message>
+ <message>
+ <source>(%1-bit)</source>
+ <translation>(%1-bit)</translation>
+ </message>
<message>
<source>About Bitcoin Core</source>
<translation>Despre Nucleul Bitcoin</translation>
<source>&Main</source>
<translation>&Principal</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Taxa optionala de tranzactie per kB care ajuta ca tranzactiile dumneavoastra sa fie procesate rapid. Majoritatea tranzactiilor sunt 1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Plăteşte comision pentru tranzacţie &f</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Porneşte automat programul Bitcoin la pornirea computerului.</translation>
<source>MB</source>
<translation>MB</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Conecteaza-te la reteaua Bitcoin printr-un proxy SOCKS</translation>
- </message>
<message>
<source>Reset all client options to default.</source>
<translation>Resetează toate setările clientului la valorile implicite.</translation>
-<TS language="ru" version="2.1">
+<TS language="ru" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<context>
<name>CoinControlDialog</name>
<message>
- <source>Coin Control Address Selection</source>
- <translation>Ð\92Ñ\8bбоÑ\80 адÑ\80еÑ\81а конÑ\82Ñ\80олÑ\8f монеÑ\82</translation>
+ <source>Coin Selection</source>
+ <translation>Выбор монет</translation>
</message>
<message>
<source>Quantity:</source>
<translation>Сумма</translation>
</message>
<message>
- <source>Address</source>
- <translation>Адрес</translation>
+ <source>Received with label</source>
+ <translation>Получено с пометкой</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Получено с адреса</translation>
</message>
<message>
<source>Date</source>
<source>&Main</source>
<translation>&Главная</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Необязательная комиссия за каждый КБ транзакции, которая ускоряет обработку Ваших транзакций. Большинство транзакций занимают 1КБ.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Заплатить ко&миссию</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Автоматически запускать Bitcoin после входа в систему</translation>
<source>Allow incoming connections</source>
<translation>Разрешить входящие подключения</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Подключаться к сети Bitcoin через прокси SOCKS.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Подключаться через SOCKS прокси (прокси по умолчанию):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>IP-адрес прокси (например IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Map port using &UPnP</source>
<translation>Пробросить порт через &UPnP</translation>
</message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Подключаться к сети Bitcoin через прокси SOCKS5</translation>
+ </message>
+ <message>
+ <source>&Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&Подключаться к сети Bitcoin через прокси SOCKS5 (прокси по умолчанию):</translation>
+ </message>
<message>
<source>Proxy &IP:</source>
<translation>&IP Прокси: </translation>
<source>Custom change address</source>
<translation>Свой адрес для сдачи</translation>
</message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Комиссия</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Выберите...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>Свернуть настройки комиссии</translation>
+ </message>
+ <message>
+ <source>Minimize</source>
+ <translation>Сворачивать</translation>
+ </message>
+ <message>
+ <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>Если комиссия установлена в 1000 сатоши, а транзакция составляет лишь 250 байт, тогда комиссия "на килобайт" составит 250 сатоши, а "как минимум" — 1000 сатоши. Для транзакций крупнее килобайта в обоих случаях будет использоваться платёж "на килобайт".</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>за килобайт</translation>
+ </message>
+ <message>
+ <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>Если комиссия установлена в 1000 сатоши, а транзакция составляет лишь 250 байт, тогда комиссия "на килобайт" составит 250 сатоши, а "всего как минимум" — 1000 сатоши. Для транзакций крупнее килобайта в обоих случаях будет использоваться платёж "на килобайт".</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>Итого как минимум</translation>
+ </message>
+ <message>
+ <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>Уплата минимальной комиссии — не проблема, пока объём транзакций меньше, чем свободное место в блоках. Учтите, однако, что такая транзакция может никогда не подтвердиться, если спрос на транзакции превышает возможности сети по их обработке.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(прочтите подсказку)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Рекомендовано:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Выборочно:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Умная комиссия пока не инициализирована. Обычно для этого требуется несколько блоков...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Время подтверждения:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>обычный</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>ускоренный</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Осуществить транзакцию бесплатно, если возможно</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(подтверждение может занять больше времени)</translation>
+ </message>
<message>
<source>Send to multiple recipients at once</source>
<translation>Отправить нескольким получателям одновременно</translation>
<source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
<translation>Транзакция была отклонена! Такое может произойти, если некоторые монеты уже были потрачены, например, если Вы используете одну копию бумажника (wallet.dat), а монеты были потрачены из другой копии, но не были отмечены как потраченные в этой.</translation>
</message>
+ <message>
+ <source>A fee higher than %1 is considered an insanely high fee.</source>
+ <translation>Комиссия больше, чем %1, считается невероятно большой.</translation>
+ </message>
+ <message>
+ <source>Estimated to begin confirmation within %1 block(s).</source>
+ <translation>Начало подтверждения ожидается через %1 блок(ов).</translation>
+ </message>
<message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Внимание: неверный адрес Bitcoin</translation>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Удалить все транзакции бумажника с возможностью восстановить эти части цепи блоков с помощью -rescan при запуске</translation>
</message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
+ <translation>Распространяется под лицензией MIT, см. приложенный файл COPYING или <http://www.opensource.org/licenses/mit-license.php>.</translation>
+ </message>
<message>
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
<translation>Войти в режим тестирования на регрессии, в котором используется специальная цепь, где блоки находятся мгновенно.</translation>
<source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
<translation>Внимание: wallet.dat повреждён, данные спасены! Оригинальный wallet.dat сохранён как wallet.{timestamp}.bak в %s; если ваш баланс или транзакции некорректны, вы должны восстановить файл из резервной копии.</translation>
</message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Вносить в белый список участников, подключающихся с указанной маски сети или IP. Можно использовать многократно.</translation>
+ </message>
<message>
<source>(default: 1)</source>
<translation>(по умолчанию: 1)</translation>
<source>This is intended for regression testing tools and app development.</source>
<translation>Это рассчитано на инструменты регрессионного тестирования и разработку приложений.</translation>
</message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Использовать UPnP для проброса порта (по умолчанию: %u)</translation>
+ </message>
<message>
<source>Verifying blocks...</source>
<translation>Проверка блоков...</translation>
<translation>Не удалось установить блокировку на каталог данных %s. Возможно, Bitcoin Core уже запущен.</translation>
</message>
<message>
- <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
- <translation>СоздаваÑ\82Ñ\8c новÑ\8bе Ñ\84айлÑ\8b Ñ\81 Ñ\81иÑ\81Ñ\82емнÑ\8bми пÑ\80авами по Ñ\83молÑ\87аниÑ\8e вмеÑ\81Ñ\82о umask 077 (Ñ\8dÑ\84Ñ\84екÑ\82ивно Ñ\82олÑ\8cко пÑ\80и оÑ\82клÑ\8eÑ\87енном бÑ\83мажнике)</translation>
+ <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source>
+ <translation>Ð\9eгÑ\80аниÑ\87иÑ\82Ñ\8c Ñ\81коÑ\80оÑ\81Ñ\82Ñ\8c пеÑ\80едаÑ\87и беÑ\81плаÑ\82нÑ\8bÑ\85 Ñ\82Ñ\80анзакÑ\86ий до <n>*1000 байÑ\82 в минÑ\83Ñ\82Ñ\83 (по Ñ\83молÑ\87аниÑ\8e: %u)</translation>
</message>
<message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>РаÑ\81пÑ\80оÑ\81Ñ\82Ñ\80анÑ\8fеÑ\82Ñ\81Ñ\8f под лиÑ\86ензией MIT/X11, Ñ\81м. пÑ\80иложеннÑ\8bй Ñ\84айл COPYING или <http://www.opensource.org/licenses/mit-license.php>.</translation>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>СоздаваÑ\82Ñ\8c новÑ\8bе Ñ\84айлÑ\8b Ñ\81 Ñ\81иÑ\81Ñ\82емнÑ\8bми пÑ\80авами по Ñ\83молÑ\87аниÑ\8e вмеÑ\81Ñ\82о umask 077 (Ñ\8dÑ\84Ñ\84екÑ\82ивно Ñ\82олÑ\8cко пÑ\80и оÑ\82клÑ\8eÑ\87енном бÑ\83мажнике)</translation>
</message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
<translation>Комиссии (в BTC/Кб) меньшие этого значения считаются нулевыми для создания транзакции (по умолчанию: %s)</translation>
</message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Наибольший размер данных в носителе данных транзакций, которые мы передаем и генерируем (по умолчанию: %u)</translation>
+ </message>
<message>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation>Запрашивать адреса участников с помощью DNS, если адресов мало (по умолчанию: 1, если не указан -connect)</translation>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Задать максимальный размер высокоприоритетных/низкокомиссионных транзакций в байтах (по умолчанию: %d)</translation>
</message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Задать число потоков генерации монет, если она включена (-1 = все ядра процессора, по умолчанию: %d)</translation>
+ </message>
<message>
<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>Этот продукт включает ПО, разработанное OpenSSL Project для использования в OpenSSL Toolkit <https://www.openssl.org/> и криптографическое ПО, написанное Eric Young и ПО для работы с UPnP, написанное Thomas Bernard.</translation>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Выводить информацию трассировки/отладки на консоль вместо файла debug.log</translation>
</message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Осуществить транзакцию бесплатно, если возможно (по умолчанию: %u)</translation>
+ </message>
<message>
<source>Show all debugging options (usage: --help -help-debug)</source>
<translation>Показать все отладочные параметры (использование: --help -help-debug)</translation>
<source>Error loading wallet.dat: Wallet corrupted</source>
<translation>Ошибка загрузки wallet.dat: Бумажник поврежден</translation>
</message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = сохранять метаданные транзакции: например, владельца аккаунта и информацию запроса платежа; 2 = отбросить метаданные)</translation>
+ </message>
+ <message>
+ <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source>
+ <translation>Сбрасывать активность базы данных из памяти на диск каждые <n> мегабайт (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Насколько тщательна проверка контрольных блоков -checkblocks (0-4, по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source>
+ <translation>Если paytxfee не задан, включить достаточную комиссию для подтверждения транзакции в среднем за n блоков (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
+ <translation>Записывать в лог приоритет транзакции и комиссию на килобайт во время добычи блоков (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Держать полный индекс транзакций, используемый RPC-запросом getrawtransaction (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Число секунд блокирования неправильно ведущих себя узлов (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying <category> is optional)</source>
+ <translation>Выводить отладочную информацию (по умолчанию: %u, указание <category> необязательно)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Использовать отдельный прокси SOCKS5 для соединения с участниками через скрытые сервисы Tor (по умолчанию: %s)</translation>
+ </message>
<message>
<source>(default: %s)</source>
<translation>(по умолчанию: %s)</translation>
</message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Допустимые шифры (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Всегда запрашивать адреса участников с помощью DNS (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Disable safemode, override a real safe mode event (default: %u)</source>
+ <translation>Отключить безопасный режим, перекрыть реальное событие безопасного режима (по умолчанию: %u)</translation>
+ </message>
<message>
<source>Error loading wallet.dat</source>
<translation>Ошибка при загрузке wallet.dat</translation>
</message>
+ <message>
+ <source>Force safe mode (default: %u)</source>
+ <translation>Принудительный безопасный режим (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Включить добычу монет (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Сколько блоков проверять при запуске (по умолчанию: %u, 0 = все)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Включить IP-адреса в отладочный вывод (по умолчанию: %u)</translation>
+ </message>
<message>
<source>Invalid -proxy address: '%s'</source>
<translation>Неверный адрес -proxy: '%s'</translation>
</message>
+ <message>
+ <source>Limit size of signature cache to <n> entries (default: %u)</source>
+ <translation>Ограничить размер кэша подписей <n> записями (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source>
+ <translation>Прослушивать подключения JSON-RPC на <порту> (по умолчанию: %u или %u в тестовой сети)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on <port> (default: %u or testnet: %u)</source>
+ <translation>Принимать входящие подключения на <port> (по умолчанию: %u или %u в тестовой сети)</translation>
+ </message>
+ <message>
+ <source>Maintain at most <n> connections to peers (default: %u)</source>
+ <translation>Поддерживать не более <n> подключений к узлам (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source>
+ <translation>Максимальный размер буфера приёма на соединение, <n>*1000 байт (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source>
+ <translation>Максимальный размер буфера отправки на соединение, <n>*1000 байт (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
+ <translation>Принимать цепь блоков, лишь если она соответствует встроенным контрольным точкам (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Дописывать отметки времени к отладочному выводу (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Print block tree on startup (default: %u)</source>
+ <translation>Печатать дерево блоков при запуске (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Транслировать и генерировать транзакции носителей данных (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Транслировать не-P2SH мультиподпись (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Run a thread to flush wallet periodically (default: %u)</source>
+ <translation>Запустить поток для периодического сохранения бумажника (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Файл сертификата сервера (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Закрытый ключ сервера (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to <n> (default: %u)</source>
+ <translation>Установить размер пула ключей в <n> (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Задать число потоков выполнения запросов RPC (по умолчанию: %d)</translation>
+ </message>
+ <message>
+ <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
+ <translation>Установить флаг DB_PRIVATE в окружении базы данных бумажника (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Указать конфигурационный файл (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Указать тайм-аут соединения в миллисекундах (минимум: 1, по умолчанию: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Указать pid-файл (по умолчанию: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Тратить неподтвержденную сдачу при отправке транзакций (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Stop running after importing blocks from disk (default: %u)</source>
+ <translation>Остановиться после импорта блоков с диска (по умолчанию: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Порог для отключения неправильно ведущих себя узлов (по умолчанию: %u)</translation>
+ </message>
<message>
<source>Unknown network specified in -onlynet: '%s'</source>
<translation>В параметре -onlynet указана неизвестная сеть: '%s'</translation>
-<TS language="sah" version="2.1">
+<TS language="sah" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
-<TS language="sk" version="2.1">
+<TS language="sk" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options</source>
<translation>Zobraziť pomocnú správu od Bitcoin Jadra pre získanie zoznamu dostupných možností príkazového riadku</translation>
</message>
+ <message numerus="yes">
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n aktívne pripojenie do siete Bitcoin</numerusform><numerusform>%n aktívne pripojenia do siete Bitcoin</numerusform><numerusform>%n aktívnych pripojení do siete Bitcoin</numerusform></translation>
+ </message>
<message>
<source>No block source available...</source>
<translation>Nedostupný zdroj blokov...</translation>
</message>
+ <message numerus="yes">
+ <source>%n hour(s)</source>
+ <translation><numerusform>%n hodina</numerusform><numerusform>%n hodiny</numerusform><numerusform>%n hodín</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n day(s)</source>
+ <translation><numerusform>%n deň</numerusform><numerusform>%n dni</numerusform><numerusform>%n dní</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>%n week(s)</source>
+ <translation><numerusform>%n týždeň</numerusform><numerusform>%n týždne</numerusform><numerusform>%n týždňov</numerusform></translation>
+ </message>
<message>
<source>%1 and %2</source>
<translation> %1 a %2</translation>
</message>
+ <message numerus="yes">
+ <source>%n year(s)</source>
+ <translation><numerusform>%n rok</numerusform><numerusform>%n roky</numerusform><numerusform>%n rokov</numerusform></translation>
+ </message>
<message>
<source>%1 behind</source>
<translation>%1 pozadu</translation>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Coin Control výber adresy</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Množstvo:</translation>
<source>Amount</source>
<translation>Suma</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Adresa</translation>
- </message>
<message>
<source>Date</source>
<translation>Dátum</translation>
<source>&Main</source>
<translation>&Hlavné</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Voliteľný transakčný poplatok za kB ktorý pomôže rýchlemu spracovaniu transakcie. Väčšina transakcií má 1 kB. Poplatok 0.01 je odporúčaný.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Zaplatiť transakčné &poplatky</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Automaticky spustiť Bitcoin po zapnutí počítača</translation>
<source>Number of script &verification threads</source>
<translation>Počet skript overujucich vlákien</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Pripojiť k Bitcoin sieti cez SOCKS proxy.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>Pripojiť sa cez SOCKS proxy (predvolené proxy)</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>IP adresy proxy (napr. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
-<TS language="sl_SI" version="2.1">
+<TS language="sl_SI" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Količina</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Naslov</translation>
- </message>
<message>
<source>Date</source>
<translation>Datum</translation>
<source>&Main</source>
<translation>&Glavno</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Neobvezna pristojbina k transakciji poskrbi, da je transackcija hitro opravljena. Velikost povprečne transakcije je 1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Nakazilo plačila & provizija</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Po prijavi v sistem samodejno zaženite Bitcoin.</translation>
<source>Allow incoming connections</source>
<translation>Dovoli prihajajoče povezave</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>V Bitcoin omrežje se poveži skozu SOCKS proxy.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Poveži se skozi SOCKS proxy (privzet proxy):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>IP naslov proxy strežnika (npr. IPv4: 127.0.0.1 ali IPv6: ::1)</translation>
-<TS language="sq" version="2.1">
+<TS language="sq" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Sasia</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Adresë</translation>
- </message>
<message>
<source>Date</source>
<translation>Data</translation>
-<TS language="sr" version="2.1">
+<TS language="sr" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Double-click to edit address or label</source>
- <translation>Кликните два пута да промените адресу и/или етикету</translation>
+ <translation>Kliknite dva puta da izmenite adresu ili etiketu</translation>
</message>
<message>
<source>Create a new address</source>
- <translation>Прави нову адресу</translation>
+ <translation>Napravite novu adresu</translation>
+ </message>
+ <message>
+ <source>&New</source>
+ <translation>Novo</translation>
</message>
<message>
<source>Copy the currently selected address to the system clipboard</source>
- <translation>Копира изабрану адресу на системски клипборд</translation>
+ <translation>Kopirajte trenutno izabranu adresu</translation>
+ </message>
+ <message>
+ <source>&Copy</source>
+ <translation>Kopirajte</translation>
+ </message>
+ <message>
+ <source>&Copy Address</source>
+ <translation>Kopirajte adresu</translation>
+ </message>
+ <message>
+ <source>Delete the currently selected address from the list</source>
+ <translation>Izbrisite trenutno izabranu adresu sa liste</translation>
</message>
<message>
<source>&Delete</source>
<source>Amount</source>
<translation>iznos</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Адреса</translation>
- </message>
<message>
<source>Date</source>
<translation>datum</translation>
-<TS language="sv" version="2.1">
+<TS language="sv" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Up to date</source>
<translation>Uppdaterad</translation>
</message>
+ <message numerus="yes">
+ <source>Processed %n blocks of transaction history.</source>
+ <translation><numerusform>Bearbetat %n block av transaktionshistoriken.</numerusform><numerusform>Bearbetat %n block av transaktionshistoriken.</numerusform></translation>
+ </message>
<message>
<source>Catching up...</source>
<translation>Hämtar senaste...</translation>
<context>
<name>CoinControlDialog</name>
<message>
- <source>Coin Control Address Selection</source>
- <translation>Adressval för myntkontroll</translation>
+ <source>Coin Selection</source>
+ <translation>Myntval</translation>
</message>
<message>
<source>Quantity:</source>
<translation>Mängd</translation>
</message>
<message>
- <source>Address</source>
- <translation>Adress</translation>
+ <source>Received with label</source>
+ <translation>Mottagen med etikett</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Mottagen med adress</translation>
</message>
<message>
<source>Date</source>
<source>Error</source>
<translation>Fel</translation>
</message>
- </context>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>%n GB fritt utrymme kvar</numerusform><numerusform>%n GB fritt utrymme kvar</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(av %n GB behövs)</numerusform><numerusform>(av %n GB behövs)</numerusform></translation>
+ </message>
+</context>
<context>
<name>OpenURIDialog</name>
<message>
<source>&Main</source>
<translation>&Allmänt</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Valfri transaktionsavgift per kB som ser till att dina transaktioner behandlas snabbt. De flesta transaktioner är 1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Betala överförings&avgift</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Starta Bitcoin automatiskt efter inloggning.</translation>
<source>Allow incoming connections</source>
<translation>Acceptera inkommande anslutningar</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Anslut till Bitcoin-nätverket genom en SOCKS-proxy.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Anslut genom SOCKS-proxy (förvald proxy):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Proxyns IP-adress (t.ex. IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Map port using &UPnP</source>
<translation>Tilldela port med hjälp av &UPnP</translation>
</message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Anslut till Bitcoin-nätverket genom en SOCKS5-proxy.</translation>
+ </message>
+ <message>
+ <source>&Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&Anslut genom SOCKS5-proxy (förvald proxy):</translation>
+ </message>
<message>
<source>Proxy &IP:</source>
<translation>Proxy-&IP: </translation>
<source>Mined balance that has not yet matured</source>
<translation>Den genererade balansen som ännu inte har mognat</translation>
</message>
+ <message>
+ <source>Balances</source>
+ <translation>Balanser</translation>
+ </message>
<message>
<source>Total:</source>
<translation>Totalt:</translation>
<source>Your current balance in watch-only addresses</source>
<translation>Ditt nuvarande saldo i granska-bara adresser</translation>
</message>
+ <message>
+ <source>Spendable:</source>
+ <translation>Spenderbar:</translation>
+ </message>
+ <message>
+ <source>Recent transactions</source>
+ <translation>Nyligen genomförda transaktioner</translation>
+ </message>
<message>
<source>Unconfirmed transactions to watch-only addresses</source>
<translation>Okonfirmerade transaktioner till granska-bara adresser</translation>
<source>Custom change address</source>
<translation>Specialväxeladress</translation>
</message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Transaktionsavgift:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Välj...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>Fäll ihop avgiftsinställningarna</translation>
+ </message>
+ <message>
+ <source>Minimize</source>
+ <translation>Minimera</translation>
+ </message>
+ <message>
+ <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>Om den anpassad avgiften är satt till 1000 satoshi och transaktionen bara är 250 byte, betalar "per kilobyte" bara 250 satoshi i avgift, medans "minst" betalar 1000 satoshi. För transaktioner större än en kilobyte betalar både per kilobyte.</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>per kilobyte</translation>
+ </message>
+ <message>
+ <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>Om den anpassad avgiften är satt till 1000 satoshi och transaktionen bara är 250 byte, betalar "per kilobyte" bara 250 satoshi i avgift, medans "totalt minst" betalar 1000 satoshi. För transaktioner större än en kilobyte betalar både per kilobyte.</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>totalt minst</translation>
+ </message>
+ <message>
+ <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>Att betala endast den minsta avgiften är bara bra så länge det är mindre transaktionsvolym än utrymme i blocken. Men tänk på att det kan hamna i en aldrig bekräftar transaktion när det finns mer efterfrågan på bitcoin transaktioner än nätverket kan bearbeta.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(läs verktygstips)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Rekommenderad:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Anpassad:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Smartavgiften är inte initierad än. Detta tar vanligen några block...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Bekräftelsetid:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>snabb</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Sänd som nollavgiftstransaktion om möjligt</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(bekräftelse kan ta längre tid)</translation>
+ </message>
<message>
<source>Send to multiple recipients at once</source>
<translation>Skicka till flera mottagare samtidigt</translation>
<source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
<translation>Transaktionen avslogs! Detta kan hända om några av mynten i plånboken redan spenderats, t.ex om du använt en kopia av wallet.dat och mynt spenderades i kopian men inte markerats som spenderade här.</translation>
</message>
+ <message>
+ <source>A fee higher than %1 is considered an insanely high fee.</source>
+ <translation>En avgift högre än %1 anses som en onormalt hög avgift.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Betala endast den minimala avgiften på %1</translation>
+ </message>
+ <message>
+ <source>Estimated to begin confirmation within %1 block(s).</source>
+ <translation>Bekräftelsen beräknas börja inom %1 block.</translation>
+ </message>
<message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Varning: Felaktig Bitcoinadress</translation>
<source>Type of transaction.</source>
<translation>Transaktionstyp.</translation>
</message>
+ <message>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation>Anger om granska-bara--adresser är involverade i denna transaktion.</translation>
+ </message>
<message>
<source>Destination address of transaction.</source>
<translation>Transaktionens destinationsadress.</translation>
<source>Export Transaction History</source>
<translation>Exportera Transaktionshistoriken</translation>
</message>
+ <message>
+ <source>Watch-only</source>
+ <translation>Granska-bara</translation>
+ </message>
<message>
<source>Exporting Failed</source>
<translation>Exporteringen misslyckades</translation>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Ta bort alla plånbokstransaktioner och återskapa bara dom som är en del av blockkedjan genom att ange -rescan vid uppstart</translation>
</message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
+ <translation>Distribuerad under MIT mjukvarulicens, se den bifogade filen COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation>
+ </message>
<message>
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
<translation>Ange regressiontestläge, som använder en speciell kedja i vilka block kan lösas omedelbart.</translation>
<source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
<translation>Varning: wallet.dat korrupt, datan har räddats! Den ursprungliga wallet.dat har sparas som wallet.{timestamp}.bak i %s; om ditt saldo eller transaktioner är felaktiga ska du återställa från en säkerhetskopia.</translation>
</message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>Vitlista klienter som ansluter från angivna nätmasker eller IP-adresser. Kan specificeras flera gånger.</translation>
+ </message>
<message>
<source>(default: 1)</source>
<translation>(förvalt: 1)</translation>
<source>Error opening block database</source>
<translation>Fel vid öppning av blockdatabasen</translation>
</message>
+ <message>
+ <source>Error: A fatal internal error occured, see debug.log for details</source>
+ <translation>Fel: Ett fatalt internt fel inträffade. Se debug.log för detaljer</translation>
+ </message>
<message>
<source>Error: Disk space is low!</source>
<translation>Fel: Hårddiskutrymme är lågt!</translation>
<source>Not enough file descriptors available.</source>
<translation>Inte tillräckligt med filbeskrivningar tillgängliga.</translation>
</message>
+ <message>
+ <source>Only connect to nodes in network <net> (ipv4, ipv6 or onion)</source>
+ <translation>Anslut enbart till noder i nätverket <net> (IPv4, IPv6 eller onion)</translation>
+ </message>
<message>
<source>Rebuild block chain index from current blk000??.dat files</source>
<translation>Återskapa blockkedjans index från nuvarande blk000??.dat filer</translation>
<source>This is intended for regression testing tools and app development.</source>
<translation>Detta är avsett för regressionstestningsverktyg och applikationsutveckling.</translation>
</message>
+ <message>
+ <source>Use UPnP to map the listening port (default: %u)</source>
+ <translation>Använd UPnP för att mappa den lyssnande porten (förvalt: %u)</translation>
+ </message>
<message>
<source>Verifying blocks...</source>
<translation>Verifierar block...</translation>
<translation>Kan inte låsa data-mappen %s. Bitcoin Core körs förmodligen redan.</translation>
</message>
<message>
- <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
- <translation>Skapa nya filer med systemets förvalda rättigheter, istället för umask 077 (bara effektivt med avaktiverad plånboks funktionalitet)</translation>
+ <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source>
+ <translation>Antalsbegränsa kontinuerligt fria transaktioner till <n>*1000 bytes per minut (förvalt:%u)</translation>
</message>
<message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>Distribuerad under MIT/X11 mjukvarulicens, se den bifogade filen COPYING eller <http://www.opensource.org/licenses/mit-license.php>.</translation>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>Skapa nya filer med systemets förvalda rättigheter, istället för umask 077 (bara effektivt med avaktiverad plånboks funktionalitet)</translation>
</message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
<translation>Avgifter (i BTC/Kb) mindre än detta betraktas som nollavgift för transaktionsskapande (förvalt: %s)</translation>
</message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Maximal storlek på data i databärartransaktioner som vi reläar och bryter (förvalt: %u) </translation>
+ </message>
<message>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation>Sök efter klientadresser med DNS sökningen, om det finns otillräckligt med adresser (förvalt: 1 om inte -connect)</translation>
<source>Keep at most <n> unconnectable blocks in memory (default: %u)</source>
<translation>Håll som mest <n> oanslutningsbara block i minnet (förvalt: %u)</translation>
</message>
+ <message>
+ <source>Keep at most <n> unconnectable transactions in memory (default: %u)</source>
+ <translation>Håll som mest <n> oanslutningsbara transaktioner i minnet (förvalt: %u)</translation>
+ </message>
<message>
<source>Need to specify a port with -whitebind: '%s'</source>
<translation>Port måste anges med -whitelist: '%s'</translation>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Skicka trace-/debuginformation till terminalen istället för till debug.log</translation>
</message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Sänd transaktioner som nollavgiftstransaktioner om möjligt (förvalt: %u)</translation>
+ </message>
<message>
<source>Show all debugging options (usage: --help -help-debug)</source>
<translation>Visa alla avlusningsoptioner (använd: --help -help-debug)</translation>
<source>Error loading wallet.dat: Wallet corrupted</source>
<translation>Fel vid inläsningen av wallet.dat: Plånboken är skadad</translation>
</message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 = spara tx metadata t.ex. kontoägare och betalningsbegäransinformation, 2 = släng tx metadata)</translation>
+ </message>
+ <message>
+ <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source>
+ <translation>Töm databasens minnespool till disk varje <n> megabytes (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>Hur grundlig blockverifikationen vid -checkblocks är (0-4, förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source>
+ <translation>Om paytxfee inte är satt, inkludera tillräcklig avgift så att transaktionen konfirmeras inom n blocks (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
+ <translation>Logga transaktionsprioritet och avgift per kB vid blockbrytning (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>Upprätthåll ett fullständigt transaktionsindex, som används av getrawtransaction rpc-anrop (förval: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>Antal sekunder att hindra klienter som missköter sig från att ansluta (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying <category> is optional)</source>
+ <translation>Skriv ut avlusningsinformation (förvalt: %u, att ange <category> är frivilligt)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>Använd separat SOCKS5 proxy för att nå kollegor via dolda tjänster i Tor (förvalt: -%s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>Accepterbara chiffer (förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>Sök alltid efter klientadresser med DNS sökningen (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Disable safemode, override a real safe mode event (default: %u)</source>
+ <translation>Avaktivera säkert läge. Åsidosätt en riktigt säkert läge händelse (förvalt: %u)</translation>
+ </message>
<message>
<source>Error loading wallet.dat</source>
<translation>Fel vid inläsning av plånboksfilen wallet.dat</translation>
</message>
+ <message>
+ <source>Force safe mode (default: %u)</source>
+ <translation>Tvångskör i säkert läge (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>Generera mynt (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>Hur många block att kontrollera vid uppstart (förvalt: %u, 0 = alla)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>Inkludera IP-adresser i debugutskrift (förvalt: %u)</translation>
+ </message>
<message>
<source>Invalid -proxy address: '%s'</source>
<translation>Ogiltig -proxy adress: '%s'</translation>
</message>
+ <message>
+ <source>Limit size of signature cache to <n> entries (default: %u)</source>
+ <translation>Begränsa signaturcachestorleken till <n> poster (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source>
+ <translation>Lyssna på JSON-RPC-anslutningar på <port> (förval: %u eller testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on <port> (default: %u or testnet: %u)</source>
+ <translation>Lyssna efter anslutningar på <port> (förvalt: %u eller testnet: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most <n> connections to peers (default: %u)</source>
+ <translation>Ha som mest <n> anslutningar till andra klienter (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source>
+ <translation>Maximal mottagningsbuffert per anslutning, <n>*1000 byte (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source>
+ <translation>Maximal sändningsbuffert per anslutning, <n>*1000 byte (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
+ <translation>Acceptera bara blockkedjans matchande inbyggda kontrollpunkter (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>Skriv ut tidsstämpel i avlusningsinformationen (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Print block tree on startup (default: %u)</source>
+ <translation>Skriv ut blockträdet vid uppstart (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>Reläa och bearbeta databärartransaktioner (förvalt: %u) </translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>Reläa icke P2SH multisig (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Run a thread to flush wallet periodically (default: %u)</source>
+ <translation>Kör en tråd för att tömma plånboken periodiskt (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>Serverns certifikatfil (förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>Serverns privata nyckel (förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to <n> (default: %u)</source>
+ <translation>Sätt storleken på nyckelpoolen till <n> (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>Sätt minsta blockstorlek i byte (standard: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>Ange antalet trådar för att hantera RPC anrop (förvalt: %d)</translation>
+ </message>
+ <message>
+ <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
+ <translation>Sätt DB_PRIVATE flaggan i plånbokens databasmiljö (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>Ange konfigurationsfil (förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>Ange timeout för uppkoppling i millisekunder (minimum:1, förvalt: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>Ange pid-fil (förvalt: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>Spendera okonfirmerad växel när transaktioner sänds (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Stop running after importing blocks from disk (default: %u)</source>
+ <translation>Sluta köra efter importen av block från disk är klar (förvalt: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>Tröskelvärde för att koppla ifrån klienter som missköter sig (förvalt: %u)</translation>
+ </message>
<message>
<source>Unknown network specified in -onlynet: '%s'</source>
<translation>Okänt nätverk som anges i -onlynet: '%s'</translation>
-<TS language="th_TH" version="2.1">
+<TS language="th_TH" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Address</source>
- <translation>ที่อยู่</translation>
- </message>
<message>
<source>(no label)</source>
<translation>(ไม่มีชื่อ)</translation>
-<TS language="tr" version="2.1">
+<TS language="tr" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<context>
<name>CoinControlDialog</name>
<message>
- <source>Coin Control Address Selection</source>
- <translation>Para kontrolü adres seçimi</translation>
+ <source>Coin Selection</source>
+ <translation>Bitcoin Seçimi</translation>
</message>
<message>
<source>Quantity:</source>
<translation>Meblağ</translation>
</message>
<message>
- <source>Address</source>
- <translation>Adres</translation>
+ <source>Received with label</source>
+ <translation>Şu etiketle alındı</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Şu adresle alındı</translation>
</message>
<message>
<source>Date</source>
<source>&Main</source>
<translation>&Esas ayarlar</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Muamelelerin hızlı işlenmesini garantilemeye yardım eden, seçime dayalı kB başı muamele ücreti. Muamelelerin çoğunluğunun boyutu 1 kB'dir.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Muamele ücreti &öde</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Sistemde oturum açıldığında Bitcoin'i otomatik olarak başlat.</translation>
<source>Allow incoming connections</source>
<translation>Gelen bağlantılara izin ver</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Bitcoin şebekesine bir SOCKS vekil sunucusu vasıtasıyla bağlan.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>SOCKS vekil sunucusuyla &bağlan (varsayılan vekil):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Vekil sunucusunun IP adresi (mesela IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Map port using &UPnP</source>
<translation>Portları &UPnP kullanarak haritala</translation>
</message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Bitcoin şebekesine SOCKS5 vekil sunucusu vasıtasıyla bağlan.</translation>
+ </message>
+ <message>
+ <source>&Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>SOCKS5 vekil sunucusu vasıtasıyla &bağlan (varsayılan vekil sunucusu):</translation>
+ </message>
<message>
<source>Proxy &IP:</source>
<translation>Vekil &İP:</translation>
<source>Custom change address</source>
<translation>Özel para üstü adresi</translation>
</message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Muamele ücreti:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Seç...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>ücret-ayarlarını-küçült</translation>
+ </message>
+ <message>
+ <source>Minimize</source>
+ <translation>Küçült</translation>
+ </message>
+ <message>
+ <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>Eğer özel ücret 1000 satoşi olarak ayarlandıysa ve muamele sadece 250 baytsa, "kilobayt başı" ücret olarak sadece 250 satoşi öder ve "asgari" 1000 satoşi öder. Bir kilobayttan yüksek muameleler için ikisi de kilobayt başı ödeme yapar.</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>kilobayt başı</translation>
+ </message>
+ <message>
+ <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>Eğer özel ücret 1000 satoşi olarak ayarlandıysa ve muamele sadece 250 baytsa, "kilobayt başı" ücret olarak sadece 250 satoşi öder ve "toplam asgari" 1000 satoşi öder. Bir kilobayttan yüksek muameleler için ikisi de kilobayt başı ödeme yapar.</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>toplam asgari</translation>
+ </message>
+ <message>
+ <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>Asgari ücreti ödemek, bloklarda boşluktan daha az muamele hacmi olduğu sürece bir sorun çıkarmaz. Fakat şebekenin işleyecebileceğinden daha çok bitcoin muameleleri talebi olduğunda bunun asla teyit edilmeyen bir muamele olabileceğinin farkında olmalısınız.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(bilgi balonunu oku)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Tavsiye edilen:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Özel:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Zeki ücret henüz başlatılmadı. Bu genelde birkaç blok alır...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Teyit süresi:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>normal</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>çabuk</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Mümkünse ücretsiz muamele olarak gönder</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(teyit daha uzun süre alabilir)</translation>
+ </message>
<message>
<source>Send to multiple recipients at once</source>
<translation>Birçok alıcıya aynı anda gönder</translation>
<source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
<translation>Muamele reddedildi! Cüzdanınızdaki madenî paraların bazıları zaten harcanmış olduğunda bu meydana gelebilir. Örneğin wallet.dat dosyasının bir kopyasını kullandıysanız ve kopyada para harcandığında ancak burada harcandığı işaretlenmediğinde.</translation>
</message>
+ <message>
+ <source>A fee higher than %1 is considered an insanely high fee.</source>
+ <translation>%1 tutarından yüksek ücret delicesine aşırı yüksek bir ücret olarak kabul edilir.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Sadece asgari ücret olan %1 tutarını öde</translation>
+ </message>
+ <message>
+ <source>Estimated to begin confirmation within %1 block(s).</source>
+ <translation>Tahmini olarak %1 blok içinde teyide başlanacaktır.</translation>
+ </message>
<message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Uyarı: geçersiz Bitcoin adresi</translation>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Tüm cüzdan muamelelerini sil ve başlangıçta -rescan ile sadece blok zincirinin parçası olanları geri getir</translation>
</message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
+ <translation>MIT yazılım lisansı kapsamında yayınlanmıştır, ekteki COPYING dosyasına ya da <http://www.opensource.org/licenses/mit-license.php> adresine bakınız.</translation>
+ </message>
<message>
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
<translation>Blokların anında çözülebileceği özel bir zincir kullanan regresyon deneme kipine gir.</translation>
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
<translation>Yeni dosyaları umask 077 yerine varsayılan izinlerle oluştur (sadece devre dışı cüzdan işlevselliği ile etkilidir)</translation>
</message>
- <message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>MIT/X11 yazılım lisansı kapsamında yayınlanmıştır, ekteki COPYING dosyasına ya da <http://www.opensource.org/licenses/mit-license.php> adresine bakınız.</translation>
- </message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Hata: İçeri gelen bağlantıların dinlenmesi başarısız oldu (dinleme %s hatasını verdi)</translation>
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
<translation>Kb başına BTC olarak bundan düşük ücretler muamele oluşturulması için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s)</translation>
</message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Aktardığımız ve oluşturduğumuz veri taşıyıcı muamelelerindeki azami veri boyutu (varsayılan: %u)</translation>
+ </message>
<message>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation>Adres sayısı azaldıysa DNS sorgulamasıyla eş adresleri ara (varsayılan: 1 -connect kullanılmadıysa)</translation>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Yüksek öncelikli/düşük ücretli muamelelerin azami boyutunu bayt olarak ayarla (varsayılan: %d)</translation>
</message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Etkinse bitcoin oluşuturulmasına atanan iş parçacığı sayısını ayarla (-1 = tüm çekirdekler, varsayılan: %d)</translation>
+ </message>
<message>
<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>Bu ürün OpenSSL projesi tarafından OpenSSL araç takımı (http://www.openssl.org/) için geliştirilen yazılımlar, Eric Young (
[email protected]) tarafından hazırlanmış şifreleme yazılımları ve Thomas Bernard tarafından programlanmış UPnP yazılımı içerir.</translation>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Trace/hata ayıklama verilerini debug.log dosyası yerine konsola gönder</translation>
</message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Muameleleri mümkünse ücretsiz olarak gönder (varsayılan: %u)</translation>
+ </message>
<message>
<source>Show all debugging options (usage: --help -help-debug)</source>
<translation>Tüm hata ayıklama seçeneklerini göster (kullanımı: --help -help-debug)</translation>
<source>Output debugging information (default: %u, supplying <category> is optional)</source>
<translation>Hata ayıklama bilgisi dök (varsayılan: %u, <kategori> sağlanması seçime dayalıdır)</translation>
</message>
- <message>
- <source>Set the processor limit for when generation is on (-1 = unlimited, default: %d)</source>
- <translation>Oluşturma etkinken işlemci sınırını belirle (-1 = sınırsız, varsayılan: %d)</translation>
- </message>
<message>
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
<translation>Eşlere gizli Tor servisleri ile ulaşmak için ayrı SOCKS5 vekil sunucusu kullan (varsayılan: %s)</translation>
-<TS language="uk" version="2.1">
+<TS language="uk" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</message>
<message>
<source>Comma separated file (*.csv)</source>
- <translation>Файли, розділені комою (*.csv)</translation>
+ <translation>Ð\97наÑ\87еннÑ\8f, розділені комою (*.csv)</translation>
</message>
<message>
<source>Exporting Failed</source>
<context>
<name>CoinControlDialog</name>
<message>
- <source>Coin Control Address Selection</source>
- <translation>Ð\92ибÑ\96Ñ\80 адÑ\80еÑ\81 длÑ\8f кеÑ\80Ñ\83ваннÑ\8f монеÑ\82ами</translation>
+ <source>Coin Selection</source>
+ <translation>Ð\92ибÑ\96Ñ\80 Ð\9cонеÑ\82</translation>
</message>
<message>
<source>Quantity:</source>
<translation>Кількість</translation>
</message>
<message>
- <source>Address</source>
- <translation>Адреса</translation>
+ <source>Received with label</source>
+ <translation>Отримано з позначкою</translation>
+ </message>
+ <message>
+ <source>Received with address</source>
+ <translation>Отримано з адресою</translation>
</message>
<message>
<source>Date</source>
<source>&Main</source>
<translation>&Головні</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Необов'язкова комісия за Кб допомагає переконатися, що ваші транзакції обробляються швидше. Більшість транзакцій є 1 Кб.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Заплатити комісі&ю</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Автоматично запускати гаманець при вході до системи.</translation>
<source>Allow incoming connections</source>
<translation>Дозволити вхідні з’єднання</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Підключатись до мережі Bitcoin через SOCKS-проксі.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>&Підключатись через SOCKS-проксі (типовий проксі):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>IP-адреса проксі-сервера (наприклад IPv4: 127.0.0.1 / IPv6: ::1)</translation>
<source>Map port using &UPnP</source>
<translation>Відображення порту через &UPnP</translation>
</message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>Підключення до мережі Bitcoin через SOCKS5 проксі.</translation>
+ </message>
+ <message>
+ <source>&Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>&Підключення через SOCKS5 проксі (проксі за замовчуванням):</translation>
+ </message>
<message>
<source>Proxy &IP:</source>
<translation>&IP проксі:</translation>
</message>
<message>
<source>URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source>
- <translation>Ð\9dеможливо обÑ\80обиÑ\82и URI! Це може бÑ\83Ñ\82и викликано непÑ\80авилÑ\8cноÑ\8e Bitcoin-адÑ\80еÑ\81оÑ\8e, Ñ\87и невÑ\96Ñ\80ними паÑ\80амеÑ\82Ñ\80ами URI.</translation>
+ <translation>Ð\9dеможливо обÑ\80обиÑ\82и URI! Ð\9fÑ\80иÑ\87иноÑ\8e Ñ\86Ñ\8cого може бÑ\83Ñ\82и некоÑ\80екÑ\82на Bitcoin-адÑ\80еÑ\81а або непÑ\80авилÑ\8cнÑ\96 паÑ\80амеÑ\82Ñ\80и URI.</translation>
</message>
<message>
<source>Payment request file handling</source>
<source>Custom change address</source>
<translation>Вказати адресу для решти</translation>
</message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>Комісія за передачу:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>Виберіть...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>згорнути налаштування оплат</translation>
+ </message>
+ <message>
+ <source>Minimize</source>
+ <translation>Мінімізувати</translation>
+ </message>
+ <message>
+ <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>Якщо оплата користувача встановлюється в 1000 Satoshi і розмір передачі всього 250 байт, то "за кілобайт" платить тільки 250 Satoshi, в той час як "щонайменше" платить 1000 satoshis. Для передач більших, ніж кілобайт обоє платять за кілобайт.</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>за кілобайт</translation>
+ </message>
+ <message>
+ <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>Якщо оплата користувача встановлюється в 1000 Satoshi і розмір передачі всього 250 байт, то "за кілобайт" платить тільки 250 Satoshi, в той час як "всього щонайменше" платить 1000 satoshis. Для передач більших, ніж кілобайт обоє платять за кілобайт.</translation>
+ </message>
+ <message>
+ <source>total at least</source>
+ <translation>всього щонайменше</translation>
+ </message>
+ <message>
+ <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>Оплата тільки мінімальних зборів є прийнятною до тих пір, як обсяг транзакцій там є меншим аніж простору в блоках. Але майте на увазі, що це може анулювати транзакцію, якщо попит на Bitcoin транзакції стане значно більшим, ніж мережа зможе обробити.</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(читати підказки)</translation>
+ </message>
+ <message>
+ <source>Recommended:</source>
+ <translation>Рекомендовано:</translation>
+ </message>
+ <message>
+ <source>Custom:</source>
+ <translation>Змінено:</translation>
+ </message>
+ <message>
+ <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source>
+ <translation>(Розумна оплата ще не ініціалізована. Це звичайно займає кілька блоків...)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>Час підтвердження:</translation>
+ </message>
+ <message>
+ <source>normal</source>
+ <translation>звичайний</translation>
+ </message>
+ <message>
+ <source>fast</source>
+ <translation>швидкий</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>Надіслати як нульовий плата за передачу, якщо це можливо</translation>
+ </message>
+ <message>
+ <source>(confirmation may take longer)</source>
+ <translation>(підтвердження може зайняти більше часу)</translation>
+ </message>
<message>
<source>Send to multiple recipients at once</source>
<translation>Відправити на декілька адрес</translation>
<source>The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source>
<translation>Транзакцію відхилено! Це може статись, якщо декілька монет з вашого гаманця вже використані, наприклад, якщо ви використовуєте одну копію гаманця (wallet.dat), а монети були використані з іншої копії, але не позначені як використані в цій.</translation>
</message>
+ <message>
+ <source>A fee higher than %1 is considered an insanely high fee.</source>
+ <translation>Плата вища, ніж %1 вважається шалено високою.</translation>
+ </message>
+ <message>
+ <source>Pay only the minimum fee of %1</source>
+ <translation>Платити тільки мінімальний збір у розмірі %1</translation>
+ </message>
+ <message>
+ <source>Estimated to begin confirmation within %1 block(s).</source>
+ <translation>Розрахунковий початок підтвердження протягом %1 блоку(ів).</translation>
+ </message>
<message>
<source>Warning: Invalid Bitcoin address</source>
<translation>Увага: Неправильна Bitcoin-адреса</translation>
</message>
<message>
<source>Comma separated file (*.csv)</source>
- <translation>Файли, розділені комою (*.csv)</translation>
+ <translation>Ð\97наÑ\87еннÑ\8f, розділені комою (*.csv)</translation>
</message>
<message>
<source>Confirmed</source>
Ім’я користувача та пароль ПОВИННІ бути різними.
Якщо файлу не існує, створіть його, обмеживши доступ правом читання для власника.
Також рекомендується використовувати alertnotify для того, щоб отримувати сповіщення про проблеми;
</translation>
</message>
<message>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>Видалити всі транзакції гаманця та відновити ті, що будуть знайдені під час запуску за допомогою -rescan</translation>
</message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
+ <translation>Поширюється за ліцензією MIT, додаткова інформація міститься у файлі COPYING та за адресою <http://www.opensource.org/licenses/mit-license.php>.</translation>
+ </message>
<message>
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
<translation>Ввійти в режим регресивного тестування, що використовує спеціальний ланцюг з миттєвим знаходженням блоків.</translation>
<source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
<translation>Створювати нові файли з типовими для системи атрибутами доступу замість маски 077 (діє тільки при вимкненому гаманці)</translation>
</message>
- <message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>Поширюється за ліцензією MIT/X11, додаткова інформація міститься у файлі COPYING, а також за адресою <http://www.opensource.org/licenses/mit-license.php>.</translation>
- </message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<translation>Помилка: Не вдалося налаштувати прослуховування вхідних підключень (listen повернув помилку: %s)</translation>
</message>
<message>
<source>Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)</source>
- <translation>Виконати команду при надходженні важливого попереджувального повідомлення або при спостереженні тривалого розгалуження ланцюжка (замість %s буде підставлено повідомлення)</translation>
+ <translation>Виконати команду при надходженні важливого сповіщення або при спостереженні тривалого розгалуження ланцюжка (замість %s буде підставлено повідомлення)</translation>
</message>
<message>
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)</source>
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
<translation>Комісії (в BTC/КБ), що менші за вказану, вважатимуться нульовими (для створення транзакції) (типово: %s)</translation>
</message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>Максимальний розмір даних в транзакціях носіїв даних, що ми передаємо і добуваємо (за замовчуванням: %u)</translation>
+ </message>
<message>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation>Дізнаватися адреси учасників через DNS при замалій кількості відомих адрес (типово: 1 за відсутності -connect)</translation>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>Встановити максимальний розмір транзакцій з високим пріоритетом та низькою комісією (в байтах) (типово: %d)</translation>
</message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>Встановити кількість потоків для генерації монет (-1 = кількості ядер, типово: %d)</translation>
+ </message>
<message>
<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>Цей продукт включає в себе програмне забезпечення, розроблене в рамках проекту OpenSSL <https://www.openssl.org/>, криптографічне програмне забезпечення, написане Еріком Янгом, та функції для роботи з UPnP, написані Томасом Бернардом.</translation>
</message>
<message>
<source>Invalid amount for -minrelaytxfee=<amount>: '%s'</source>
- <translation>Вказано некоректну суму для параметру -minrelaytxfee: '%s'</translation>
+ <translation>Вказано некоректну суму для параметру -minrelaytxfee: «%s»</translation>
</message>
<message>
<source>Invalid amount for -mintxfee=<amount>: '%s'</source>
- <translation>Вказано некоректну суму для параметру -mintxfee: '%s'</translation>
+ <translation>Вказано некоректну суму для параметру -mintxfee: «%s»</translation>
</message>
<message>
<source>Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source>
- <translation>Вказано некоректну суму для параметру -paytxfee: '%s' (повинно бути щонайменше %s)</translation>
+ <translation>Вказано некоректну суму для параметру -paytxfee: «%s» (повинно бути щонайменше %s)</translation>
</message>
<message>
<source>Invalid netmask specified in -whitelist: '%s'</source>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>Відсилати налагоджувальну інформацію на консоль, а не у файл debug.log</translation>
</message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>Встановити операцію надсилання, як неоплатну операцію, якщо це можливо (за замовчуванням: %u)</translation>
+ </message>
<message>
<source>Show all debugging options (usage: --help -help-debug)</source>
<translation>Показати всі налагоджувальні параметри (використання: --help -help-debug)</translation>
<source>Output debugging information (default: %u, supplying <category> is optional)</source>
<translation>Виводити налагоджувальну інформацію (типово: %u, вказання <category> необов'язкове)</translation>
</message>
- <message>
- <source>Set the processor limit for when generation is on (-1 = unlimited, default: %d)</source>
- <translation>Встановити максимальну кількість процесорів, що будуть використовуватися при ввімкненій генерації (-1 = необмежено, типово: %d)</translation>
- </message>
<message>
<source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
<translation>Використовувати окремий SOCKS5-проксі для з'єднання з учасниками через приховані сервіси Tor (типово: %s)</translation>
-<TS language="ur_PK" version="2.1">
+<TS language="ur_PK" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>رقم</translation>
</message>
- <message>
- <source>Address</source>
- <translation> پتہ</translation>
- </message>
<message>
<source>Date</source>
<translation>تاریخ</translation>
-<TS language="uz@Cyrl" version="2.1">
+<TS language="uz@Cyrl" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>Танга бошқарув манзилини танлаш</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>Сони:</translation>
<source>Amount</source>
<translation>Миқдори</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Манзил</translation>
- </message>
<message>
<source>Date</source>
<translation>Сана</translation>
<source>&Main</source>
<translation>&Асосий</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>Ҳар бир кб учун ўтказма солиғи ўтказмаларингизни тезроқ ўтишига ишонишингизга ёрдам беради. Кўпгина ўтказмалар 1 кб.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>Ўтказма &солиғини тўлаш</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>Тизимга киргандан сўнг Bitcoin дастури автоматик ишга туширилсин.</translation>
<source>Allow incoming connections</source>
<translation>Кирувчи уланишларга рухсат бериш</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>Bitcoin тармоққа SOCKS прокси орқали уланинг.</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>SOCKS прокси орқали &уланинг (стандарт прокси):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>Прокси IP манзили (масалан: IPv4: 127.0.0.1 / IPv6: ::1)</translation>
-<TS language="vi" version="2.1">
+<TS language="vi" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
<source>Amount</source>
<translation>Số lượng</translation>
</message>
- <message>
- <source>Address</source>
- <translation>Địa chỉ</translation>
- </message>
<message>
<source>(no label)</source>
<translation>(chưa có nhãn)</translation>
-<TS language="vi_VN" version="2.1">
+<TS language="vi_VN" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
-<TS language="zh_CN" version="2.1">
+<TS language="zh_CN" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</context>
<context>
<name>CoinControlDialog</name>
- <message>
- <source>Coin Control Address Selection</source>
- <translation>选择交易源地址</translation>
- </message>
<message>
<source>Quantity:</source>
<translation>总量:</translation>
<source>Amount</source>
<translation>金额</translation>
</message>
- <message>
- <source>Address</source>
- <translation>地址</translation>
- </message>
<message>
<source>Date</source>
<translation>日期</translation>
<source>&Main</source>
<translation>主要(&M)</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>可选的每 kB 交易费,这有助于您的交易被更快的处理。大多数交易都是 1 kB。</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>支付交易费用(&F)</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>登录系统后自动开启比特币客户端</translation>
<source>Allow incoming connections</source>
<translation>允许流入连接</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>通过 SOCKS 代理连接到比特币网络。</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>通过 SO&CKS 代理连接 (默认代理):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>代理的 IP 地址 (例如 IPv4: 127.0.0.1 / IPv6: ::1)</translation>
-<TS language="zh_HK" version="2.1">
+<TS language="zh_HK" version="2.0">
<context>
<name>AddressBookPage</name>
</context>
-<TS language="zh_TW" version="2.1">
+<TS language="zh_TW" version="2.0">
<context>
<name>AddressBookPage</name>
<message>
</message>
<message>
<source>Create a new address</source>
- <translation>製造新的位址</translation>
+ <translation>新增新的位址</translation>
</message>
<message>
<source>&New</source>
<source>Up to date</source>
<translation>最新狀態</translation>
</message>
+ <message numerus="yes">
+ <source>Processed %n blocks of transaction history.</source>
+ <translation><numerusform>已經處理了 %n 個區塊的交易紀錄。</numerusform></translation>
+ </message>
<message>
<source>Catching up...</source>
<translation>正在趕進度...</translation>
<context>
<name>CoinControlDialog</name>
<message>
- <source>Coin Control Address Selection</source>
- <translation>é\8c¢å¹£æ\8e§å\88¶ç\9a\84ä½\8då\9d\80é\81¸æ\93\87</translation>
+ <source>Coin Selection</source>
+ <translation>é\81¸æ\93\87é\8c¢å¹£</translation>
</message>
<message>
<source>Quantity:</source>
<source>Amount</source>
<translation>金額</translation>
</message>
- <message>
- <source>Address</source>
- <translation>位址</translation>
- </message>
<message>
<source>Date</source>
<translation>日期</translation>
<source>Error</source>
<translation>錯誤</translation>
</message>
- </context>
+ <message numerus="yes">
+ <source>%n GB of free space available</source>
+ <translation><numerusform>可用空間尚存 %n GB</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <source>(of %n GB needed)</source>
+ <translation><numerusform>(需要 %n GB)</numerusform></translation>
+ </message>
+</context>
<context>
<name>OpenURIDialog</name>
<message>
<source>&Main</source>
<translation>主要</translation>
</message>
- <message>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source>
- <translation>每一千位元組(kB)要付的交易手續費,如果有付可以加速網路處理你的交易。大部份交易資料的大小是 1 kB.</translation>
- </message>
- <message>
- <source>Pay transaction &fee</source>
- <translation>付交易手續費</translation>
- </message>
<message>
<source>Automatically start Bitcoin after logging in to the system.</source>
<translation>在登入系統後自動啓動位元幣軟體。</translation>
<source>Allow incoming connections</source>
<translation>接受外來連線</translation>
</message>
- <message>
- <source>Connect to the Bitcoin network through a SOCKS proxy.</source>
- <translation>透過 SOCKS 代理伺服器來連線到位元幣網路。</translation>
- </message>
- <message>
- <source>&Connect through SOCKS proxy (default proxy):</source>
- <translation>透過 SOCKS 代理伺服器連線(預設代理伺服器):</translation>
- </message>
<message>
<source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source>
<translation>代理伺服器的網際網路位址(像是 IPv4 的 127.0.0.1 或 IPv6 的 ::1)</translation>
<source>Map port using &UPnP</source>
<translation>用 &UPnP 設定通訊埠對應</translation>
</message>
+ <message>
+ <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source>
+ <translation>透過 SOCKS5 代理伺服器來連線到位元幣網路。</translation>
+ </message>
+ <message>
+ <source>&Connect through SOCKS5 proxy (default proxy):</source>
+ <translation>透過 SOCKS5 代理伺服器連線(預設代理伺服器):</translation>
+ </message>
<message>
<source>Proxy &IP:</source>
<translation>代理位址:</translation>
<source>Custom change address</source>
<translation>自定找零位址</translation>
</message>
+ <message>
+ <source>Transaction Fee:</source>
+ <translation>交易手續費:</translation>
+ </message>
+ <message>
+ <source>Choose...</source>
+ <translation>選擇...</translation>
+ </message>
+ <message>
+ <source>collapse fee-settings</source>
+ <translation>展開手續費設定</translation>
+ </message>
+ <message>
+ <source>Minimize</source>
+ <translation>最小化</translation>
+ </message>
+ <message>
+ <source>per kilobyte</source>
+ <translation>每千位元組</translation>
+ </message>
+ <message>
+ <source>(read the tooltip)</source>
+ <translation>(請看提示)</translation>
+ </message>
+ <message>
+ <source>Confirmation time:</source>
+ <translation>確認時間:</translation>
+ </message>
+ <message>
+ <source>Send as zero-fee transaction if possible</source>
+ <translation>盡可能送不用付手續費的交易</translation>
+ </message>
<message>
<source>Send to multiple recipients at once</source>
<translation>一次付給多個收款人</translation>
<source>Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup</source>
<translation>清掉錢包裡的所有交易,並且在下次啟動時,使用 -rescan 來從區塊鏈中復原回來。</translation>
</message>
+ <message>
+ <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
+ <translation>這套軟體是依據 MIT 軟體授權條款散布,詳情請見附帶的 COPYING 檔案,或是以下網站: <http://www.opensource.org/licenses/mit-license.php>.</translation>
+ </message>
<message>
<source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source>
<translation>進入回歸測試模式,使用可以立即解出區塊的特殊區塊鏈。</translation>
<source>Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup.</source>
<translation>警告: 錢包檔 wallet.dat 壞掉,但資料被拯救回來了!原來的 wallet.dat 會改儲存在 %s, 檔名是 wallet.{timestamp}.bak. 如果餘額或交易資料有誤,你應該要用備份資料復原回來。</translation>
</message>
+ <message>
+ <source>Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.</source>
+ <translation>把來自指定網域或位址的節點放進白名單。這個選項可以設定多次。</translation>
+ </message>
<message>
<source>(default: 1)</source>
<translation>(預設值: 1)</translation>
</message>
<message>
<source>Do not load the wallet and disable wallet RPC calls</source>
- <translation>不要載入錢包,並且拿掉錢包相關的 RPC 功能呼叫。</translation>
+ <translation>不要載入錢包,並且拿掉錢包相關的 RPC 功能請求。</translation>
</message>
<message>
<source>Do you want to rebuild the block database now?</source>
<translation>沒辦法鎖定資料目錄 %s。位元幣核心可能已經在執行了。</translation>
</message>
<message>
- <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
- <translation>用系統預設權限來造出新的檔案,而不是用使用者權限罩遮(umask)值 077 (只有在關掉錢包功能時才有作用)。</translation>
+ <source>Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)</source>
+ <translation>對沒付手續費的交易持續限制每分鐘內最多只能有 <n>*1000 個位元組(預設值: %u)</translation>
</message>
<message>
- <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source>
- <translation>這套軟體是依據 MIT/X11 軟體授權條款散布,詳情請見附帶的 COPYING 檔案,或是以下網站: <http://www.opensource.org/licenses/mit-license.php>.</translation>
+ <source>Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)</source>
+ <translation>用系統預設權限來造出新的檔案,而不是用使用者權限罩遮(umask)值 077 (只有在關掉錢包功能時才有作用)。</translation>
</message>
<message>
<source>Error: Listening for incoming connections failed (listen returned error %s)</source>
<source>Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)</source>
<translation>當製造交易時,如果每千位元組(Kb)的手續費比這個值低,就視為沒付手續費 (預設值: %s)</translation>
</message>
+ <message>
+ <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source>
+ <translation>轉發和開採時,對只帶資料的交易的大小上限(預設值: %u)</translation>
+ </message>
<message>
<source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source>
<translation>是否允許在節點位址數目不足時,使用域名查詢來搜尋節點 (預設值: 當沒用 -connect 時為 1)</translation>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: %d)</source>
<translation>設定高優先度或低手續費的交易資料大小上限成多少位元組(預設值: %d)</translation>
</message>
+ <message>
+ <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source>
+ <translation>設定產生錢幣的執行緒數目(-1 表示處理器核心數,預設值: %d)</translation>
+ </message>
<message>
<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>此產品也包含了由 OpenSSL Project 所開發的 OpenSSL Toolkit 軟體 <https://www.openssl.org/>, 和由 Eric Young 撰寫的加解密軟體,以及由 Thomas Bernard 所撰寫的 UPnP 軟體。</translation>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation>在終端機顯示追蹤或除錯資訊,而不是寫到檔案 debug.log 中</translation>
</message>
+ <message>
+ <source>Send transactions as zero-fee transactions if possible (default: %u)</source>
+ <translation>盡可能送出不用付手續費的交易(預設值: %u)</translation>
+ </message>
<message>
<source>Show all debugging options (usage: --help -help-debug)</source>
<translation>顯示所有的除錯選項 (用法: --help --help-debug)</translation>
<source>Error loading wallet.dat: Wallet corrupted</source>
<translation>載入檔案 wallet.dat 時發生錯誤: 錢包損毀了</translation>
</message>
+ <message>
+ <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
+ <translation>(1 表示保留交易描述資料,像是帳戶使用者和付款請求資訊;2 表示丟掉交易描述資料)</translation>
+ </message>
+ <message>
+ <source>Flush database activity from memory pool to disk log every <n> megabytes (default: %u)</source>
+ <translation>每當累積到 <n> 百萬位元組(MB)時,才將資料庫的變動從記憶體暫存池中寫進磁碟紀錄檔(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>How thorough the block verification of -checkblocks is (0-4, default: %u)</source>
+ <translation>使用 -checkblocks 檢查區塊的仔細程度(0 到 4,預設值: %u)</translation>
+ </message>
+ <message>
+ <source>If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)</source>
+ <translation>當沒有設定 paytxfee 時,自動包含可以讓交易能在平均 n 個區塊內確認的手續費(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Log transaction priority and fee per kB when mining blocks (default: %u)</source>
+ <translation>開採區塊的時候,紀錄交易的優先度以及每千位元組(kB)的手續費(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)</source>
+ <translation>維護全部交易的索引,用在 getrawtransaction 這個 RPC 請求(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source>
+ <translation>避免與亂搞的節點連線的秒數(預設: %u)</translation>
+ </message>
+ <message>
+ <source>Output debugging information (default: %u, supplying <category> is optional)</source>
+ <translation>輸出除錯資訊(預設值: %u, 不一定要指定 <category>)</translation>
+ </message>
+ <message>
+ <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source>
+ <translation>使用另外的 SOCK5 代理伺服器,來透過 Tor 隱藏服務跟節點聯繫(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>(default: %s)</source>
+ <translation>(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Acceptable ciphers (default: %s)</source>
+ <translation>可以接受的加密演算法(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Always query for peer addresses via DNS lookup (default: %u)</source>
+ <translation>是否一定要用域名查詢來搜尋節點(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Disable safemode, override a real safe mode event (default: %u)</source>
+ <translation>不進入安全模式,用在真的發生需要進入安全模式的事件時,強制不進入(預設值: %u)</translation>
+ </message>
<message>
<source>Error loading wallet.dat</source>
<translation>載入錢包檔 wallet.dat 時發生錯誤</translation>
</message>
+ <message>
+ <source>Force safe mode (default: %u)</source>
+ <translation>強制進入安全模式(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Generate coins (default: %u)</source>
+ <translation>生產位元幣(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>How many blocks to check at startup (default: %u, 0 = all)</source>
+ <translation>啓動時檢查的區塊數(預設值: %u, 指定 0 表示全部)</translation>
+ </message>
+ <message>
+ <source>Include IP addresses in debug output (default: %u)</source>
+ <translation>在除錯輸出內容中包含網際網路位址(預設值: %u)</translation>
+ </message>
<message>
<source>Invalid -proxy address: '%s'</source>
<translation>無效的 -proxy 位址: '%s'</translation>
</message>
+ <message>
+ <source>Limit size of signature cache to <n> entries (default: %u)</source>
+ <translation>限制簽章快取大小為 <n> 筆(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)</source>
+ <translation>在通訊埠 <port> 聽候 JSON-RPC 連線(預設值: %u, 或若為測試網路: %u)</translation>
+ </message>
+ <message>
+ <source>Listen for connections on <port> (default: %u or testnet: %u)</source>
+ <translation>在通訊埠 <port> 聽候連線(預設值: %u, 或若為測試網路: %u)</translation>
+ </message>
+ <message>
+ <source>Maintain at most <n> connections to peers (default: %u)</source>
+ <translation>維持與節點連線數的上限為 <n> 個(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)</source>
+ <translation>每個連線的接收緩衝區大小上限為 <n>*1000 個位元組(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Maximum per-connection send buffer, <n>*1000 bytes (default: %u)</source>
+ <translation>每個連線的傳送緩衝區大小上限為 <n>*1000 個位元組(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Only accept block chain matching built-in checkpoints (default: %u)</source>
+ <translation>只接受與內建的檢查段點吻合的區塊鎖鏈(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Prepend debug output with timestamp (default: %u)</source>
+ <translation>在除錯輸出內容前附加時間(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Print block tree on startup (default: %u)</source>
+ <translation>啟動時輸出區塊樹(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Relay and mine data carrier transactions (default: %u)</source>
+ <translation>允許轉發和開採只帶資料的交易(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Relay non-P2SH multisig (default: %u)</source>
+ <translation>允許轉發非 P2SH 的多簽章交易(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Run a thread to flush wallet periodically (default: %u)</source>
+ <translation>啟用定期將變動寫入錢包檔的執行緒(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Server certificate file (default: %s)</source>
+ <translation>伺服器憑證檔(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Server private key (default: %s)</source>
+ <translation>伺服器密鑰檔(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Set key pool size to <n> (default: %u)</source>
+ <translation>設定密鑰池大小為 <n> (預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Set minimum block size in bytes (default: %u)</source>
+ <translation>設定區塊大小下限為多少位元組(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Set the number of threads to service RPC calls (default: %d)</source>
+ <translation>設定處理 RPC 服務請求的執行緒數目(預設值: %d)</translation>
+ </message>
+ <message>
+ <source>Sets the DB_PRIVATE flag in the wallet db environment (default: %u)</source>
+ <translation>在錢包資料庫環境變數設定 DB_PRIVATE 旗標(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Specify configuration file (default: %s)</source>
+ <translation>指定設定檔(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Specify connection timeout in milliseconds (minimum: 1, default: %d)</source>
+ <translation>指定連線在幾毫秒後逾時 (最少值: 1, 預設值: %d)</translation>
+ </message>
+ <message>
+ <source>Specify pid file (default: %s)</source>
+ <translation>指定行程識別碼檔案(預設值: %s)</translation>
+ </message>
+ <message>
+ <source>Spend unconfirmed change when sending transactions (default: %u)</source>
+ <translation>傳送交易時可以花還沒確認的零錢(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Stop running after importing blocks from disk (default: %u)</source>
+ <translation>從磁碟匯入區塊資料後停止執行(預設值: %u)</translation>
+ </message>
+ <message>
+ <source>Threshold for disconnecting misbehaving peers (default: %u)</source>
+ <translation>與亂搞的節點斷線的臨界值 (預設: %u)</translation>
+ </message>
<message>
<source>Unknown network specified in -onlynet: '%s'</source>
<translation>在 -onlynet 指定了不明的網路別: '%s'</translation>
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_MACDOCKICONHANDLER_H
class QWidget;
QT_END_NAMESPACE
-#ifdef __OBJC__
-@class DockIconClickEventHandler;
-#else
-class DockIconClickEventHandler;
-#endif
-
/** Macintosh-specific dock icon handler.
*/
class MacDockIconHandler : public QObject
void setIcon(const QIcon &icon);
void setMainWindow(QMainWindow *window);
static MacDockIconHandler *instance();
-
+ static void cleanup();
void handleDockIconClickEvent();
signals:
private:
MacDockIconHandler();
- DockIconClickEventHandler *m_dockIconClickEventHandler;
QWidget *m_dummyWidget;
QMenu *m_dockMenu;
QMainWindow *mainWindow;
// Copyright (c) 2011-2013 The Bitcoin Core 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 "macdockiconhandler.h"
#undef slots
#include <Cocoa/Cocoa.h>
+#include <objc/objc.h>
+#include <objc/message.h>
#if QT_VERSION < 0x050000
extern void qt_mac_set_dock_menu(QMenu *);
#endif
-@interface DockIconClickEventHandler : NSObject
-{
- MacDockIconHandler* dockIconHandler;
-}
-
-@end
+static MacDockIconHandler *s_instance = NULL;
-@implementation DockIconClickEventHandler
-
-- (id)initWithDockIconHandler:(MacDockIconHandler *)aDockIconHandler
-{
- self = [super init];
- if (self) {
- dockIconHandler = aDockIconHandler;
-
- [[NSAppleEventManager sharedAppleEventManager]
- setEventHandler:self
- andSelector:@selector(handleDockClickEvent:withReplyEvent:)
- forEventClass:kCoreEventClass
- andEventID:kAEReopenApplication];
- }
- return self;
+bool dockClickHandler(id self,SEL _cmd,...) {
+ Q_UNUSED(self)
+ Q_UNUSED(_cmd)
+
+ s_instance->handleDockIconClickEvent();
+
+ // Return NO (false) to suppress the default OS X actions
+ return false;
}
-- (void)handleDockClickEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
-{
- Q_UNUSED(event)
- Q_UNUSED(replyEvent)
-
- if (dockIconHandler) {
- dockIconHandler->handleDockIconClickEvent();
+void setupDockClickHandler() {
+ Class cls = objc_getClass("NSApplication");
+ id appInst = objc_msgSend((id)cls, sel_registerName("sharedApplication"));
+
+ if (appInst != NULL) {
+ id delegate = objc_msgSend(appInst, sel_registerName("delegate"));
+ Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class"));
+ SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
+ if (class_getInstanceMethod(delClass, shouldHandle))
+ class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:");
+ else
+ class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler,"B@:");
}
}
-@end
MacDockIconHandler::MacDockIconHandler() : QObject()
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- this->m_dockIconClickEventHandler = [[DockIconClickEventHandler alloc] initWithDockIconHandler:this];
+ setupDockClickHandler();
this->m_dummyWidget = new QWidget();
this->m_dockMenu = new QMenu(this->m_dummyWidget);
this->setMainWindow(NULL);
MacDockIconHandler::~MacDockIconHandler()
{
- [this->m_dockIconClickEventHandler release];
delete this->m_dummyWidget;
this->setMainWindow(NULL);
}
MacDockIconHandler *MacDockIconHandler::instance()
{
- static MacDockIconHandler *s_instance = NULL;
if (!s_instance)
s_instance = new MacDockIconHandler();
return s_instance;
}
+void MacDockIconHandler::cleanup()
+{
+ delete s_instance;
+}
+
void MacDockIconHandler::handleDockIconClickEvent()
{
if (this->mainWindow)
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_MACNOTIFICATIONHANDLER_H
// Copyright (c) 2011-2013 The Bitcoin Core 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 "macnotificationhandler.h"
-// Copyright (c) 2014 The Bitcoin developers
+// 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.
#include "networkstyle.h"
#include "guiconstants.h"
+#include "scicon.h"
#include <QApplication>
static const struct {
const char *networkId;
const char *appName;
- const char *appIcon;
+ const int iconColorHueShift;
+ const int iconColorSaturationReduction;
const char *titleAddText;
- const char *splashImage;
} network_styles[] = {
- {"main", QAPP_APP_NAME_DEFAULT, ":/icons/bitcoin", "", ":/images/splash"},
- {"test", QAPP_APP_NAME_TESTNET, ":/icons/bitcoin_testnet", QT_TRANSLATE_NOOP("SplashScreen", "[testnet]"), ":/images/splash_testnet"},
- {"regtest", QAPP_APP_NAME_TESTNET, ":/icons/bitcoin_testnet", "[regtest]", ":/images/splash_testnet"}
+ {"main", QAPP_APP_NAME_DEFAULT, 0, 0, ""},
+ {"test", QAPP_APP_NAME_TESTNET, 70, 30, QT_TRANSLATE_NOOP("SplashScreen", "[testnet]")},
+ {"regtest", QAPP_APP_NAME_TESTNET, 160, 30, "[regtest]"}
};
static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles);
// titleAddText needs to be const char* for tr()
-NetworkStyle::NetworkStyle(const QString &appName, const QString &appIcon, const char *titleAddText, const QString &splashImage):
+NetworkStyle::NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText):
appName(appName),
- appIcon(appIcon),
- titleAddText(qApp->translate("SplashScreen", titleAddText)),
- splashImage(splashImage)
+ titleAddText(qApp->translate("SplashScreen", titleAddText))
{
+ // load pixmap
+ QPixmap pixmap(":/icons/bitcoin");
+
+ if(iconColorHueShift != 0 && iconColorSaturationReduction != 0)
+ {
+ // generate QImage from QPixmap
+ QImage img = pixmap.toImage();
+
+ int h,s,l,a;
+
+ // traverse though lines
+ for(int y=0;y<img.height();y++)
+ {
+ QRgb *scL = reinterpret_cast< QRgb *>( img.scanLine( y ) );
+
+ // loop through pixels
+ for(int x=0;x<img.width();x++)
+ {
+ // preserve alpha because QColor::getHsl doesen't return the alpha value
+ a = qAlpha(scL[x]);
+ QColor col(scL[x]);
+
+ // get hue value
+ col.getHsl(&h,&s,&l);
+
+ // rotate color on RGB color circle
+ // 70° should end up with the typical "testnet" green
+ h+=iconColorHueShift;
+
+ // change saturation value
+ if(s>iconColorSaturationReduction)
+ {
+ s -= iconColorSaturationReduction;
+ }
+ col.setHsl(h,s,l,a);
+
+ // set the pixel
+ scL[x] = col.rgba();
+ }
+ }
+
+ //convert back to QPixmap
+#if QT_VERSION >= 0x040700
+ pixmap.convertFromImage(img);
+#else
+ pixmap = QPixmap::fromImage(img);
+#endif
+ }
+
+ appIcon = QIcon(pixmap);
+ trayAndWindowIcon = QIcon(pixmap.scaled(QSize(256,256)));
}
const NetworkStyle *NetworkStyle::instantiate(const QString &networkId)
{
return new NetworkStyle(
network_styles[x].appName,
- network_styles[x].appIcon,
- network_styles[x].titleAddText,
- network_styles[x].splashImage);
+ network_styles[x].iconColorHueShift,
+ network_styles[x].iconColorSaturationReduction,
+ network_styles[x].titleAddText);
}
}
return 0;
-// Copyright (c) 2014 The Bitcoin developers
+// 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.
const QString &getAppName() const { return appName; }
const QIcon &getAppIcon() const { return appIcon; }
+ const QIcon &getTrayAndWindowIcon() const { return trayAndWindowIcon; }
const QString &getTitleAddText() const { return titleAddText; }
- const QPixmap &getSplashImage() const { return splashImage; }
private:
- NetworkStyle(const QString &appName, const QString &appIcon, const char *titleAddText, const QString &splashImage);
+ NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText);
QString appName;
QIcon appIcon;
+ QIcon trayAndWindowIcon;
QString titleAddText;
- QPixmap splashImage;
};
#endif // BITCOIN_QT_NETWORKSTYLE_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "notificator.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_NOTIFICATOR_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "openuridialog.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_OPENURIDIALOG_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
fProxyIpValid(true)
{
ui->setupUi(this);
- GUIUtil::restoreWindowGeometry("nOptionsDialogWindow", this->size(), this);
/* Main elements init */
ui->databaseCache->setMinimum(nMinDbCache);
OptionsDialog::~OptionsDialog()
{
- GUIUtil::saveWindowGeometry("nOptionsDialogWindow", this);
delete ui;
}
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_OPTIONSDIALOG_H
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-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.
#if defined(HAVE_CONFIG_H)
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_OPTIONSMODEL_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "overviewpage.h"
#include "guiconstants.h"
#include "guiutil.h"
#include "optionsmodel.h"
+#include "scicon.h"
#include "transactionfilterproxy.h"
#include "transactiontablemodel.h"
#include "walletmodel.h"
{
painter->save();
- QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
+ QIcon icon = qvariant_cast<QIcon>(index.data(TransactionTableModel::RawDecorationRole));
QRect mainRect = option.rect;
QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE));
int xspace = DECORATION_SIZE + 8;
int halfheight = (mainRect.height() - 2*ypad)/2;
QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight);
QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight);
+ icon = SingleColorIcon(icon, SingleColor());
icon.paint(painter, decorationRect);
QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime();
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_OVERVIEWPAGE_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
#include "paymentrequestplus.h"
+#include "util.h"
+
#include <stdexcept>
-#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <QDateTime>
{
bool parseOK = paymentRequest.ParseFromArray(data.data(), data.size());
if (!parseOK) {
- qWarning() << "PaymentRequestPlus::parse : Error parsing payment request";
+ qWarning() << "PaymentRequestPlus::parse: Error parsing payment request";
return false;
}
if (paymentRequest.payment_details_version() > 1) {
- qWarning() << "PaymentRequestPlus::parse : Received up-version payment details, version=" << paymentRequest.payment_details_version();
+ qWarning() << "PaymentRequestPlus::parse: Received up-version payment details, version=" << paymentRequest.payment_details_version();
return false;
}
parseOK = details.ParseFromString(paymentRequest.serialized_payment_details());
if (!parseOK)
{
- qWarning() << "PaymentRequestPlus::parse : Error parsing payment details";
+ qWarning() << "PaymentRequestPlus::parse: Error parsing payment details";
paymentRequest.Clear();
return false;
}
digestAlgorithm = EVP_sha1();
}
else if (paymentRequest.pki_type() == "none") {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: pki_type == none";
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: pki_type == none";
return false;
}
else {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type());
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type());
return false;
}
payments::X509Certificates certChain;
if (!certChain.ParseFromString(paymentRequest.pki_data())) {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: error parsing pki_data";
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error parsing pki_data";
return false;
}
QByteArray certData(certChain.certificate(i).data(), certChain.certificate(i).size());
QSslCertificate qCert(certData, QSsl::Der);
if (currentTime < qCert.effectiveDate() || currentTime > qCert.expiryDate()) {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: certificate expired or not yet active: " << qCert;
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: certificate expired or not yet active: " << qCert;
return false;
}
#if QT_VERSION >= 0x050000
if (qCert.isBlacklisted()) {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: certificate blacklisted: " << qCert;
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: certificate blacklisted: " << qCert;
return false;
}
#endif
certs.push_back(cert);
}
if (certs.empty()) {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: empty certificate chain";
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: empty certificate chain";
return false;
}
// load the signing cert into it and verify.
X509_STORE_CTX *store_ctx = X509_STORE_CTX_new();
if (!store_ctx) {
- qWarning() << "PaymentRequestPlus::getMerchant : Payment request: error creating X509_STORE_CTX";
+ qWarning() << "PaymentRequestPlus::getMerchant: Payment request: error creating X509_STORE_CTX";
return false;
}
int result = X509_verify_cert(store_ctx);
if (result != 1) {
int error = X509_STORE_CTX_get_error(store_ctx);
- throw SSLVerifyError(X509_verify_cert_error_string(error));
+ // For testing payment requests, we allow self signed root certs!
+ // This option is just shown in the UI options, if -help-debug is enabled.
+ if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && GetBoolArg("-allowselfsignedrootcertificates", false))) {
+ throw SSLVerifyError(X509_verify_cert_error_string(error));
+ } else {
+ qDebug() << "PaymentRequestPlus::getMerchant: Allowing self signed root certificate, because -allowselfsignedrootcertificates is true.";
+ }
}
X509_NAME *certname = X509_get_subject_name(signing_cert);
}
// TODO: detect EV certificates and set merchant = business name instead of unfriendly NID_commonName ?
}
- catch (SSLVerifyError& err)
- {
+ catch (const SSLVerifyError& err) {
fResult = false;
- qWarning() << "PaymentRequestPlus::getMerchant : SSL error: " << err.what();
+ qWarning() << "PaymentRequestPlus::getMerchant: SSL error: " << err.what();
}
if (website)
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-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_QT_PAYMENTREQUESTPLUS_H
#include "base58.h"
+#include <openssl/x509.h>
+
#include <QByteArray>
#include <QList>
#include <QString>
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "paymentserver.h"
#include "bitcoinunits.h"
-#include "guiconstants.h"
#include "guiutil.h"
#include "optionsmodel.h"
#include <cstdlib>
-#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
+
#include <QApplication>
#include <QByteArray>
#include <QDataStream>
#endif
using namespace std;
-using namespace boost;
const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds
const QString BITCOIN_IPC_PREFIX("bitcoin:");
-const char* BITCOIN_REQUEST_MIMETYPE = "application/bitcoin-paymentrequest";
-const char* BITCOIN_PAYMENTACK_MIMETYPE = "application/bitcoin-paymentack";
-const char* BITCOIN_PAYMENTACK_CONTENTTYPE = "application/bitcoin-payment";
+// BIP70 payment protocol messages
+const char* BIP70_MESSAGE_PAYMENTACK = "PaymentACK";
+const char* BIP70_MESSAGE_PAYMENTREQUEST = "PaymentRequest";
+// BIP71 payment protocol media types
+const char* BIP71_MIMETYPE_PAYMENT = "application/bitcoin-payment";
+const char* BIP71_MIMETYPE_PAYMENTACK = "application/bitcoin-paymentack";
+const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/bitcoin-paymentrequest";
+// BIP70 max payment request size in bytes (DoS protection)
+const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000;
X509_STORE* PaymentServer::certStore = NULL;
void PaymentServer::freeCertStore()
static void ReportInvalidCertificate(const QSslCertificate& cert)
{
- qDebug() << "ReportInvalidCertificate : Payment server found an invalid certificate: " << cert.subjectInfo(QSslCertificate::CommonName);
+ qDebug() << "ReportInvalidCertificate: Payment server found an invalid certificate: " << cert.subjectInfo(QSslCertificate::CommonName);
}
//
// and get 'I don't like X.509 certificates, don't trust anybody' behavior:
QString certFile = QString::fromStdString(GetArg("-rootcertificates", "-system-"));
- if (certFile.isEmpty())
- return; // Empty store
+ // Empty store
+ if (certFile.isEmpty()) {
+ qDebug() << QString("PaymentServer::%1: Payment request authentication via X.509 certificates disabled.").arg(__func__);
+ return;
+ }
QList<QSslCertificate> certList;
- if (certFile != "-system-")
- {
+ if (certFile != "-system-") {
+ qDebug() << QString("PaymentServer::%1: Using \"%2\" as trusted root certificate.").arg(__func__).arg(certFile);
+
certList = QSslCertificate::fromPath(certFile);
// Use those certificates when fetching payment requests, too:
QSslSocket::setDefaultCaCertificates(certList);
- }
- else
- certList = QSslSocket::systemCaCertificates ();
+ } else
+ certList = QSslSocket::systemCaCertificates();
int nRootCerts = 0;
const QDateTime currentTime = QDateTime::currentDateTime();
continue;
}
}
- qWarning() << "PaymentServer::LoadRootCAs : Loaded " << nRootCerts << " root certificates";
+ qWarning() << "PaymentServer::LoadRootCAs: Loaded " << nRootCerts << " root certificates";
// Project for another day:
// Fetch certificate revocation lists, and add them to certStore.
// Warning: ipcSendCommandLine() is called early in init,
// so don't use "emit message()", but "QMessageBox::"!
//
-bool PaymentServer::ipcParseCommandLine(int argc, char* argv[])
+void PaymentServer::ipcParseCommandLine(int argc, char* argv[])
{
for (int i = 1; i < argc; i++)
{
if (arg.startsWith("-"))
continue;
+ // If the bitcoin: URI contains a payment request, we are not able to detect the
+ // network as that would require fetching and parsing the payment request.
+ // That means clicking such an URI which contains a testnet payment request
+ // will start a mainnet instance and throw a "wrong network" error.
if (arg.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: URI
{
savedPaymentRequests.append(arg);
savedPaymentRequests.append(arg);
PaymentRequestPlus request;
- if (readPaymentRequest(arg, request))
+ if (readPaymentRequestFromFile(arg, request))
{
if (request.getDetails().network() == "main")
{
{
// Printing to debug.log is about the best we can do here, the
// GUI hasn't started yet so we can't pop up a message box.
- qWarning() << "PaymentServer::ipcSendCommandLine : Payment request file does not exist: " << arg;
+ qWarning() << "PaymentServer::ipcSendCommandLine: Payment request file does not exist: " << arg;
}
}
- return true;
}
//
if (!socket->waitForConnected(BITCOIN_IPC_CONNECT_TIMEOUT))
{
delete socket;
+ socket = NULL;
return false;
}
out.setVersion(QDataStream::Qt_4_0);
out << r;
out.device()->seek(0);
+
socket->write(block);
socket->flush();
-
socket->waitForBytesWritten(BITCOIN_IPC_CONNECT_TIMEOUT);
socket->disconnectFromServer();
+
delete socket;
+ socket = NULL;
fResult = true;
}
if (optionsModel->getProxySettings(proxy)) {
netManager->setProxy(proxy);
- qDebug() << "PaymentServer::initNetManager : Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port();
+ qDebug() << "PaymentServer::initNetManager: Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port();
}
else
- qDebug() << "PaymentServer::initNetManager : No active proxy server found.";
+ qDebug() << "PaymentServer::initNetManager: No active proxy server found.";
connect(netManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(netRequestFinished(QNetworkReply*)));
if (fetchUrl.isValid())
{
- qDebug() << "PaymentServer::handleURIOrFile : fetchRequest(" << fetchUrl << ")";
+ qDebug() << "PaymentServer::handleURIOrFile: fetchRequest(" << fetchUrl << ")";
fetchRequest(fetchUrl);
}
else
{
- qWarning() << "PaymentServer::handleURIOrFile : Invalid URL: " << fetchUrl;
+ qWarning() << "PaymentServer::handleURIOrFile: Invalid URL: " << fetchUrl;
emit message(tr("URI handling"),
tr("Payment request fetch URL is invalid: %1").arg(fetchUrl.toString()),
CClientUIInterface::ICON_WARNING);
{
PaymentRequestPlus request;
SendCoinsRecipient recipient;
- if (!readPaymentRequest(s, request))
+ if (!readPaymentRequestFromFile(s, request))
{
emit message(tr("Payment request file handling"),
tr("Payment request file cannot be read! This can be caused by an invalid payment request file."),
handleURIOrFile(msg);
}
-bool PaymentServer::readPaymentRequest(const QString& filename, PaymentRequestPlus& request)
+//
+// Warning: readPaymentRequestFromFile() is used in ipcSendCommandLine()
+// so don't use "emit message()", but "QMessageBox::"!
+//
+bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request)
{
QFile f(filename);
- if (!f.open(QIODevice::ReadOnly))
- {
- qWarning() << "PaymentServer::readPaymentRequest : Failed to open " << filename;
+ if (!f.open(QIODevice::ReadOnly)) {
+ qWarning() << QString("PaymentServer::%1: Failed to open %2").arg(__func__).arg(filename);
return false;
}
- if (f.size() > MAX_PAYMENT_REQUEST_SIZE)
- {
- qWarning() << "PaymentServer::readPaymentRequest : " << filename << " too large";
+ // BIP70 DoS protection
+ if (f.size() > BIP70_MAX_PAYMENTREQUEST_SIZE) {
+ qWarning() << QString("PaymentServer::%1: Payment request %2 is too large (%3 bytes, allowed %4 bytes).")
+ .arg(__func__)
+ .arg(filename)
+ .arg(f.size())
+ .arg(BIP70_MAX_PAYMENTREQUEST_SIZE);
return false;
}
return false;
if (request.IsInitialized()) {
- const payments::PaymentDetails& details = request.getDetails();
-
// Payment request network matches client network?
- if (details.network() != Params().NetworkIDString())
- {
+ if (!verifyNetwork(request.getDetails())) {
emit message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."),
CClientUIInterface::MSG_ERROR);
return false;
}
- // Expired payment request?
- if (details.has_expires() && (int64_t)details.expires() < GetTime())
- {
- emit message(tr("Payment request rejected"), tr("Payment request has expired."),
+ // Make sure any payment requests involved are still valid.
+ // This is re-checked just before sending coins in WalletModel::sendCoins().
+ if (verifyExpired(request.getDetails())) {
+ emit message(tr("Payment request rejected"), tr("Payment request expired."),
CClientUIInterface::MSG_ERROR);
return false;
}
- }
- else {
+ } else {
emit message(tr("Payment request error"), tr("Payment request is not initialized."),
CClientUIInterface::MSG_ERROR);
return false;
}
+ // Bitcoin amounts are stored as (optional) uint64 in the protobuf messages (see paymentrequest.proto),
+ // but CAmount is defined as int64_t. Because of that we need to verify that amounts are in a valid range
+ // and no overflow has happened.
+ if (!verifyAmount(sendingTo.second)) {
+ emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR);
+ return false;
+ }
+
// Extract and check amounts
CTxOut txOut(sendingTo.second, sendingTo.first);
if (txOut.IsDust(::minRelayTxFee)) {
}
recipient.amount += sendingTo.second;
+ // Also verify that the final amount is still in a valid range after adding additional amounts.
+ if (!verifyAmount(recipient.amount)) {
+ emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR);
+ return false;
+ }
}
// Store addresses and format them to fit nicely into the GUI
recipient.address = addresses.join("<br />");
if (!recipient.authenticatedMerchant.isEmpty()) {
- qDebug() << "PaymentServer::processPaymentRequest : Secure payment request from " << recipient.authenticatedMerchant;
+ qDebug() << "PaymentServer::processPaymentRequest: Secure payment request from " << recipient.authenticatedMerchant;
}
else {
- qDebug() << "PaymentServer::processPaymentRequest : Insecure payment request to " << addresses.join(", ");
+ qDebug() << "PaymentServer::processPaymentRequest: Insecure payment request to " << addresses.join(", ");
}
return true;
void PaymentServer::fetchRequest(const QUrl& url)
{
QNetworkRequest netRequest;
- netRequest.setAttribute(QNetworkRequest::User, "PaymentRequest");
+ netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTREQUEST);
netRequest.setUrl(url);
netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
- netRequest.setRawHeader("Accept", BITCOIN_REQUEST_MIMETYPE);
+ netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTREQUEST);
netManager->get(netRequest);
}
return;
QNetworkRequest netRequest;
- netRequest.setAttribute(QNetworkRequest::User, "PaymentACK");
+ netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTACK);
netRequest.setUrl(QString::fromStdString(details.payment_url()));
- netRequest.setHeader(QNetworkRequest::ContentTypeHeader, BITCOIN_PAYMENTACK_CONTENTTYPE);
+ netRequest.setHeader(QNetworkRequest::ContentTypeHeader, BIP71_MIMETYPE_PAYMENT);
netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
- netRequest.setRawHeader("Accept", BITCOIN_PAYMENTACK_MIMETYPE);
+ netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTACK);
payments::Payment payment;
payment.set_merchant_data(details.merchant_data());
else {
CPubKey newKey;
if (wallet->GetKeyFromPool(newKey)) {
- LOCK(wallet->cs_wallet); // SetAddressBook
CKeyID keyID = newKey.GetID();
wallet->SetAddressBook(keyID, strAccount, "refund");
else {
// This should never happen, because sending coins should have
// just unlocked the wallet and refilled the keypool.
- qWarning() << "PaymentServer::fetchPaymentACK : Error getting refund key, refund_to not set";
+ qWarning() << "PaymentServer::fetchPaymentACK: Error getting refund key, refund_to not set";
}
}
}
else {
// This should never happen, either.
- qWarning() << "PaymentServer::fetchPaymentACK : Error serializing payment message";
+ qWarning() << "PaymentServer::fetchPaymentACK: Error serializing payment message";
}
}
void PaymentServer::netRequestFinished(QNetworkReply* reply)
{
reply->deleteLater();
- if (reply->error() != QNetworkReply::NoError)
- {
+
+ // BIP70 DoS protection
+ if (reply->size() > BIP70_MAX_PAYMENTREQUEST_SIZE) {
+ QString msg = tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).")
+ .arg(reply->request().url().toString())
+ .arg(reply->size())
+ .arg(BIP70_MAX_PAYMENTREQUEST_SIZE);
+
+ qWarning() << QString("PaymentServer::%1:").arg(__func__) << msg;
+ emit message(tr("Payment request DoS protection"), msg, CClientUIInterface::MSG_ERROR);
+ return;
+ }
+
+ if (reply->error() != QNetworkReply::NoError) {
QString msg = tr("Error communicating with %1: %2")
.arg(reply->request().url().toString())
.arg(reply->errorString());
- qWarning() << "PaymentServer::netRequestFinished : " << msg;
+ qWarning() << "PaymentServer::netRequestFinished: " << msg;
emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR);
return;
}
QByteArray data = reply->readAll();
QString requestType = reply->request().attribute(QNetworkRequest::User).toString();
- if (requestType == "PaymentRequest")
+ if (requestType == BIP70_MESSAGE_PAYMENTREQUEST)
{
PaymentRequestPlus request;
SendCoinsRecipient recipient;
if (!request.parse(data))
{
- qWarning() << "PaymentServer::netRequestFinished : Error parsing payment request";
+ qWarning() << "PaymentServer::netRequestFinished: Error parsing payment request";
emit message(tr("Payment request error"),
tr("Payment request cannot be parsed!"),
CClientUIInterface::MSG_ERROR);
return;
}
- else if (requestType == "PaymentACK")
+ else if (requestType == BIP70_MESSAGE_PAYMENTACK)
{
payments::PaymentACK paymentACK;
if (!paymentACK.ParseFromArray(data.data(), data.size()))
QString msg = tr("Bad response from server %1")
.arg(reply->request().url().toString());
- qWarning() << "PaymentServer::netRequestFinished : " << msg;
+ qWarning() << "PaymentServer::netRequestFinished: " << msg;
emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR);
}
else
QString errString;
foreach (const QSslError& err, errs) {
- qWarning() << "PaymentServer::reportSslErrors : " << err;
+ qWarning() << "PaymentServer::reportSslErrors: " << err;
errString += err.errorString() + "\n";
}
emit message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR);
// currently we don't futher process or store the paymentACK message
emit message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL);
}
+
+bool PaymentServer::verifyNetwork(const payments::PaymentDetails& requestDetails)
+{
+ bool fVerified = requestDetails.network() == Params().NetworkIDString();
+ if (!fVerified) {
+ qWarning() << QString("PaymentServer::%1: Payment request network \"%2\" doesn't match client network \"%3\".")
+ .arg(__func__)
+ .arg(QString::fromStdString(requestDetails.network()))
+ .arg(QString::fromStdString(Params().NetworkIDString()));
+ }
+ return fVerified;
+}
+
+bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails)
+{
+ bool fVerified = (requestDetails.has_expires() && (int64_t)requestDetails.expires() < GetTime());
+ if (fVerified) {
+ const QString requestExpires = QString::fromStdString(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", (int64_t)requestDetails.expires()));
+ qWarning() << QString("PaymentServer::%1: Payment request expired \"%2\".")
+ .arg(__func__)
+ .arg(requestExpires);
+ }
+ return fVerified;
+}
+
+bool PaymentServer::verifyAmount(const CAmount& requestAmount)
+{
+ bool fVerified = MoneyRange(requestAmount);
+ if (!fVerified) {
+ qWarning() << QString("PaymentServer::%1: Payment request amount out of allowed range (%2, allowed 0 - %3).")
+ .arg(__func__)
+ .arg(requestAmount)
+ .arg(MAX_MONEY);
+ }
+ return fVerified;
+}
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-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.
#ifndef BITCOIN_QT_PAYMENTSERVER_H
class OptionsModel;
+class CWallet;
+
QT_BEGIN_NAMESPACE
class QApplication;
class QByteArray;
class QUrl;
QT_END_NAMESPACE
-class CWallet;
+// BIP70 max payment request size in bytes (DoS protection)
+extern const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE;
class PaymentServer : public QObject
{
public:
// Parse URIs on command line
// Returns false on error
- static bool ipcParseCommandLine(int argc, char *argv[]);
+ static void ipcParseCommandLine(int argc, char *argv[]);
// Returns true if there were URIs on the command line
// which were successfully sent to an already-running
// OptionsModel is used for getting proxy settings and display unit
void setOptionsModel(OptionsModel *optionsModel);
+ // This is now public, because we use it in paymentservertests.cpp
+ static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request);
+
+ // Verify that the payment request network matches the client network
+ static bool verifyNetwork(const payments::PaymentDetails& requestDetails);
+ // Verify if the payment request is expired
+ static bool verifyExpired(const payments::PaymentDetails& requestDetails);
+ // Verify the payment request amount is valid
+ static bool verifyAmount(const CAmount& requestAmount);
+
signals:
// Fired when a valid payment request is received
void receivedPaymentRequest(SendCoinsRecipient);
bool eventFilter(QObject *object, QEvent *event);
private:
- static bool readPaymentRequest(const QString& filename, PaymentRequestPlus& request);
bool processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient);
void fetchRequest(const QUrl& url);
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "peertablemodel.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_PEERTABLEMODEL_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "qvalidatedlineedit.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_QVALIDATEDLINEEDIT_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "qvaluecombobox.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_QVALUECOMBOBOX_H
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "receivecoinsdialog.h"
#include "optionsmodel.h"
#include "receiverequestdialog.h"
#include "recentrequeststablemodel.h"
+#include "scicon.h"
#include "walletmodel.h"
#include <QAction>
ui->receiveButton->setIcon(QIcon());
ui->showRequestButton->setIcon(QIcon());
ui->removeRequestButton->setIcon(QIcon());
+#else
+ ui->clearButton->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->receiveButton->setIcon(SingleColorIcon(":/icons/receiving_addresses"));
+ ui->showRequestButton->setIcon(SingleColorIcon(":/icons/edit"));
+ ui->removeRequestButton->setIcon(SingleColorIcon(":/icons/remove"));
#endif
// context menu actions
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-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.
#ifndef BITCOIN_QT_RECEIVECOINSDIALOG_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "receiverequestdialog.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_RECEIVEREQUESTDIALOG_H
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "recentrequeststablemodel.h"
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-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.
#ifndef BITCOIN_QT_RECENTREQUESTSTABLEMODEL_H
IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico"
-IDI_ICON2 ICON DISCARDABLE "icons/bitcoin_testnet.ico"
#include <windows.h> // needed for VERSIONINFO
#include "../../clientversion.h" // holds the needed client version information
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", "bitcoin-qt"
VALUE "LegalCopyright", COPYRIGHT_STR
- VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
+ VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
VALUE "OriginalFilename", "bitcoin-qt.exe"
VALUE "ProductName", "Bitcoin Core"
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
--- /dev/null
+for i in {1..35}
+do
+ value=$(printf "%03d" $i)
+ angle=$(($i * 10))
+ convert spinner-000.png -background "rgba(0,0,0,0.0)" -distort SRT $angle spinner-$value.png
+done
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16px"
- height="16px"
- id="svg2987"
- version="1.1"
- inkscape:version="0.48.0 r9654"
- sodipodi:docname="clock0.svg">
- <defs
- id="defs2989">
- <linearGradient
- id="linearGradient4465">
- <stop
- id="stop4467"
- offset="0"
- style="stop-color:#c1c1c1;stop-opacity:1;" />
- <stop
- id="stop4469"
- offset="1"
- style="stop-color:#8c8c8c;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4424">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop4426" />
- <stop
- style="stop-color:#b3b3b3;stop-opacity:1;"
- offset="1"
- id="stop4428" />
- </linearGradient>
- <linearGradient
- id="linearGradient4357">
- <stop
- id="stop4359"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- style="stop-color:#ff84a6;stop-opacity:0.49803922;"
- offset="0.36363637"
- id="stop4473" />
- <stop
- id="stop4361"
- offset="1"
- style="stop-color:#ff0a4d;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4347">
- <stop
- id="stop4349"
- offset="0"
- style="stop-color:#909090;stop-opacity:1;" />
- <stop
- id="stop4351"
- offset="1"
- style="stop-color:#3c3c3c;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient3767">
- <stop
- style="stop-color:#ff8282;stop-opacity:1;"
- offset="0"
- id="stop3769" />
- <stop
- style="stop-color:#ff1919;stop-opacity:1;"
- offset="1"
- id="stop3771" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4347"
- id="linearGradient3779"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574"
- gradientUnits="userSpaceOnUse" />
- <filter
- inkscape:collect="always"
- id="filter4339">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.3240906"
- id="feGaussianBlur4341" />
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3767"
- id="linearGradient4345"
- gradientUnits="userSpaceOnUse"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4424"
- id="linearGradient4430"
- x1="10.740074"
- y1="16.148634"
- x2="6.3055735"
- y2="-1.2798394"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4357"
- id="radialGradient4440"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)"
- cx="8.1975746"
- cy="-0.080271922"
- fx="8.1975746"
- fy="-0.080271922"
- r="7.7781744" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4465"
- id="linearGradient4471"
- gradientUnits="userSpaceOnUse"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="1"
- inkscape:cx="0.31530906"
- inkscape:cy="12.478576"
- inkscape:current-layer="layer4"
- showgrid="true"
- inkscape:grid-bbox="true"
- inkscape:document-units="px"
- inkscape:window-width="1920"
- inkscape:window-height="1127"
- inkscape:window-x="0"
- inkscape:window-y="25"
- inkscape:window-maximized="1"
- showguides="true"
- inkscape:guide-bbox="true" />
- <metadata
- id="metadata2992">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:groupmode="layer"
- id="layer4"
- inkscape:label="Shadow"
- style="display:inline">
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)"
- id="path2997"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.7781744"
- sodipodi:ry="7.7781744"
- d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z"
- transform="translate(0,-0.08838835)" />
- </g>
- <g
- id="layer1"
- inkscape:label="Clock"
- inkscape:groupmode="layer"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)"
- d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z"
- sodipodi:ry="7.7781744"
- sodipodi:rx="7.7781744"
- sodipodi:cy="8.1334372"
- sodipodi:cx="8.0433397"
- id="path4343"
- style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none"
- sodipodi:type="arc" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer5"
- inkscape:label="Block"
- sodipodi:insensitive="true"
- style="display:inline">
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline"
- id="path4462"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.7781744"
- sodipodi:ry="7.7781744"
- d="M 14.4287,3.6919089 A 7.7781744,7.7781744 0 1 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z"
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)"
- sodipodi:start="5.675432"
- sodipodi:end="10.999096" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer2"
- inkscape:label="Ticks"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- id="use4309"
- transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)"
- style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none"
- d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 7.875,2.8017767 0,5.25"
- id="path4436"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 7.7781746,7.4629419 10.783378,7.6397186"
- id="path4438"
- inkscape:connector-curvature="0" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer3"
- inkscape:label="Shine"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- sodipodi:type="arc"
- style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none"
- id="path4353"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.3686199"
- sodipodi:ry="7.4368792"
- d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z"
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" />
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16px"
- height="16px"
- id="svg2987"
- version="1.1"
- inkscape:version="0.48.0 r9654"
- sodipodi:docname="clock0.svg">
- <defs
- id="defs2989">
- <linearGradient
- id="linearGradient4465">
- <stop
- id="stop4467"
- offset="0"
- style="stop-color:#c1c1c1;stop-opacity:1;" />
- <stop
- id="stop4469"
- offset="1"
- style="stop-color:#8c8c8c;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4424">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop4426" />
- <stop
- style="stop-color:#b3b3b3;stop-opacity:1;"
- offset="1"
- id="stop4428" />
- </linearGradient>
- <linearGradient
- id="linearGradient4357">
- <stop
- id="stop4359"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- style="stop-color:#ff848d;stop-opacity:0.49803922;"
- offset="0.36363637"
- id="stop4473" />
- <stop
- id="stop4361"
- offset="1"
- style="stop-color:#ff0a1b;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4347">
- <stop
- id="stop4349"
- offset="0"
- style="stop-color:#909090;stop-opacity:1;" />
- <stop
- id="stop4351"
- offset="1"
- style="stop-color:#3c3c3c;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient3767">
- <stop
- style="stop-color:#ffae82;stop-opacity:1;"
- offset="0"
- id="stop3769" />
- <stop
- style="stop-color:#ff6a19;stop-opacity:1;"
- offset="1"
- id="stop3771" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4347"
- id="linearGradient3779"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574"
- gradientUnits="userSpaceOnUse" />
- <filter
- inkscape:collect="always"
- id="filter4339">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.3240906"
- id="feGaussianBlur4341" />
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3767"
- id="linearGradient4345"
- gradientUnits="userSpaceOnUse"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4424"
- id="linearGradient4430"
- x1="10.740074"
- y1="16.148634"
- x2="6.3055735"
- y2="-1.2798394"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4357"
- id="radialGradient4440"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)"
- cx="8.1975746"
- cy="-0.080271922"
- fx="8.1975746"
- fy="-0.080271922"
- r="7.7781744" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4465"
- id="linearGradient4471"
- gradientUnits="userSpaceOnUse"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="1"
- inkscape:cx="10.569917"
- inkscape:cy="10.828475"
- inkscape:current-layer="layer5"
- showgrid="true"
- inkscape:grid-bbox="true"
- inkscape:document-units="px"
- inkscape:window-width="1920"
- inkscape:window-height="1127"
- inkscape:window-x="0"
- inkscape:window-y="25"
- inkscape:window-maximized="1"
- showguides="true"
- inkscape:guide-bbox="true" />
- <metadata
- id="metadata2992">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:groupmode="layer"
- id="layer4"
- inkscape:label="Shadow"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)"
- id="path2997"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.7781744"
- sodipodi:ry="7.7781744"
- d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z"
- transform="translate(0,-0.08838835)" />
- </g>
- <g
- id="layer1"
- inkscape:label="Clock"
- inkscape:groupmode="layer"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)"
- d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z"
- sodipodi:ry="7.7781744"
- sodipodi:rx="7.7781744"
- sodipodi:cy="8.1334372"
- sodipodi:cx="8.0433397"
- id="path4343"
- style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none"
- sodipodi:type="arc" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer5"
- inkscape:label="Block"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline"
- id="path4462"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.7781744"
- sodipodi:ry="7.7781744"
- d="M 15.197954,11.184912 A 7.7781744,7.7781744 0 1 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z"
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)"
- sodipodi:start="0.4031442"
- sodipodi:end="4.7159107" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer2"
- inkscape:label="Ticks"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- id="use4309"
- transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)"
- style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none"
- d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 7.875,2.8017767 0,5.25"
- id="path4436"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 7.7781746,7.4629419 10.783378,7.6397186"
- id="path4438"
- inkscape:connector-curvature="0" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer3"
- inkscape:label="Shine"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- sodipodi:type="arc"
- style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none"
- id="path4353"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.3686199"
- sodipodi:ry="7.4368792"
- d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z"
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" />
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16px"
- height="16px"
- id="svg2987"
- version="1.1"
- inkscape:version="0.48.0 r9654"
- sodipodi:docname="clock1.svg">
- <defs
- id="defs2989">
- <linearGradient
- id="linearGradient4465">
- <stop
- id="stop4467"
- offset="0"
- style="stop-color:#c1c1c1;stop-opacity:1;" />
- <stop
- id="stop4469"
- offset="1"
- style="stop-color:#8c8c8c;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4424">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop4426" />
- <stop
- style="stop-color:#b3b3b3;stop-opacity:1;"
- offset="1"
- id="stop4428" />
- </linearGradient>
- <linearGradient
- id="linearGradient4357">
- <stop
- id="stop4359"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- style="stop-color:#ffa184;stop-opacity:0.49803922;"
- offset="0.36363637"
- id="stop4473" />
- <stop
- id="stop4361"
- offset="1"
- style="stop-color:#ff440a;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4347">
- <stop
- id="stop4349"
- offset="0"
- style="stop-color:#909090;stop-opacity:1;" />
- <stop
- id="stop4351"
- offset="1"
- style="stop-color:#3c3c3c;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient3767">
- <stop
- style="stop-color:#ffda82;stop-opacity:1;"
- offset="0"
- id="stop3769" />
- <stop
- style="stop-color:#ffbb19;stop-opacity:1;"
- offset="1"
- id="stop3771" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4347"
- id="linearGradient3779"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574"
- gradientUnits="userSpaceOnUse" />
- <filter
- inkscape:collect="always"
- id="filter4339">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.3240906"
- id="feGaussianBlur4341" />
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3767"
- id="linearGradient4345"
- gradientUnits="userSpaceOnUse"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4424"
- id="linearGradient4430"
- x1="10.740074"
- y1="16.148634"
- x2="6.3055735"
- y2="-1.2798394"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4357"
- id="radialGradient4440"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)"
- cx="8.1975746"
- cy="-0.080271922"
- fx="8.1975746"
- fy="-0.080271922"
- r="7.7781744" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4465"
- id="linearGradient4471"
- gradientUnits="userSpaceOnUse"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="23.894737"
- inkscape:cx="16"
- inkscape:cy="-1"
- inkscape:current-layer="layer5"
- showgrid="true"
- inkscape:grid-bbox="true"
- inkscape:document-units="px"
- inkscape:window-width="1920"
- inkscape:window-height="1127"
- inkscape:window-x="0"
- inkscape:window-y="25"
- inkscape:window-maximized="1"
- showguides="true"
- inkscape:guide-bbox="true" />
- <metadata
- id="metadata2992">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:groupmode="layer"
- id="layer4"
- inkscape:label="Shadow"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)"
- id="path2997"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.7781744"
- sodipodi:ry="7.7781744"
- d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z"
- transform="translate(0,-0.08838835)" />
- </g>
- <g
- id="layer1"
- inkscape:label="Clock"
- inkscape:groupmode="layer"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)"
- d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z"
- sodipodi:ry="7.7781744"
- sodipodi:rx="7.7781744"
- sodipodi:cy="8.1334372"
- sodipodi:cx="8.0433397"
- id="path4343"
- style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none"
- sodipodi:type="arc" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer5"
- inkscape:label="Block"
- style="display:inline">
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline"
- id="path4462"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.7781744"
- sodipodi:ry="7.7781744"
- d="M 8.2135533,15.909749 A 7.7781744,7.7781744 0 1 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z"
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)"
- sodipodi:start="1.5489111"
- sodipodi:end="4.7159107" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer2"
- inkscape:label="Ticks"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- id="use4309"
- transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)"
- style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none"
- d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 7.875,2.8017767 0,5.25"
- id="path4436"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 7.7781746,7.4629419 10.783378,7.6397186"
- id="path4438"
- inkscape:connector-curvature="0" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer3"
- inkscape:label="Shine"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- sodipodi:type="arc"
- style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none"
- id="path4353"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.3686199"
- sodipodi:ry="7.4368792"
- d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z"
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" />
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16px"
- height="16px"
- id="svg2987"
- version="1.1"
- inkscape:version="0.48.0 r9654"
- sodipodi:docname="clock2.svg">
- <defs
- id="defs2989">
- <linearGradient
- id="linearGradient4465">
- <stop
- id="stop4467"
- offset="0"
- style="stop-color:#c1c1c1;stop-opacity:1;" />
- <stop
- id="stop4469"
- offset="1"
- style="stop-color:#8c8c8c;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4424">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop4426" />
- <stop
- style="stop-color:#b3b3b3;stop-opacity:1;"
- offset="1"
- id="stop4428" />
- </linearGradient>
- <linearGradient
- id="linearGradient4357">
- <stop
- id="stop4359"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- style="stop-color:#ffcc84;stop-opacity:0.49803922;"
- offset="0.36363637"
- id="stop4473" />
- <stop
- id="stop4361"
- offset="1"
- style="stop-color:#ff9a0a;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4347">
- <stop
- id="stop4349"
- offset="0"
- style="stop-color:#909090;stop-opacity:1;" />
- <stop
- id="stop4351"
- offset="1"
- style="stop-color:#3c3c3c;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient3767">
- <stop
- style="stop-color:#f8ff82;stop-opacity:1;"
- offset="0"
- id="stop3769" />
- <stop
- style="stop-color:#f1ff19;stop-opacity:1;"
- offset="1"
- id="stop3771" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4347"
- id="linearGradient3779"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574"
- gradientUnits="userSpaceOnUse" />
- <filter
- inkscape:collect="always"
- id="filter4339">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.3240906"
- id="feGaussianBlur4341" />
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3767"
- id="linearGradient4345"
- gradientUnits="userSpaceOnUse"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4424"
- id="linearGradient4430"
- x1="10.740074"
- y1="16.148634"
- x2="6.3055735"
- y2="-1.2798394"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4357"
- id="radialGradient4440"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)"
- cx="8.1975746"
- cy="-0.080271922"
- fx="8.1975746"
- fy="-0.080271922"
- r="7.7781744" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4465"
- id="linearGradient4471"
- gradientUnits="userSpaceOnUse"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="16"
- inkscape:cx="8.6111742"
- inkscape:cy="6.6684704"
- inkscape:current-layer="layer5"
- showgrid="true"
- inkscape:grid-bbox="true"
- inkscape:document-units="px"
- inkscape:window-width="1920"
- inkscape:window-height="1127"
- inkscape:window-x="0"
- inkscape:window-y="25"
- inkscape:window-maximized="1"
- showguides="true"
- inkscape:guide-bbox="true" />
- <metadata
- id="metadata2992">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:groupmode="layer"
- id="layer4"
- inkscape:label="Shadow"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)"
- id="path2997"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.7781744"
- sodipodi:ry="7.7781744"
- d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z"
- transform="translate(0,-0.08838835)" />
- </g>
- <g
- id="layer1"
- inkscape:label="Clock"
- inkscape:groupmode="layer"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)"
- d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z"
- sodipodi:ry="7.7781744"
- sodipodi:rx="7.7781744"
- sodipodi:cy="8.1334372"
- sodipodi:cx="8.0433397"
- id="path4343"
- style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none"
- sodipodi:type="arc" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer5"
- inkscape:label="Block"
- style="display:inline">
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline"
- id="path4462"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.7781744"
- sodipodi:ry="7.7781744"
- d="M 1.7005474,12.635546 A 7.7781744,7.7781744 0 0 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z"
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)"
- sodipodi:start="2.5243203"
- sodipodi:end="4.7159107" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer2"
- inkscape:label="Ticks"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- id="use4309"
- transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)"
- style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none"
- d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 7.875,2.8017767 0,5.25"
- id="path4436"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 7.7781746,7.4629419 10.783378,7.6397186"
- id="path4438"
- inkscape:connector-curvature="0" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer3"
- inkscape:label="Shine"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- sodipodi:type="arc"
- style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none"
- id="path4353"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.3686199"
- sodipodi:ry="7.4368792"
- d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z"
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" />
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16px"
- height="16px"
- id="svg2987"
- version="1.1"
- inkscape:version="0.48.0 r9654"
- sodipodi:docname="clock3.svg">
- <defs
- id="defs2989">
- <linearGradient
- id="linearGradient4465">
- <stop
- id="stop4467"
- offset="0"
- style="stop-color:#c1c1c1;stop-opacity:1;" />
- <stop
- id="stop4469"
- offset="1"
- style="stop-color:#8c8c8c;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4424">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop4426" />
- <stop
- style="stop-color:#b3b3b3;stop-opacity:1;"
- offset="1"
- id="stop4428" />
- </linearGradient>
- <linearGradient
- id="linearGradient4357">
- <stop
- id="stop4359"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- style="stop-color:#fff884;stop-opacity:0.49803922;"
- offset="0.36363637"
- id="stop4473" />
- <stop
- id="stop4361"
- offset="1"
- style="stop-color:#fff10a;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4347">
- <stop
- id="stop4349"
- offset="0"
- style="stop-color:#909090;stop-opacity:1;" />
- <stop
- id="stop4351"
- offset="1"
- style="stop-color:#3c3c3c;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient3767">
- <stop
- style="stop-color:#ccff82;stop-opacity:1;"
- offset="0"
- id="stop3769" />
- <stop
- style="stop-color:#a0ff19;stop-opacity:1;"
- offset="1"
- id="stop3771" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4347"
- id="linearGradient3779"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574"
- gradientUnits="userSpaceOnUse" />
- <filter
- inkscape:collect="always"
- id="filter4339">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.3240906"
- id="feGaussianBlur4341" />
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3767"
- id="linearGradient4345"
- gradientUnits="userSpaceOnUse"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4424"
- id="linearGradient4430"
- x1="10.740074"
- y1="16.148634"
- x2="6.3055735"
- y2="-1.2798394"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4357"
- id="radialGradient4440"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)"
- cx="8.1975746"
- cy="-0.080271922"
- fx="8.1975746"
- fy="-0.080271922"
- r="7.7781744" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4465"
- id="linearGradient4471"
- gradientUnits="userSpaceOnUse"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="16"
- inkscape:cx="8.6111742"
- inkscape:cy="6.6684704"
- inkscape:current-layer="layer3"
- showgrid="true"
- inkscape:grid-bbox="true"
- inkscape:document-units="px"
- inkscape:window-width="1920"
- inkscape:window-height="1127"
- inkscape:window-x="0"
- inkscape:window-y="25"
- inkscape:window-maximized="1"
- showguides="true"
- inkscape:guide-bbox="true" />
- <metadata
- id="metadata2992">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:groupmode="layer"
- id="layer4"
- inkscape:label="Shadow"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)"
- id="path2997"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.7781744"
- sodipodi:ry="7.7781744"
- d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z"
- transform="translate(0,-0.08838835)" />
- </g>
- <g
- id="layer1"
- inkscape:label="Clock"
- inkscape:groupmode="layer"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)"
- d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z"
- sodipodi:ry="7.7781744"
- sodipodi:rx="7.7781744"
- sodipodi:cy="8.1334372"
- sodipodi:cx="8.0433397"
- id="path4343"
- style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none"
- sodipodi:type="arc" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer5"
- inkscape:label="Block"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline"
- id="path4462"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.7781744"
- sodipodi:ry="7.7781744"
- d="M 1.0968082,4.6340519 A 7.7781744,7.7781744 0 0 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z"
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)"
- sodipodi:start="3.6082438"
- sodipodi:end="4.7159107" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer2"
- inkscape:label="Ticks"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- id="use4309"
- transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)"
- style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none"
- d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 7.875,2.8017767 0,5.25"
- id="path4436"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 7.7781746,7.4629419 10.783378,7.6397186"
- id="path4438"
- inkscape:connector-curvature="0" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer3"
- inkscape:label="Shine"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- sodipodi:type="arc"
- style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none"
- id="path4353"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.3686199"
- sodipodi:ry="7.4368792"
- d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z"
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" />
- </g>
-</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 841.9 841.9" enable-background="new 0 0 841.9 841.9" xml:space="preserve">\r
+<g>\r
+ <path d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1\r
+ s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6\r
+ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4\r
+ c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>\r
+</g>\r
+<path fill="#000000" d="M293.5,452.6h99.6c14.9,0,24.8-9.9,24.8-24.8S408,403,393.1,403h-74.8V278.2c0-14.9-9.9-24.8-24.8-24.8\r
+ c-14.9,0-24.8,9.9-24.8,24.8v149.6C268.7,440.2,278.7,452.6,293.5,452.6z"/>\r
+</svg>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 841.9 841.9" enable-background="new 0 0 841.9 841.9" xml:space="preserve">\r
+<g>\r
+ <path d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1\r
+ s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6\r
+ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4\r
+ c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>\r
+</g>\r
+<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>\r
+</svg>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 841.9 841.9" enable-background="new 0 0 841.9 841.9" xml:space="preserve">\r
+<g>\r
+ <path d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1\r
+ s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6\r
+ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4\r
+ c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>\r
+</g>\r
+<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>\r
+<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>\r
+</svg>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 841.9 841.9" enable-background="new 0 0 841.9 841.9" xml:space="preserve">\r
+<g>\r
+ <path d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1\r
+ s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6\r
+ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4\r
+ c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>\r
+</g>\r
+<polygon points="117,588.5 297.6,657.3 297.6,420.9 61.3,420.9 "/>\r
+<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>\r
+<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>\r
+</svg>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 841.9 841.9" enable-background="new 0 0 841.9 841.9" xml:space="preserve">\r
+<g>\r
+ <path d="M297.6,677.3c-68.5,0-132.9-26.7-181.3-75.1S41.3,489.4,41.3,420.9s26.7-132.9,75.1-181.3c48.4-48.4,112.8-75.1,181.3-75.1\r
+ s132.9,26.7,181.3,75.1c48.4,48.4,75.1,112.8,75.1,181.3s-26.7,132.9-75.1,181.3S366.1,677.3,297.6,677.3z M297.6,204.6\r
+ c-57.8,0-112.1,22.5-153,63.4c-40.9,40.9-63.4,95.2-63.4,153c0,57.8,22.5,112.1,63.4,153c40.9,40.9,95.2,63.4,153,63.4\r
+ c57.8,0,112.1-22.5,153-63.4c40.9-40.9,63.4-95.2,63.4-153c0-57.8-22.5-112.1-63.4-153C409.8,227.1,355.4,204.6,297.6,204.6z"/>\r
+</g>\r
+<polygon points="130.1,240.3 61.3,420.9 297.6,420.9 297.6,184.6 "/>\r
+<polygon points="117,588.5 297.6,657.3 297.6,420.9 61.3,420.9 "/>\r
+<polygon points="465.2,601.6 534,420.9 297.6,420.9 297.6,657.3 "/>\r
+<polygon points="478.3,253.4 297.6,184.6 297.6,420.9 534,420.9 "/>\r
+<path fill="#FFFFFF" d="M293.5,452.6h99.6c14.9,0,24.8-9.9,24.8-24.8S408,403,393.1,403h-74.8V278.2c0-14.9-9.9-24.8-24.8-24.8\r
+ c-14.9,0-24.8,9.9-24.8,24.8v149.6C268.7,440.2,278.7,452.6,293.5,452.6z"/>\r
+</svg>\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16px"
- height="16px"
- id="svg2987"
- version="1.1"
- inkscape:version="0.48.0 r9654"
- sodipodi:docname="clock_green.svg">
- <defs
- id="defs2989">
- <linearGradient
- id="linearGradient4465">
- <stop
- id="stop4467"
- offset="0"
- style="stop-color:#c1c1c1;stop-opacity:1;" />
- <stop
- id="stop4469"
- offset="1"
- style="stop-color:#8c8c8c;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4424">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop4426" />
- <stop
- style="stop-color:#b3b3b3;stop-opacity:1;"
- offset="1"
- id="stop4428" />
- </linearGradient>
- <linearGradient
- id="linearGradient4357">
- <stop
- id="stop4359"
- offset="0"
- style="stop-color:#ffffff;stop-opacity:1;" />
- <stop
- style="stop-color:#baff84;stop-opacity:0.49803922;"
- offset="0.36363637"
- id="stop4473" />
- <stop
- id="stop4361"
- offset="1"
- style="stop-color:#76ff0a;stop-opacity:0;" />
- </linearGradient>
- <linearGradient
- id="linearGradient4347">
- <stop
- id="stop4349"
- offset="0"
- style="stop-color:#c1c1c1;stop-opacity:1;" />
- <stop
- id="stop4351"
- offset="1"
- style="stop-color:#8c8c8c;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- id="linearGradient3767">
- <stop
- style="stop-color:#82ff82;stop-opacity:1;"
- offset="0"
- id="stop3769" />
- <stop
- style="stop-color:#19ff19;stop-opacity:1;"
- offset="1"
- id="stop3771" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4347"
- id="linearGradient3779"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574"
- gradientUnits="userSpaceOnUse" />
- <filter
- inkscape:collect="always"
- id="filter4339">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.3240906"
- id="feGaussianBlur4341" />
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3767"
- id="linearGradient4345"
- gradientUnits="userSpaceOnUse"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4424"
- id="linearGradient4430"
- x1="10.740074"
- y1="16.148634"
- x2="6.3055735"
- y2="-1.2798394"
- gradientUnits="userSpaceOnUse" />
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4357"
- id="radialGradient4440"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)"
- cx="8.1975746"
- cy="-0.080271922"
- fx="8.1975746"
- fy="-0.080271922"
- r="7.7781744" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4465"
- id="linearGradient4471"
- gradientUnits="userSpaceOnUse"
- x1="2.224874"
- y1="2.8301363"
- x2="14.038582"
- y2="13.171574" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="8"
- inkscape:cx="9.1870806"
- inkscape:cy="14.089546"
- inkscape:current-layer="layer3"
- showgrid="true"
- inkscape:grid-bbox="true"
- inkscape:document-units="px"
- inkscape:window-width="1920"
- inkscape:window-height="1127"
- inkscape:window-x="0"
- inkscape:window-y="25"
- inkscape:window-maximized="1"
- showguides="true"
- inkscape:guide-bbox="true" />
- <metadata
- id="metadata2992">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:groupmode="layer"
- id="layer4"
- inkscape:label="Shadow"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)"
- id="path2997"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.7781744"
- sodipodi:ry="7.7781744"
- d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z"
- transform="translate(0,-0.08838835)" />
- </g>
- <g
- id="layer1"
- inkscape:label="Clock"
- inkscape:groupmode="layer"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)"
- d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z"
- sodipodi:ry="7.7781744"
- sodipodi:rx="7.7781744"
- sodipodi:cy="8.1334372"
- sodipodi:cx="8.0433397"
- id="path4343"
- style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none"
- sodipodi:type="arc" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer5"
- inkscape:label="Block"
- sodipodi:insensitive="true"
- style="display:inline">
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline"
- id="path4462"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.7781744"
- sodipodi:ry="7.7781744"
- d="M 14.4287,3.6919089 A 7.7781744,7.7781744 0 1 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z"
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)"
- sodipodi:start="5.675432"
- sodipodi:end="10.999096" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer2"
- inkscape:label="Ticks"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- id="use4309"
- transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)"
- style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none"
- d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 7.875,2.8017767 0,5.25"
- id="path4436"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 7.7781746,7.4629419 10.783378,7.6397186"
- id="path4438"
- inkscape:connector-curvature="0" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer3"
- inkscape:label="Shine"
- style="display:inline"
- sodipodi:insensitive="true">
- <path
- sodipodi:type="arc"
- style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none"
- id="path4353"
- sodipodi:cx="8.0433397"
- sodipodi:cy="8.1334372"
- sodipodi:rx="7.3686199"
- sodipodi:ry="7.4368792"
- d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z"
- transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" />
- </g>
-</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">\r
+<path fill="none" stroke="#000000" stroke-miterlimit="10" d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0\r
+ c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z M7.8,15.8c-0.5,0-1-0.2-1.4-0.6c-0.8-0.8-0.8-2,0-2.8\r
+ c3.1-3.1,8.2-3.1,11.3,0c0.8,0.8,0.8,2,0,2.8c-0.8,0.8-2,0.8-2.8,0c-1.6-1.6-4.1-1.6-5.7,0C8.8,15.6,8.3,15.8,7.8,15.8z"/>\r
+<path fill="none" stroke="#000000" stroke-miterlimit="10" d="M20.5,11.5c-0.5,0-1-0.2-1.4-0.6C15.2,7,8.8,7,4.9,10.9\r
+ c-0.8,0.8-2,0.8-2.8,0c-0.8-0.8-0.8-2,0-2.8c5.5-5.5,14.3-5.5,19.8,0c0.8,0.8,0.8,2,0,2.8C21.5,11.3,21,11.5,20.5,11.5z"/>\r
+</svg>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">\r
+<g>\r
+ <path d="M12,11c1.9,0,3.6,0.7,4.9,2c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C14.6,13.5,13.3,13,12,13\r
+ c-1.3,0-2.6,0.5-3.5,1.5c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C8.4,11.7,10.1,11,12,11 M12,17\r
+ c0.3,0,0.5,0.1,0.7,0.3c0.2,0.2,0.3,0.4,0.3,0.7s-0.1,0.5-0.3,0.7C12.5,18.9,12.3,19,12,19c-0.3,0-0.5-0.1-0.7-0.3\r
+ C11.1,18.5,11,18.3,11,18c0-0.3,0.1-0.5,0.3-0.7C11.5,17.1,11.7,17,12,17 M12,10c-2,0-4.1,0.8-5.7,2.3c-0.8,0.8-0.8,2,0,2.8\r
+ c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C10,14.4,11,14,12,14c1,0,2,0.4,2.8,1.2c0.4,0.4,0.9,0.6,1.4,0.6s1-0.2,1.4-0.6\r
+ c0.8-0.8,0.8-2,0-2.8C16.1,10.8,14,10,12,10L12,10z M12,16c-0.5,0-1,0.2-1.4,0.6c-0.8,0.8-0.8,2.1,0,2.8C11,19.8,11.5,20,12,20\r
+ c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C13,16.2,12.5,16,12,16L12,16z"/>\r
+</g>\r
+<g>\r
+ <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7\r
+ c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4\r
+ C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9\r
+ c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>\r
+</g>\r
+</svg>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">\r
+<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z"/>\r
+<g>\r
+ <path d="M12,11c1.9,0,3.6,0.7,4.9,2c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C14.6,13.5,13.3,13,12,13\r
+ c-1.3,0-2.6,0.5-3.5,1.5c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C8.4,11.7,10.1,11,12,11 M12,17\r
+ c0.3,0,0.5,0.1,0.7,0.3c0.2,0.2,0.3,0.4,0.3,0.7s-0.1,0.5-0.3,0.7C12.5,18.9,12.3,19,12,19c-0.3,0-0.5-0.1-0.7-0.3\r
+ C11.1,18.5,11,18.3,11,18c0-0.3,0.1-0.5,0.3-0.7C11.5,17.1,11.7,17,12,17 M12,10c-2,0-4.1,0.8-5.7,2.3c-0.8,0.8-0.8,2,0,2.8\r
+ c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C10,14.4,11,14,12,14c1,0,2,0.4,2.8,1.2c0.4,0.4,0.9,0.6,1.4,0.6s1-0.2,1.4-0.6\r
+ c0.8-0.8,0.8-2,0-2.8C16.1,10.8,14,10,12,10L12,10z M12,16c-0.5,0-1,0.2-1.4,0.6c-0.8,0.8-0.8,2.1,0,2.8C11,19.8,11.5,20,12,20\r
+ c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C13,16.2,12.5,16,12,16L12,16z"/>\r
+</g>\r
+<g>\r
+ <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7\r
+ c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4\r
+ C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9\r
+ c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>\r
+</g>\r
+</svg>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">\r
+<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z"/>\r
+<path d="M13.4,19.4c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0c-0.8,0.8-0.8,2.1,0,2.8C11.4,20.2,12.6,20.2,13.4,19.4z M7.8,15.8\r
+ c-0.5,0-1-0.2-1.4-0.6c-0.8-0.8-0.8-2,0-2.8c3.1-3.1,8.2-3.1,11.3,0c0.8,0.8,0.8,2,0,2.8c-0.8,0.8-2,0.8-2.8,0\r
+ c-1.6-1.6-4.1-1.6-5.7,0C8.8,15.6,8.3,15.8,7.8,15.8z"/>\r
+<g>\r
+ <path d="M12,5c3.5,0,6.7,1.3,9.2,3.8c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3C17.7,8.1,14.9,7,12,7\r
+ c-2.9,0-5.7,1.1-7.8,3.2c-0.2,0.2-0.4,0.3-0.7,0.3c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4C5.3,6.4,8.5,5,12,5 M12,4\r
+ C8.4,4,4.8,5.4,2.1,8.1c-0.8,0.8-0.8,2,0,2.8c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6C6.9,9,9.4,8,12,8c2.6,0,5.1,1,7.1,2.9\r
+ c0.4,0.4,0.9,0.6,1.4,0.6c0.5,0,1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8C19.2,5.4,15.6,4,12,4L12,4z"/>\r
+</g>\r
+</svg>\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- id="svg3039"
- version="1.1"
- inkscape:version="0.48.0 r9654"
- width="120"
- height="120"
- sodipodi:docname="inout3.svg"
- inkscape:export-filename="/home/orion/projects2/bitcoin/tx_mined.png"
- inkscape:export-xdpi="12"
- inkscape:export-ydpi="12"
- style="display:inline">
- <metadata
- id="metadata3045">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs3043" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1920"
- inkscape:window-height="1127"
- id="namedview3041"
- showgrid="false"
- inkscape:zoom="1"
- inkscape:cx="87.12655"
- inkscape:cy="67.287943"
- inkscape:window-x="0"
- inkscape:window-y="25"
- inkscape:window-maximized="1"
- inkscape:current-layer="layer7" />
- <g
- inkscape:groupmode="layer"
- id="layer2"
- inkscape:label="base"
- style="display:none">
- <path
- style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#afafaf;fill-opacity:1;stroke:none;stroke-width:7;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
- d="m 45.375,17 c -13.984022,0.241082 -24.968241,3.28976 -37.4375,9.59375 -8.9920665,21.871558 -6.680947,46.393002 -1.96875,69 26.190925,13.15317 55.594909,12.97748 81.75,-0.21875 3.852144,-9.729509 1.599587,-12.800015 2.375,-23.15625 C 83.917272,72.423868 77.129905,67.688094 74.1875,75.25 72.702487,79.722025 76.119709,82.645519 69.15625,83.34375 53.023957,88.536726 37.721719,89.140031 21.875,82.28125 19.715285,68.367979 18.599566,53.65725 22.5,40 c 16.868164,-6.642068 33.121079,-6.120062 50.03125,-0.15625 1.285344,5.854815 1.574746,5.763255 2.375,11.6875 C 80.46378,51.970623 89.644961,53.334736 91.3125,46 91.85305,36.007959 89.372312,31.625095 87.1875,25.6875 73.709743,21.03478 59.804255,16.698888 45.375,17 z"
- id="path3053"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccccccccc" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer3"
- inkscape:label="arrow_out"
- style="display:none">
- <path
- style="fill:#6e6e6e;fill-opacity:1;stroke:none;display:inline"
- d="m 63.983409,65.48134 0.267857,-9.514444 36.161424,-0.194173 -7.414458,-8.757971 3.798312,-7.572721 c 0,0 23.437946,20.796656 22.500436,21.185 -0.93751,0.388345 -23.170094,22.73838 -23.170094,22.73838 l -3.128654,-8.931927 7.548388,-8.5638 z"
- id="path3844"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccscccc" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer4"
- inkscape:label="arrow_in"
- style="display:none">
- <path
- inkscape:connector-curvature="0"
- id="path4080"
- d="m 99.28763,65.48134 -0.26786,-9.514444 -36.161422,-0.194173 7.768009,-6.283097 -4.151865,-9.279828 c 0,0 -23.43795,20.028889 -22.500436,20.417233 0.937514,0.388345 23.170094,20.970613 23.170094,20.970613 l 3.482207,-9.639034 -7.901936,-6.088926 z"
- style="fill:#6e6e6e;fill-opacity:1;stroke:none;display:inline"
- sodipodi:nodetypes="cccccscccc" />
- </g>
- <g
- inkscape:groupmode="layer"
- id="layer7"
- inkscape:label="mined"
- style="display:inline">
- <path
- style="fill:#a9a9a9;fill-opacity:1;stroke:none;display:inline"
- d="M 9.4375,99.758169 78.14665,33.110294 73.680556,28.300653 67.153187,8.375 l 18.55147,6.527369 4.80964,3.779003 4.809641,-4.80964 11.680552,12.367647 -6.18382,4.80964 13.74183,14.085377 -12.71119,14.42892 -14.77247,-16.14665 -65.273693,70.770424 z"
- id="path4103"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccccccccc" />
- <path
- sodipodi:nodetypes="cccccccccccccc"
- inkscape:connector-curvature="0"
- id="path4619"
- d="M 114.5625,99.758169 45.85335,33.110294 50.319444,28.300653 56.846813,8.375 l -18.55147,6.527369 -4.80964,3.779003 -4.809641,-4.80964 -11.680556,12.367647 6.183825,4.80964 L 9.4375,45.134396 22.148693,59.563316 36.92116,43.416666 102.19485,114.18709 z"
- style="fill:#a9a9a9;fill-opacity:1;stroke:none;display:inline" />
- <path
- style="fill:#6e6e6e;fill-opacity:1;stroke:none"
- d="M 10.960155,44.693128 38.53732,16.408856 54.093669,10.752002 48.436815,28.076118 22.273864,56.713943 z"
- id="path5256"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccc" />
- <path
- style="fill:#6e6e6e;fill-opacity:1;stroke:none"
- d="M 69.296465,10.398449 85.559921,17.115963 111.72287,45.046681 102.17693,56.713943 74.953319,27.722565 z"
- id="path5258"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccc" />
- </g>
-</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 841.9 595.3" enable-background="new 0 0 841.9 595.3" xml:space="preserve">\r
+<rect x="464" y="158.6" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 1027.5018 42.8013)" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="81.9" height="151.3"/>\r
+<rect x="190" y="342.1" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 882.9977 387.9771)" fill="none" stroke="#000000" stroke-width="30" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="342.3" height="69.4"/>\r
+<path stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M445.7,186l32.2-32.2\r
+ c-44.6-37.2-124-74.4-218.3-64.5l-2.5,9.9C361.4,114.1,403.6,153.8,445.7,186z"/>\r
+<path stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M552.4,292.7l32.2-32.2\r
+ c37.2,44.6,74.4,124,64.5,218.3l-9.9,2.5C624.3,377,584.6,332.4,552.4,292.7z"/>\r
+</svg>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 841.9 595.3" enable-background="new 0 0 841.9 595.3" xml:space="preserve">\r
+<g>\r
+ <path d="M182.8,310c0-74.4,0-148.8,0-220.7c0-19.8,5-39.7,19.8-54.6c12.4-12.4,27.3-17.4,44.6-19.8c37.2-5,74.4,2.5,109.1,7.4\r
+ C428.4,34.7,497.8,44.6,569.8,57c27.3,5,57,9.9,84.3,12.4c7.4,0,5,5,5,9.9c0,91.8,0,181.1,0,272.8c0,32.2,0,64.5,0,99.2\r
+ c0,14.9-5,29.8-12.4,44.6c-9.9,14.9-22.3,22.3-39.7,27.3c-69.4,12.4-138.9,22.3-208.3,34.7c-57,9.9-114.1,19.8-171.1,29.8\r
+ c-2.5,0-5,0-7.4-2.5c-12.4-14.9-22.3-24.8-32.2-34.7c-2.5-2.5-2.5-7.4-2.5-9.9c0-71.9,0-143.9,0-215.8\r
+ C182.8,320,182.8,315,182.8,310z M430.9,436.5c9.9-7.4,19.8-12.4,29.8-19.8c14.9-14.9,24.8-32.2,29.8-54.6\r
+ c12.4-54.6,14.9-111.6,0-166.2c-12.4-47.1-42.2-74.4-84.3-79.4c-37.2-2.5-67,7.4-86.8,39.7c-7.4,14.9-12.4,29.8-14.9,44.6\r
+ c-9.9,39.7-9.9,81.9-5,121.5c2.5,22.3,7.4,44.6,17.4,67c12.4,24.8,29.8,42.2,54.6,49.6c2.5,0,5,2.5,5,5c5,12.4,7.4,22.3,12.4,34.7\r
+ s17.4,19.8,32.2,22.3c14.9,2.5,27.3,2.5,42.2,0c2.5,0,2.5-2.5,2.5-2.5c0-9.9,0-22.3,0-32.2C438.3,461.3,433.3,456.4,430.9,436.5z\r
+ M505.3,191c0,12.4,0,22.3,0,34.7c0,2.5,2.5,2.5,5,2.5c5,0,7.4,0,12.4,0c0,2.5,0,5,0,9.9c0,44.6,0,86.8,0,131.5\r
+ c0,7.4,0,17.4,2.5,24.8c2.5,12.4,12.4,22.3,24.8,24.8c19.8,5,37.2-2.5,54.6-9.9l2.5-2.5c0-9.9,0-19.8,0-29.8\r
+ c-7.4,2.5-14.9,5-22.3,5s-12.4-2.5-14.9-9.9c0-5-2.5-9.9-2.5-14.9c0-39.7,0-79.4,0-119.1c0-2.5,0-5,0-7.4c9.9,0,19.8,0,29.8,2.5\r
+ c5,0,7.4-2.5,7.4-7.4c0-7.4,0-14.9,0-22.3c0-5-2.5-7.4-7.4-7.4c-7.4,0-14.9-2.5-22.3-2.5c-5,0-7.4-2.5-7.4-7.4\r
+ c0-14.9,0-29.8,0-42.2c0-5-2.5-5-5-7.4c-5,0-12.4,0-17.4-2.5s-7.4,0-9.9,7.4c-2.5,17.4-7.4,32.2-12.4,49.6\r
+ C520.2,191,512.7,191,505.3,191z"/>\r
+ <path d="M443.3,277.8c-2.5,27.3-5,57-9.9,84.3c0,7.4-5,17.4-9.9,24.8c-12.4,17.4-32.2,14.9-44.6-2.5c-9.9-14.9-12.4-32.2-14.9-49.6\r
+ c-5-42.2-5-81.9,0-124c5-12.4,7.4-24.8,14.9-37.2c12.4-17.4,34.7-17.4,47.1-2.5c2.5,5,7.4,9.9,7.4,14.9c2.5,9.9,5,19.8,7.4,32.2\r
+ c2.5,9.9,2.5,22.3,2.5,34.7C440.8,260.4,440.8,270.4,443.3,277.8L443.3,277.8z"/>\r
+</g>\r
+</svg>\r
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16px"
- height="16px"
- id="svg2993"
- version="1.1"
- inkscape:version="0.48.0 r9654"
- sodipodi:docname="questionmark.svg"
- inkscape:export-filename="/store/orion/projects/bitcoin/questionmark.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs2995">
- <linearGradient
- id="linearGradient3808">
- <stop
- style="stop-color:#c8c8c8;stop-opacity:1;"
- offset="0"
- id="stop3810" />
- <stop
- style="stop-color:#959595;stop-opacity:1"
- offset="1"
- id="stop3812" />
- </linearGradient>
- <filter
- inkscape:collect="always"
- id="filter3804"
- x="-0.2510722"
- width="1.5021444"
- y="-0.13164773"
- height="1.2632955">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.73280473"
- id="feGaussianBlur3806" />
- </filter>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3808"
- id="linearGradient3844"
- x1="8.4916801"
- y1="1.4395804"
- x2="8.6022711"
- y2="14.211697"
- gradientUnits="userSpaceOnUse" />
- <filter
- inkscape:collect="always"
- id="filter3889"
- x="-0.13954329"
- width="1.2790866"
- y="-0.073168421"
- height="1.1463368">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.40728516"
- id="feGaussianBlur3891" />
- </filter>
- <filter
- inkscape:collect="always"
- id="filter3897"
- x="-0.17178624"
- width="1.3435725"
- y="-0.090074761"
- height="1.1801495">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="0.50139271"
- id="feGaussianBlur3899" />
- </filter>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="1"
- inkscape:cx="10.789648"
- inkscape:cy="7.6382159"
- inkscape:current-layer="layer2"
- showgrid="true"
- inkscape:grid-bbox="true"
- inkscape:document-units="px"
- inkscape:window-width="1920"
- inkscape:window-height="1127"
- inkscape:window-x="0"
- inkscape:window-y="25"
- inkscape:window-maximized="1" />
- <metadata
- id="metadata2998">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:groupmode="layer"
- id="layer2"
- inkscape:label="Below"
- style="display:inline">
- <text
- sodipodi:linespacing="125%"
- id="text3006"
- y="14.748394"
- x="4.1060953"
- style="font-size:18px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;filter:url(#filter3897)"
- xml:space="preserve"><tspan
- y="14.748394"
- x="4.1060953"
- id="tspan3008"
- sodipodi:role="line">?</tspan></text>
- <text
- xml:space="preserve"
- style="font-size:18px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;filter:url(#filter3889)"
- x="4.1060953"
- y="14.748394"
- id="text3824"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan3826"
- x="4.1060953"
- y="14.748394">?</tspan></text>
- </g>
- <g
- id="layer1"
- inkscape:label="QuestionMark"
- inkscape:groupmode="layer"
- style="display:inline"
- sodipodi:insensitive="true">
- <text
- xml:space="preserve"
- style="font-size:18px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient3844);fill-opacity:1;stroke:none;font-family:Sans"
- x="4.1060953"
- y="14.748394"
- id="text3001"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan3003"
- x="4.1060953"
- y="14.748394"
- style="fill:url(#linearGradient3844);fill-opacity:1">?</tspan></text>
- </g>
-</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">\r
+<path d="M13,17.5c-2.5,0-4.5-2-4.5-4.5c0-0.6-0.4-1-1-1s-1,0.4-1,1c0,3.6,2.9,6.5,6.5,6.5s6.5-2.9,6.5-6.5S16.6,6.5,13,6.5\r
+ c-0.6,0-1,0.4-1,1s0.4,1,1,1c2.5,0,4.5,2,4.5,4.5S15.5,17.5,13,17.5z M3.7,10.3c-0.6,0-1-0.4-1-1s0.4-1,1-1H7L5.3,6.6L1.2,2.5\r
+ c-0.4-0.4-0.4-1,0-1.4c0.2-0.2,0.4-0.3,0.7-0.3s0.5,0.1,0.7,0.3l4.1,4.1l1.7,1.7V3.6c0-0.6,0.4-1,1-1s1,0.4,1,1v6.7L3.7,10.3"/>\r
+</svg>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">\r
+<path d="M14.7,19.5c-2.5,0-4.5-2-4.5-4.5c0-0.6-0.4-1-1-1c-0.6,0-1,0.4-1,1c0,3.6,2.9,6.5,6.5,6.5s6.5-2.9,6.5-6.5s-2.9-6.5-6.5-6.5\r
+ c-0.6,0-1,0.4-1,1s0.4,1,1,1c2.5,0,4.5,2,4.5,4.5S17.2,19.5,14.7,19.5z M5.9,12.5c-0.6,0-1-0.4-1-1s0.4-1,1-1h3.2L7.4,8.8L3.3,4.7\r
+ c-0.4-0.4-0.4-1,0-1.4C3.5,3.1,3.7,3,4,3s0.5,0.1,0.7,0.3l4.1,4.1l1.7,1.7V5.8c0-0.6,0.4-1,1-1s1,0.4,1,1v6.7L5.9,12.5 M7.5,0.8\r
+ c0.6,0,1,0.4,1,1s-0.4,1-1,1H4.3L6,4.5l4.1,4.1c0.4,0.4,0.4,1,0,1.4c-0.2,0.2-0.4,0.3-0.7,0.3S8.9,10.2,8.7,10L4.6,5.9L2.9,4.2v3.2\r
+ c0,0.6-0.4,1-1,1s-1-0.4-1-1V0.8L7.5,0.8"/>\r
+</svg>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+ viewBox="0 0 841.9 595.3" enable-background="new 0 0 841.9 595.3" xml:space="preserve">\r
+<path d="M654.1,317.5c-14.9-9.9-37.2-2.5-44.6,12.4l-62,111.6l-34.7-34.7c-12.4-12.4-34.7-12.4-47.1,0c-12.4,12.4-12.4,34.7,0,47.1\r
+ l67,67c7.4,7.4,14.9,9.9,22.3,9.9h5c9.9-2.5,19.8-7.4,24.8-17.4l81.9-148.8C676.4,347.2,671.5,327.4,654.1,317.5z"/>\r
+<path d="M326.7,471.3H177.9V362.1l94.3-94.3c-5-14.9-7.4-29.8-7.4-44.6c0-81.9,67-148.8,148.8-148.8s148.8,67,148.8,148.8\r
+ s-67,148.8-148.8,148.8h-37.2v49.6h-49.6L326.7,471.3L326.7,471.3z M227.5,421.7h49.6v-49.6h49.6v-49.6h86.8\r
+ c54.6,0,99.2-44.6,99.2-99.2S468.1,124,413.5,124s-99.2,44.6-99.2,99.2c0,14.9,2.5,27.3,9.9,39.7l7.4,14.9L230,379.5v42.2H227.5z\r
+ M413.5,198.4c14.9,0,24.8,9.9,24.8,24.8c0,14.9-9.9,24.8-24.8,24.8c-14.9,0-24.8-9.9-24.8-24.8\r
+ C388.7,208.3,401.1,198.4,413.5,198.4 M413.5,173.6c-27.3,0-49.6,22.3-49.6,49.6c0,27.3,22.3,49.6,49.6,49.6\r
+ c27.3,0,49.6-22.3,49.6-49.6C463.1,195.9,443.3,173.6,413.5,173.6z"/>\r
+</svg>\r
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "rpcconsole.h"
#include "clientmodel.h"
#include "guiutil.h"
#include "peertablemodel.h"
+#include "scicon.h"
#include "main.h"
#include "chainparams.h"
emit reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint));
}
- catch (json_spirit::Object& objError)
+ catch (const json_spirit::Object& objError)
{
try // Nice formatting for standard-format error
{
std::string message = find_value(objError, "message").get_str();
emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")");
}
- catch(std::runtime_error &) // raised when converting to invalid type, i.e. missing code or message
+ catch (const std::runtime_error&) // raised when converting to invalid type, i.e. missing code or message
{ // Show raw JSON object
emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false)));
}
}
- catch (std::exception& e)
+ catch (const std::exception& e)
{
emit reply(RPCConsole::CMD_ERROR, QString("Error: ") + QString::fromStdString(e.what()));
}
}
RPCConsole::RPCConsole(QWidget *parent) :
- QDialog(parent),
+ QWidget(parent),
ui(new Ui::RPCConsole),
clientModel(0),
historyPtr(0),
GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this);
#ifndef Q_OS_MAC
- ui->openDebugLogfileButton->setIcon(QIcon(":/icons/export"));
+ ui->openDebugLogfileButton->setIcon(SingleColorIcon(":/icons/export"));
#endif
+ ui->clearButton->setIcon(SingleColorIcon(":/icons/remove"));
// Install event filter for up and down arrow
ui->lineEdit->installEventFilter(this);
}
}
}
- return QDialog::eventFilter(obj, event);
+ return QWidget::eventFilter(obj, event);
}
void RPCConsole::setClientModel(ClientModel *model)
setNumConnections(model->getNumConnections());
connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
- setNumBlocks(model->getNumBlocks());
- connect(model, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
+ setNumBlocks(model->getNumBlocks(), model->getLastBlockDate());
+ connect(model, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent());
connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64)));
ui->messagesWidget->document()->addResource(
QTextDocument::ImageResource,
QUrl(ICON_MAPPING[i].url),
- QImage(ICON_MAPPING[i].source).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ SingleColorImage(ICON_MAPPING[i].source, SingleColor()).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
}
// Set default style sheet
"b { color: #006060; } "
);
- message(CMD_REPLY, (tr("Welcome to the Bitcoin RPC console.") + "<br>" +
+ message(CMD_REPLY, (tr("Welcome to the Bitcoin Core RPC console.") + "<br>" +
tr("Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.") + "<br>" +
tr("Type <b>help</b> for an overview of available commands.")), true);
}
-void RPCConsole::reject()
+void RPCConsole::keyPressEvent(QKeyEvent *event)
{
- // Ignore escape keypress if this is not a seperate window
- if(windowType() != Qt::Widget)
- QDialog::reject();
+ if(windowType() != Qt::Widget && event->key() == Qt::Key_Escape)
+ {
+ close();
+ }
}
void RPCConsole::message(int category, const QString &message, bool html)
ui->numberOfConnections->setText(connections);
}
-void RPCConsole::setNumBlocks(int count)
+void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate)
{
ui->numberOfBlocks->setText(QString::number(count));
- if(clientModel)
- ui->lastBlockTime->setText(clientModel->getLastBlockDate().toString());
+ ui->lastBlockTime->setText(blockDate.toString());
}
void RPCConsole::on_lineEdit_returnPressed()
ui->peerBytesRecv->setText(FormatBytes(stats->nodeStats.nRecvBytes));
ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nTimeConnected));
ui->peerPingTime->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingTime));
+ ui->timeoffset->setText(GUIUtil::formatTimeOffset(stats->nodeStats.nTimeOffset));
ui->peerVersion->setText(QString("%1").arg(stats->nodeStats.nVersion));
ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer));
ui->peerDirection->setText(stats->nodeStats.fInbound ? tr("Inbound") : tr("Outbound"));
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-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.
#ifndef BITCOIN_QT_RPCCONSOLE_H
#include "net.h"
-#include <QDialog>
+#include <QWidget>
class ClientModel;
QT_END_NAMESPACE
/** Local Bitcoin RPC console. */
-class RPCConsole: public QDialog
+class RPCConsole: public QWidget
{
Q_OBJECT
protected:
virtual bool eventFilter(QObject* obj, QEvent *event);
+ void keyPressEvent(QKeyEvent *);
private slots:
void on_lineEdit_returnPressed();
public slots:
void clear();
- void reject();
void message(int category, const QString &message, bool html = false);
/** Set number of connections shown in the UI */
void setNumConnections(int count);
- /** Set number of blocks shown in the UI */
- void setNumBlocks(int count);
+ /** Set number of blocks and last block date shown in the UI */
+ void setNumBlocks(int count, const QDateTime& blockDate);
/** Go forward or back in history */
void browseHistory(int offset);
/** Scroll console view to end */
--- /dev/null
+// Copyright (c) 2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "scicon.h"
+
+#include <QApplication>
+#include <QColor>
+#include <QIcon>
+#include <QImage>
+#include <QPalette>
+#include <QPixmap>
+
+static void MakeSingleColorImage(QImage& img, const QColor& colorbase)
+{
+ img = img.convertToFormat(QImage::Format_ARGB32);
+ for (int x = img.width(); x--; )
+ {
+ for (int y = img.height(); y--; )
+ {
+ const QRgb rgb = img.pixel(x, y);
+ img.setPixel(x, y, qRgba(colorbase.red(), colorbase.green(), colorbase.blue(), qAlpha(rgb)));
+ }
+ }
+}
+
+QImage SingleColorImage(const QString& filename, const QColor& colorbase)
+{
+ QImage img(filename);
+ MakeSingleColorImage(img, colorbase);
+ return img;
+}
+
+QIcon SingleColorIcon(const QIcon& ico, const QColor& colorbase)
+{
+ QIcon new_ico;
+ QSize sz;
+ Q_FOREACH(sz, ico.availableSizes())
+ {
+ QImage img(ico.pixmap(sz).toImage());
+ MakeSingleColorImage(img, colorbase);
+ new_ico.addPixmap(QPixmap::fromImage(img));
+ }
+ return new_ico;
+}
+
+QIcon SingleColorIcon(const QString& filename, const QColor& colorbase)
+{
+ return QIcon(QPixmap::fromImage(SingleColorImage(filename, colorbase)));
+}
+
+QColor SingleColor()
+{
+ const QColor colorHighlightBg(QApplication::palette().color(QPalette::Highlight));
+ const QColor colorHighlightFg(QApplication::palette().color(QPalette::HighlightedText));
+ const QColor colorText(QApplication::palette().color(QPalette::WindowText));
+ const int colorTextLightness = colorText.lightness();
+ QColor colorbase;
+ if (abs(colorHighlightBg.lightness() - colorTextLightness) < abs(colorHighlightFg.lightness() - colorTextLightness))
+ colorbase = colorHighlightBg;
+ else
+ colorbase = colorHighlightFg;
+ return colorbase;
+}
+
+QIcon SingleColorIcon(const QString& filename)
+{
+ return SingleColorIcon(filename, SingleColor());
+}
+
+static QColor TextColor()
+{
+ return QColor(QApplication::palette().color(QPalette::WindowText));
+}
+
+QIcon TextColorIcon(const QString& filename)
+{
+ return SingleColorIcon(filename, TextColor());
+}
+
+QIcon TextColorIcon(const QIcon& ico)
+{
+ return SingleColorIcon(ico, TextColor());
+}
--- /dev/null
+// Copyright (c) 2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_SCICON_H
+#define BITCOIN_QT_SCICON_H
+
+#include <QtCore>
+
+QT_BEGIN_NAMESPACE
+class QColor;
+class QIcon;
+class QString;
+QT_END_NAMESPACE
+
+QImage SingleColorImage(const QString& filename, const QColor&);
+QIcon SingleColorIcon(const QIcon&, const QColor&);
+QIcon SingleColorIcon(const QString& filename, const QColor&);
+QColor SingleColor();
+QIcon SingleColorIcon(const QString& filename);
+QIcon TextColorIcon(const QIcon&);
+QIcon TextColorIcon(const QString& filename);
+
+#endif // BITCOIN_QT_SCICON_H
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "sendcoinsdialog.h"
#include "coincontroldialog.h"
#include "guiutil.h"
#include "optionsmodel.h"
+#include "scicon.h"
#include "sendcoinsentry.h"
#include "walletmodel.h"
SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SendCoinsDialog),
- model(0)
+ clientModel(0),
+ model(0),
+ fNewRecipientAllowed(true),
+ fFeeMinimized(true)
{
ui->setupUi(this);
ui->addButton->setIcon(QIcon());
ui->clearButton->setIcon(QIcon());
ui->sendButton->setIcon(QIcon());
+#else
+ ui->addButton->setIcon(SingleColorIcon(":/icons/add"));
+ ui->clearButton->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->sendButton->setIcon(SingleColorIcon(":/icons/send"));
#endif
GUIUtil::setupAddressWidget(ui->lineEditCoinControlChange, this);
ui->checkBoxMinimumFee->setChecked(settings.value("fPayOnlyMinFee").toBool());
ui->checkBoxFreeTx->setChecked(settings.value("fSendFreeTransactions").toBool());
minimizeFeeSection(settings.value("fFeeSectionMinimized").toBool());
-
- fNewRecipientAllowed = true;
}
void SendCoinsDialog::setClientModel(ClientModel *clientModel)
{
this->clientModel = clientModel;
+
+ if (clientModel) {
+ connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(updateSmartFeeLabel()));
+ }
}
void SendCoinsDialog::setModel(WalletModel *model)
coinControlUpdateLabels();
// fee section
- connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(updateSmartFeeLabel()));
connect(ui->sliderSmartFee, SIGNAL(valueChanged(int)), this, SLOT(updateSmartFeeLabel()));
connect(ui->sliderSmartFee, SIGNAL(valueChanged(int)), this, SLOT(updateGlobalFeeVariables()));
connect(ui->sliderSmartFee, SIGNAL(valueChanged(int)), this, SLOT(coinControlUpdateLabels()));
return;
}
+ fNewRecipientAllowed = false;
+ WalletModel::UnlockContext ctx(model->requestUnlock());
+ if(!ctx.isValid())
+ {
+ // Unlock wallet was cancelled
+ fNewRecipientAllowed = true;
+ return;
+ }
+
+ // prepare transaction for getting txFee earlier
+ WalletModelTransaction currentTransaction(recipients);
+ WalletModel::SendCoinsReturn prepareStatus;
+ if (model->getOptionsModel()->getCoinControlFeatures()) // coin control enabled
+ prepareStatus = model->prepareTransaction(currentTransaction, CoinControlDialog::coinControl);
+ else
+ prepareStatus = model->prepareTransaction(currentTransaction);
+
+ // process prepareStatus and on error generate message shown to user
+ processSendCoinsReturn(prepareStatus,
+ BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee()));
+
+ if(prepareStatus.status != WalletModel::OK) {
+ fNewRecipientAllowed = true;
+ return;
+ }
+
+ CAmount txFee = currentTransaction.getTransactionFee();
+
// Format confirmation message
QStringList formatted;
- foreach(const SendCoinsRecipient &rcp, recipients)
+ foreach(const SendCoinsRecipient &rcp, currentTransaction.getRecipients())
{
// generate bold amount string
QString amount = "<b>" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
formatted.append(recipientElement);
}
- fNewRecipientAllowed = false;
-
-
- WalletModel::UnlockContext ctx(model->requestUnlock());
- if(!ctx.isValid())
- {
- // Unlock wallet was cancelled
- fNewRecipientAllowed = true;
- return;
- }
-
- // prepare transaction for getting txFee earlier
- WalletModelTransaction currentTransaction(recipients);
- WalletModel::SendCoinsReturn prepareStatus;
- if (model->getOptionsModel()->getCoinControlFeatures()) // coin control enabled
- prepareStatus = model->prepareTransaction(currentTransaction, CoinControlDialog::coinControl);
- else
- prepareStatus = model->prepareTransaction(currentTransaction);
-
- // process prepareStatus and on error generate message shown to user
- processSendCoinsReturn(prepareStatus,
- BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee()));
-
- if(prepareStatus.status != WalletModel::OK) {
- fNewRecipientAllowed = true;
- return;
- }
-
- CAmount txFee = currentTransaction.getTransactionFee();
QString questionString = tr("Are you sure you want to send?");
questionString.append("<br /><br />%1");
ui->entries->addWidget(entry);
connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*)));
connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels()));
+ connect(entry, SIGNAL(subtractFeeFromAmountChanged()), this, SLOT(coinControlUpdateLabels()));
updateTabsAndLabels();
return true;
}
-void SendCoinsDialog::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance,
+void SendCoinsDialog::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance,
const CAmount& watchBalance, const CAmount& watchUnconfirmedBalance, const CAmount& watchImmatureBalance)
{
Q_UNUSED(unconfirmedBalance);
msgParams.first = tr("The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
msgParams.second = CClientUIInterface::MSG_ERROR;
break;
- case WalletModel::InsaneFee:
- msgParams.first = tr("A fee higher than %1 is considered an insanely high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000));
+ case WalletModel::AbsurdFee:
+ msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), 10000000));
+ break;
+ case WalletModel::PaymentRequestExpired:
+ msgParams.first = tr("Payment request expired!");
+ msgParams.second = CClientUIInterface::MSG_ERROR;
break;
// included to prevent a compiler warning.
case WalletModel::OK:
{
ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB");
ui->labelSmartFee2->hide();
- ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %1 block(s).").arg(nBlocksToConfirm));
+ ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %n block(s).", "", nBlocksToConfirm));
}
updateFeeMinimizedLabel();
// Coin Control: copy label "Fee" to clipboard
void SendCoinsDialog::coinControlClipboardFee()
{
- GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
}
// Coin Control: copy label "After fee" to clipboard
void SendCoinsDialog::coinControlClipboardAfterFee()
{
- GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
}
// Coin Control: copy label "Bytes" to clipboard
void SendCoinsDialog::coinControlClipboardBytes()
{
- GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace(ASYMP_UTF8, ""));
}
// Coin Control: copy label "Priority" to clipboard
// Coin Control: copy label "Change" to clipboard
void SendCoinsDialog::coinControlClipboardChange()
{
- GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace("~", ""));
+ GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace(ASYMP_UTF8, ""));
}
// Coin Control: settings menu - coin control enabled/disabled by user
// set pay amounts
CoinControlDialog::payAmounts.clear();
+ CoinControlDialog::fSubtractFeeFromAmount = false;
for(int i = 0; i < ui->entries->count(); ++i)
{
SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
if(entry)
- CoinControlDialog::payAmounts.append(entry->getValue().amount);
+ {
+ SendCoinsRecipient rcp = entry->getValue();
+ CoinControlDialog::payAmounts.append(rcp.amount);
+ if (rcp.fSubtractFeeFromAmount)
+ CoinControlDialog::fSubtractFeeFromAmount = true;
+ }
}
if (CoinControlDialog::coinControl->HasSelected())
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_SENDCOINSDIALOG_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "sendcoinsentry.h"
#include "addresstablemodel.h"
#include "guiutil.h"
#include "optionsmodel.h"
+#include "scicon.h"
#include "walletmodel.h"
#include <QApplication>
{
ui->setupUi(this);
+ ui->addressBookButton->setIcon(SingleColorIcon(":/icons/address-book"));
+ ui->pasteButton->setIcon(SingleColorIcon(":/icons/editpaste"));
+ ui->deleteButton->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->deleteButton_is->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->deleteButton_s->setIcon(SingleColorIcon(":/icons/remove"));
+
setCurrentWidget(ui->SendCoins);
#ifdef Q_OS_MAC
// Connect signals
connect(ui->payAmount, SIGNAL(valueChanged()), this, SIGNAL(payAmountChanged()));
+ connect(ui->checkboxSubtractFeeFromAmount, SIGNAL(toggled(bool)), this, SIGNAL(subtractFeeFromAmountChanged()));
connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(deleteClicked()));
connect(ui->deleteButton_is, SIGNAL(clicked()), this, SLOT(deleteClicked()));
connect(ui->deleteButton_s, SIGNAL(clicked()), this, SLOT(deleteClicked()));
ui->payTo->clear();
ui->addAsLabel->clear();
ui->payAmount->clear();
+ ui->checkboxSubtractFeeFromAmount->setCheckState(Qt::Unchecked);
ui->messageTextLabel->clear();
ui->messageTextLabel->hide();
ui->messageLabel->hide();
recipient.label = ui->addAsLabel->text();
recipient.amount = ui->payAmount->value();
recipient.message = ui->messageTextLabel->text();
+ recipient.fSubtractFeeFromAmount = (ui->checkboxSubtractFeeFromAmount->checkState() == Qt::Checked);
return recipient;
}
QWidget::setTabOrder(prev, ui->payTo);
QWidget::setTabOrder(ui->payTo, ui->addAsLabel);
QWidget *w = ui->payAmount->setupTabChain(ui->addAsLabel);
- QWidget::setTabOrder(w, ui->addressBookButton);
+ QWidget::setTabOrder(w, ui->checkboxSubtractFeeFromAmount);
+ QWidget::setTabOrder(ui->checkboxSubtractFeeFromAmount, ui->addressBookButton);
QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton);
QWidget::setTabOrder(ui->pasteButton, ui->deleteButton);
return ui->deleteButton;
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_SENDCOINSENTRY_H
signals:
void removeEntry(SendCoinsEntry *entry);
void payAmountChanged();
+ void subtractFeeFromAmountChanged();
private slots:
void deleteClicked();
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "signverifymessagedialog.h"
#include "addressbookpage.h"
#include "guiutil.h"
+#include "scicon.h"
#include "walletmodel.h"
#include "base58.h"
{
ui->setupUi(this);
+ ui->addressBookButton_SM->setIcon(SingleColorIcon(":/icons/address-book"));
+ ui->pasteButton_SM->setIcon(SingleColorIcon(":/icons/editpaste"));
+ ui->copySignatureButton_SM->setIcon(SingleColorIcon(":/icons/editcopy"));
+ ui->signMessageButton_SM->setIcon(SingleColorIcon(":/icons/edit"));
+ ui->clearButton_SM->setIcon(SingleColorIcon(":/icons/remove"));
+ ui->addressBookButton_VM->setIcon(SingleColorIcon(":/icons/address-book"));
+ ui->verifyMessageButton_VM->setIcon(SingleColorIcon(":/icons/transaction_0"));
+ ui->clearButton_VM->setIcon(SingleColorIcon(":/icons/remove"));
+
#if QT_VERSION >= 0x040700
ui->signatureOut_SM->setPlaceholderText(tr("Click \"Sign Message\" to generate signature"));
#endif
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_SIGNVERIFYMESSAGEDIALOG_H
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "splashscreen.h"
#include <QCloseEvent>
#include <QDesktopWidget>
#include <QPainter>
+#include <QRadialGradient>
SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) :
QWidget(0, f), curAlignment(0)
int titleCopyrightVSpace = 40;
float fontFactor = 1.0;
+ float devicePixelRatio = 1.0;
+#if QT_VERSION > 0x050100
+ devicePixelRatio = ((QGuiApplication*)QCoreApplication::instance())->devicePixelRatio();
+#endif
// define text to place
QString titleText = tr("Bitcoin Core");
QString copyrightText = QChar(0xA9)+QString(" 2009-%1 ").arg(COPYRIGHT_YEAR) + QString(tr("The Bitcoin Core developers"));
QString titleAddText = networkStyle->getTitleAddText();
- QString font = "Arial";
+ QString font = QApplication::font().toString();
+
+ // create a bitmap according to device pixelratio
+ QSize splashSize(480*devicePixelRatio,320*devicePixelRatio);
+ pixmap = QPixmap(splashSize);
- // load the bitmap for writing some text over it
- pixmap = networkStyle->getSplashImage();
+#if QT_VERSION > 0x050100
+ // change to HiDPI if it makes sense
+ pixmap.setDevicePixelRatio(devicePixelRatio);
+#endif
QPainter pixPaint(&pixmap);
pixPaint.setPen(QColor(100,100,100));
+ // draw a slighly radial gradient
+ QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio);
+ gradient.setColorAt(0, Qt::white);
+ gradient.setColorAt(1, QColor(247,247,247));
+ QRect rGradient(QPoint(0,0), splashSize);
+ pixPaint.fillRect(rGradient, gradient);
+
+ // draw the bitcoin icon, expected size of PNG: 1024x1024
+ QRect rectIcon(QPoint(-150,-122), QSize(430,430));
+
+ const QSize requiredSize(1024,1024);
+ QPixmap icon(networkStyle->getAppIcon().pixmap(requiredSize));
+
+ pixPaint.drawPixmap(rectIcon, icon);
+
// check font size and drawing with
pixPaint.setFont(QFont(font, 33*fontFactor));
QFontMetrics fm = pixPaint.fontMetrics();
pixPaint.setFont(QFont(font, 33*fontFactor));
fm = pixPaint.fontMetrics();
titleTextWidth = fm.width(titleText);
- pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight,paddingTop,titleText);
+ pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop,titleText);
pixPaint.setFont(QFont(font, 15*fontFactor));
pixPaint.setFont(QFont(font, 10*fontFactor));
titleVersionVSpace -= 5;
}
- pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText);
+ pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText);
// draw copyright stuff
pixPaint.setFont(QFont(font, 10*fontFactor));
- pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight,paddingTop+titleCopyrightVSpace,copyrightText);
+ pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop+titleCopyrightVSpace,copyrightText);
// draw additional text if special network
if(!titleAddText.isEmpty()) {
pixPaint.setFont(boldFont);
fm = pixPaint.fontMetrics();
int titleAddTextWidth = fm.width(titleAddText);
- pixPaint.drawText(pixmap.width()-titleAddTextWidth-10,15,titleAddText);
+ pixPaint.drawText(pixmap.width()/devicePixelRatio-titleAddTextWidth-10,15,titleAddText);
}
pixPaint.end();
setWindowTitle(titleText + " " + titleAddText);
// Resize window and move to center of desktop, disallow resizing
- QRect r(QPoint(), pixmap.size());
+ QRect r(QPoint(), QSize(pixmap.size().width()/devicePixelRatio,pixmap.size().height()/devicePixelRatio));
resize(r.size());
setFixedSize(r.size());
move(QApplication::desktop()->screenGeometry().center() - r.center());
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-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.
#ifndef BITCOIN_QT_SPLASHSCREEN_H
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Data for paymentservertests.cpp
//
-// Base64/DER-encoded fake certificate authority certificate.
+// Base64/DER-encoded fake certificate authority certificates.
// Convert pem to base64/der with:
-// cat file.pem | openssl x509 -inform PEM -outform DER | openssl enc -base64
-//
+// openssl x509 -in cert.pem -inform PEM -outform DER | openssl enc -base64
+
// Serial Number: 10302349811211485352 (0x8ef94c91b112c0a8)
// Issuer: CN=PaymentRequest Test CA
// Subject: CN=PaymentRequest Test CA
// Not Valid After : Dec 8 16:37:24 2022 GMT
//
-const char* caCert_BASE64 =
+const char* caCert1_BASE64 =
"\
MIIB0DCCATmgAwIBAgIJAI75TJGxEsCoMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNV\
BAMTFlBheW1lbnRSZXF1ZXN0IFRlc3QgQ0EwHhcNMTIxMjEwMTYzNzI0WhcNMjIx\
p3waRjPD4bUX3nv+ojz5s4puw7Qq5QUZlhGsMzPvwDGCmZkL\
";
+// Serial Number: f0:da:97:e4:38:d7:64:16
+// Issuer: CN=PaymentRequest Test CA
+// Subject: CN=PaymentRequest Test CA
+// Not Valid After : Jan 8 18:21:06 2025 GMT
+//
+const char* caCert2_BASE64 =
+"\
+MIIC1TCCAb2gAwIBAgIJAPDal+Q412QWMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNV\
+BAMMFlBheW1lbnRSZXF1ZXN0IFRlc3QgQ0EwHhcNMTUwMTExMTgyMTA2WhcNMjUw\
+MTA4MTgyMTA2WjAhMR8wHQYDVQQDDBZQYXltZW50UmVxdWVzdCBUZXN0IENBMIIB\
+IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1S9wVLfTplJuT/1OaaBgl/Mb\
+I392v8S9kHbzYz7B4OTMslaO7piz0v3SO3TKMh0dswjiRdHrIgpO7XdIUQiU/ugg\
+xDw0kuNehfz1ycaGedlFFtFHTNXqLyIUF3dlwHhQwaomM6RXoJmxLny5BhYHEcmk\
+yWwr3Cdjd9gAZpblugVJB9C1e40uyL8ao4PHdLzOqO27iSe6riP8SwwisJZEbMaz\
+AZpgNEEMbIXPJEFvm5HTRXSMtQCOTSZYMFF0M2yrtmlECnz7hWP19b9bcoDzZQB4\
+ylIsFG/7q2jV7MC/e2STZv+niJiHL08RUdoFpAgzaxMgqj63C7B55HgNDNHJYQID\
+AQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBGejPxLxj9\
++crv6gUeEBMZPiUx7pUgcI22Wm5yymP96B4fwI3Y0DBehq20d76vbWGPN17Z6pH3\
+ge7PVY1SYqXtS6hXTo4olCm/BZADli+2Bs2xCiaa+Ltve4ufVej+bKJXN/YnrhvO\
+Kq+klQkuuHywU+GJV/NQeBqToIrSOBgi477NgLFCCCmmx2QWsxHoCFGfuRCBVseT\
+z2k/tMuALCDXGeZBRPTsGHu1y4cj84swAeoDK5QSQcI+Ub7GKc+zkoj02sdDLiMo\
+3wokYPcIy47oclhmb4xubHc+y7nF610yZBoC/zgbhbawnZ65hDDWkdQ/SVAnWZD7\
+9PFfmNnYPTQH\
+";
+
//
// This payment request validates directly against the
-// above certificate authority.
+// caCert1 certificate authority.
//
-const char* paymentrequest1_BASE64 =
+const char* paymentrequest1_cert1_BASE64 =
"\
Egt4NTA5K3NoYTI1NhrxAwruAzCCAeowggFToAMCAQICAQEwDQYJKoZIhvcNAQEL\
BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMjEyMTAx\
//
// Signed, but expired, merchant cert in the request
//
-const char* paymentrequest2_BASE64 =
+const char* paymentrequest2_cert1_BASE64 =
"\
Egt4NTA5K3NoYTI1NhrsAwrpAzCCAeUwggFOoAMCAQICAQMwDQYJKoZIhvcNAQEL\
BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMzAyMjMy\
";
//
-// 10-long chain, all intermediates valid
+// 10-long certificate chain, all intermediates valid
//
-const char* paymentrequest3_BASE64 =
+const char* paymentrequest3_cert1_BASE64 =
"\
Egt4NTA5K3NoYTI1Nhq8JAr/AzCCAfswggFkoAMCAQICAQEwDQYJKoZIhvcNAQEL\
BQAwPzEUMBIGA1UEAwwLdGVzdGNhOC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVx\
";
//
-// Long chain, with an invalid (expired) cert in the middle
+// Long certificate chain, with an expired certificate in the middle
//
-const char* paymentrequest4_BASE64 =
+const char* paymentrequest4_cert1_BASE64 =
"\
Egt4NTA5K3NoYTI1NhqeJAr/AzCCAfswggFkoAMCAQICAQEwDQYJKoZIhvcNAQEL\
BQAwPzEUMBIGA1UEAwwLdGVzdGNhOC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVx\
FAyZblLik9A7ZvF+UsjeFQiHB5wzWQvbqk5wQ4yabHIXoYv/E0q+eQ==\
";
-const char* paymentrequest5_BASE64 =
+//
+// Validly signed, but by a CA not in our root CA list
+//
+const char* paymentrequest5_cert1_BASE64 =
"\
Egt4NTA5K3NoYTI1NhrxAwruAzCCAeowggFToAMCAQICAQEwDQYJKoZIhvcNAQEL\
BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMzA0MTkx\
5/4wL4ClPRPVnOHgij0bEg+y0tGESqmF1rfOfXDszlo2U92wCxS07kq79YAZJ1Zo\
XYh860/Q4wvc7lfiTe+dXBzPKAKhMy91yETY\
";
+
+//
+// Contains a testnet paytoaddress, so payment request network doesn't match client network
+//
+const char* paymentrequest1_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iPQoEdGVzdBIhCIDWwowE\
+Ehl2qRQErGqUUwSsaMpDvWIaGnJGNQqi8oisGNeMy6UFKgxKdXN0IFRlc3Rpbmcq\
+gAFwThsozZxkZxzCn4R8WxNiLFV6m0ye9fEtSbolfaW+EjBMpO03lr/dwNnrclhg\
+ew+A05xfZztrAt16XKEY7qKJ/eY2nLd0fVAIu/nIt+7/VYVXT83zLrWc150aRS7W\
+AdJbL3JOJLs6Eyp5zrPbfI8faRttFAdONKDrJgIpuW1E3g==\
+";
+
+//
+// Expired payment request (expires is set to 1 = 1970-01-01 00:00:01)
+//
+const char* paymentrequest2_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iQgoEdGVzdBIgCICt4gQS\
+GXapFASsapRTBKxoykO9YhoackY1CqLyiKwYiNLUpQUgASoQVGVzdGluZyB0ZXN0\
+bmV0ISqAATXq9A5nmJgtmee/bQTeHeif4w1YYFPBlKghwx6qbVgXTWnwBJtOQhhV\
+sZdzbTl95ENR7/Y7VJupW9kDWobCK7zUUhLAzUlwmLlcx6itHw8LTUF5HK+AwsZm\
+Zs85lISGvOS0NZW/ENa6l+oQRnL87oqVZr/EDGiuqjz6T0ThQi0l\
+";
+
+//
+// Unexpired payment request (expires is set to 0x7FFFFFFFFFFFFFFF = max. int64_t)
+//
+const char* paymentrequest3_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iSgoEdGVzdBIgCICt4gQS\
+GXapFASsapRTBKxoykO9YhoackY1CqLyiKwYyNfZpQUg//////////9/KhBUZXN0\
+aW5nIHRlc3RuZXQhKoABNwi8WnMW4aMvbmvorTiiWJLFhofLFnsoWCJnj3rWLnLh\
+n3w6q/fZ26p50ERL/noxdTUfeFsKnlECkUu/fOcOrqyYDiwvxI0SZ034DleVyFU1\
+Z3T+X0zcL8oe7bX01Yf+s2V+5JXQXarKnKBrZCGgv2ARjFNSZe7E7vGg5K4Q6Q8=\
+";
+
+//
+// Unexpired payment request (expires is set to 0x8000000000000000 > max. int64_t, allowed uint64)
+//
+const char* paymentrequest4_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iSwoEdGVzdBIgCICt4gQS\
+GXapFASsapRTBKxoykO9YhoackY1CqLyiKwYt+HZpQUggICAgICAgICAASoQVGVz\
+dGluZyB0ZXN0bmV0ISqAAXSQG8+GFA18VaKarlYrOz293rNMIub0swKGcQm8jAGX\
+HSLaRgHfUDeEPr4hydy4dtfu59KNwe2xsHOHu/SpO4L8SrA4Dm9A7SlNBVWdcLbw\
+d2hj739GDLz0b5KuJ2SG6VknMRQM976w/m2qlq0ccVGaaZ2zMIGfpzL3p6adwx/5\
+";
+
+//
+// Payment request with amount overflow (amount is set to 21000001 BTC)
+//
+const char* paymentrequest5_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iTAoEdGVzdBIkCIDC9P+F\
+vt0DEhl2qRQErGqUUwSsaMpDvWIaGnJGNQqi8oisGLzcrKYFKhhUZXN0aW5nIGFt\
+b3VudCBvdmVyZmxvdyEqgAG8S7WEDUC6tCL6q2CTBjop/AitgEy31RL9IqYruytR\
+iEBFUrBDJZU+UEezGwr7/zoECjo5ZY3PmtZcM2sILNjyweJF6XVzGqTxUw6pN6sW\
+XR2T3Gy2LzRvhVA25QgGqpz0/juS2BtmNbsZPkN9gMMwKimgzc+PuCzmEKwPK9cQ\
+YQ==\
+";
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "optionsmodel.h"
#include "paymentrequestdata.h"
+#include "amount.h"
+#include "random.h"
+#include "script/script.h"
+#include "script/standard.h"
#include "util.h"
#include "utilstrencodings.h"
OptionsModel optionsModel;
PaymentServer* server = new PaymentServer(NULL, false);
X509_STORE* caStore = X509_STORE_new();
- X509_STORE_add_cert(caStore, parse_b64der_cert(caCert_BASE64));
+ X509_STORE_add_cert(caStore, parse_b64der_cert(caCert1_BASE64));
PaymentServer::LoadRootCAs(caStore);
server->setOptionsModel(&optionsModel);
server->uiReady();
- // Now feed PaymentRequests to server, and observe signals it produces:
- std::vector<unsigned char> data = DecodeBase64(paymentrequest1_BASE64);
- SendCoinsRecipient r = handleRequest(server, data);
+ std::vector<unsigned char> data;
+ SendCoinsRecipient r;
QString merchant;
+
+ // Now feed PaymentRequests to server, and observe signals it produces
+
+ // This payment request validates directly against the
+ // caCert1 certificate authority:
+ data = DecodeBase64(paymentrequest1_cert1_BASE64);
+ r = handleRequest(server, data);
r.paymentRequest.getMerchant(caStore, merchant);
QCOMPARE(merchant, QString("testmerchant.org"));
- // Version of the above, with an expired certificate:
- data = DecodeBase64(paymentrequest2_BASE64);
+ // Signed, but expired, merchant cert in the request:
+ data = DecodeBase64(paymentrequest2_cert1_BASE64);
r = handleRequest(server, data);
r.paymentRequest.getMerchant(caStore, merchant);
QCOMPARE(merchant, QString(""));
- // Long certificate chain:
- data = DecodeBase64(paymentrequest3_BASE64);
+ // 10-long certificate chain, all intermediates valid:
+ data = DecodeBase64(paymentrequest3_cert1_BASE64);
r = handleRequest(server, data);
r.paymentRequest.getMerchant(caStore, merchant);
QCOMPARE(merchant, QString("testmerchant8.org"));
// Long certificate chain, with an expired certificate in the middle:
- data = DecodeBase64(paymentrequest4_BASE64);
+ data = DecodeBase64(paymentrequest4_cert1_BASE64);
r = handleRequest(server, data);
r.paymentRequest.getMerchant(caStore, merchant);
QCOMPARE(merchant, QString(""));
// Validly signed, but by a CA not in our root CA list:
- data = DecodeBase64(paymentrequest5_BASE64);
+ data = DecodeBase64(paymentrequest5_cert1_BASE64);
r = handleRequest(server, data);
r.paymentRequest.getMerchant(caStore, merchant);
QCOMPARE(merchant, QString(""));
// Try again with no root CA's, verifiedMerchant should be empty:
caStore = X509_STORE_new();
PaymentServer::LoadRootCAs(caStore);
- data = DecodeBase64(paymentrequest1_BASE64);
+ data = DecodeBase64(paymentrequest1_cert1_BASE64);
r = handleRequest(server, data);
r.paymentRequest.getMerchant(caStore, merchant);
QCOMPARE(merchant, QString(""));
+ // Load second root certificate
+ caStore = X509_STORE_new();
+ X509_STORE_add_cert(caStore, parse_b64der_cert(caCert2_BASE64));
+ PaymentServer::LoadRootCAs(caStore);
+
+ QByteArray byteArray;
+
+ // For the tests below we just need the payment request data from
+ // paymentrequestdata.h parsed + stored in r.paymentRequest.
+ //
+ // These tests require us to bypass the following normal client execution flow
+ // shown below to be able to explicitly just trigger a certain condition!
+ //
+ // handleRequest()
+ // -> PaymentServer::eventFilter()
+ // -> PaymentServer::handleURIOrFile()
+ // -> PaymentServer::readPaymentRequestFromFile()
+ // -> PaymentServer::processPaymentRequest()
+
+ // Contains a testnet paytoaddress, so payment request network doesn't match client network:
+ data = DecodeBase64(paymentrequest1_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized, because network "main" is default, even for
+ // uninizialized payment requests and that will fail our test here.
+ QVERIFY(r.paymentRequest.IsInitialized());
+ QCOMPARE(PaymentServer::verifyNetwork(r.paymentRequest.getDetails()), false);
+
+ // Expired payment request (expires is set to 1 = 1970-01-01 00:00:01):
+ data = DecodeBase64(paymentrequest2_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // compares 1 < GetTime() == false (treated as expired payment request)
+ QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), true);
+
+ // Unexpired payment request (expires is set to 0x7FFFFFFFFFFFFFFF = max. int64_t):
+ // 9223372036854775807 (uint64), 9223372036854775807 (int64_t) and -1 (int32_t)
+ // -1 is 1969-12-31 23:59:59 (for a 32 bit time values)
+ data = DecodeBase64(paymentrequest3_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // compares 9223372036854775807 < GetTime() == false (treated as unexpired payment request)
+ QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), false);
+
+ // Unexpired payment request (expires is set to 0x8000000000000000 > max. int64_t, allowed uint64):
+ // 9223372036854775808 (uint64), -9223372036854775808 (int64_t) and 0 (int32_t)
+ // 0 is 1970-01-01 00:00:00 (for a 32 bit time values)
+ data = DecodeBase64(paymentrequest4_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // compares -9223372036854775808 < GetTime() == true (treated as expired payment request)
+ QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), true);
+
+ // Test BIP70 DoS protection:
+ unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1];
+ GetRandBytes(randData, sizeof(randData));
+ // Write data to a temp file:
+ QTemporaryFile tempFile;
+ tempFile.open();
+ tempFile.write((const char*)randData, sizeof(randData));
+ tempFile.close();
+ QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false);
+
+ // Payment request with amount overflow (amount is set to 21000001 BTC):
+ data = DecodeBase64(paymentrequest5_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // Extract address and amount from the request
+ QList<std::pair<CScript, CAmount> > sendingTos = r.paymentRequest.getPayTo();
+ foreach (const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) {
+ CTxDestination dest;
+ if (ExtractDestination(sendingTo.first, dest))
+ QCOMPARE(PaymentServer::verifyAmount(sendingTo.second), false);
+ }
+
delete server;
}
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "trafficgraphwidget.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_TRAFFICGRAPHWIDGET_H
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "transactiondesc.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_TRANSACTIONDESC_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "transactiondescdialog.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_TRANSACTIONDESCDIALOG_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "transactionfilterproxy.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_TRANSACTIONFILTERPROXY_H
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "transactionrecord.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_TRANSACTIONRECORD_H
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "transactiontablemodel.h"
#include "guiconstants.h"
#include "guiutil.h"
#include "optionsmodel.h"
+#include "scicon.h"
#include "transactiondesc.h"
#include "transactionrecord.h"
#include "walletmodel.h"
*/
void updateWallet(const uint256 &hash, int status, bool showTransaction)
{
- qDebug() << "TransactionTablePriv::updateWallet : " + QString::fromStdString(hash.ToString()) + " " + QString::number(status);
+ qDebug() << "TransactionTablePriv::updateWallet: " + QString::fromStdString(hash.ToString()) + " " + QString::number(status);
// Find bounds of this transaction in model
QList<TransactionRecord>::iterator lower = qLowerBound(
case CT_NEW:
if(inModel)
{
- qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model";
+ qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is already in model";
break;
}
if(showTransaction)
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
if(mi == wallet->mapWallet.end())
{
- qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet";
+ qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is not in wallet";
break;
}
// Added -- insert at the right position
case CT_DELETED:
if(!inModel)
{
- qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_DELETED, but transaction is not in model";
+ qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_DELETED, but transaction is not in model";
break;
}
// Removed -- remove entire transaction from table
switch(role)
{
- case Qt::DecorationRole:
+ case RawDecorationRole:
switch(index.column())
{
case Status:
return txAddressDecoration(rec);
}
break;
+ case Qt::DecorationRole:
+ {
+ QIcon icon = qvariant_cast<QIcon>(index.data(RawDecorationRole));
+ return TextColorIcon(icon);
+ }
case Qt::DisplayRole:
switch(index.column())
{
void invoke(QObject *ttm)
{
QString strHash = QString::fromStdString(hash.GetHex());
- qDebug() << "NotifyTransactionChanged : " + strHash + " status= " + QString::number(status);
+ qDebug() << "NotifyTransactionChanged: " + strHash + " status= " + QString::number(status);
QMetaObject::invokeMethod(ttm, "updateTransaction", Qt::QueuedConnection,
Q_ARG(QString, strHash),
Q_ARG(int, status),
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_TRANSACTIONTABLEMODEL_H
/** Formatted amount, without brackets when unconfirmed */
FormattedAmountRole,
/** Transaction status (TransactionRecord::Status) */
- StatusRole
+ StatusRole,
+ /** Unprocessed icon */
+ RawDecorationRole,
};
int rowCount(const QModelIndex &parent) const;
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "transactionview.h"
#include "editaddressdialog.h"
#include "guiutil.h"
#include "optionsmodel.h"
+#include "scicon.h"
#include "transactiondescdialog.h"
#include "transactionfilterproxy.h"
#include "transactionrecord.h"
watchOnlyWidget = new QComboBox(this);
watchOnlyWidget->setFixedWidth(24);
watchOnlyWidget->addItem("", TransactionFilterProxy::WatchOnlyFilter_All);
- watchOnlyWidget->addItem(QIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes);
- watchOnlyWidget->addItem(QIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No);
+ watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes);
+ watchOnlyWidget->addItem(SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No);
hlayout->addWidget(watchOnlyWidget);
dateWidget = new QComboBox(this);
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_TRANSACTIONVIEW_H
};
enum ColumnWidths {
- STATUS_COLUMN_WIDTH = 23,
+ STATUS_COLUMN_WIDTH = 30,
WATCHONLY_COLUMN_WIDTH = 23,
DATE_COLUMN_WIDTH = 120,
- TYPE_COLUMN_WIDTH = 120,
+ TYPE_COLUMN_WIDTH = 113,
AMOUNT_MINIMUM_COLUMN_WIDTH = 120,
MINIMUM_COLUMN_WIDTH = 23
};
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "utilitydialog.h"
#include "clientversion.h"
#include "init.h"
+#include "util.h"
#include <stdio.h>
#include <QCloseEvent>
#include <QLabel>
#include <QRegExp>
+#include <QTextTable>
+#include <QTextCursor>
#include <QVBoxLayout>
/** "Help message" or "About" dialog box */
ui(new Ui::HelpMessageDialog)
{
ui->setupUi(this);
- GUIUtil::restoreWindowGeometry("nHelpMessageDialogWindow", this->size(), this);
QString version = tr("Bitcoin Core") + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion());
/* On x86 add a bit specifier to the version so that users can distinguish between
// Replace newlines with HTML breaks
licenseInfoHTML.replace("\n\n", "<br><br>");
- ui->helpMessageLabel->setTextFormat(Qt::RichText);
+ ui->aboutMessage->setTextFormat(Qt::RichText);
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
text = version + "\n" + licenseInfo;
- ui->helpMessageLabel->setText(version + "<br><br>" + licenseInfoHTML);
- ui->helpMessageLabel->setWordWrap(true);
+ ui->aboutMessage->setText(version + "<br><br>" + licenseInfoHTML);
+ ui->aboutMessage->setWordWrap(true);
+ ui->helpMessage->setVisible(false);
} else {
setWindowTitle(tr("Command-line options"));
QString header = tr("Usage:") + "\n" +
" bitcoin-qt [" + tr("command-line options") + "] " + "\n";
+ QTextCursor cursor(ui->helpMessage->document());
+ cursor.insertText(version);
+ cursor.insertBlock();
+ cursor.insertText(header);
+ cursor.insertBlock();
QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT));
-
- QString uiOptions = tr("UI options") + ":\n" +
- " -choosedatadir " + tr("Choose data directory on startup (default: 0)") + "\n" +
- " -lang=<lang> " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
- " -min " + tr("Start minimized") + "\n" +
- " -rootcertificates=<file> " + tr("Set SSL root certificates for payment request (default: -system-)") + "\n" +
- " -splash " + tr("Show splash screen on startup (default: 1)");
-
- ui->helpMessageLabel->setFont(GUIUtil::bitcoinAddressFont());
- text = version + "\n" + header + "\n" + coreOptions + "\n" + uiOptions;
- ui->helpMessageLabel->setText(text);
+ text = version + "\n" + header + "\n" + coreOptions;
+
+ QTextTableFormat tf;
+ tf.setBorderStyle(QTextFrameFormat::BorderStyle_None);
+ tf.setCellPadding(2);
+ QVector<QTextLength> widths;
+ widths << QTextLength(QTextLength::PercentageLength, 35);
+ widths << QTextLength(QTextLength::PercentageLength, 65);
+ tf.setColumnWidthConstraints(widths);
+
+ QTextCharFormat bold;
+ bold.setFontWeight(QFont::Bold);
+
+ foreach (const QString &line, coreOptions.split("\n")) {
+ if (line.startsWith(" -"))
+ {
+ cursor.currentTable()->appendRows(1);
+ cursor.movePosition(QTextCursor::PreviousCell);
+ cursor.movePosition(QTextCursor::NextRow);
+ cursor.insertText(line.trimmed());
+ cursor.movePosition(QTextCursor::NextCell);
+ } else if (line.startsWith(" ")) {
+ cursor.insertText(line.trimmed()+' ');
+ } else if (line.size() > 0) {
+ //Title of a group
+ if (cursor.currentTable())
+ cursor.currentTable()->appendRows(1);
+ cursor.movePosition(QTextCursor::Down);
+ cursor.insertText(line.trimmed(), bold);
+ cursor.insertTable(1, 2, tf);
+ }
+ }
+
+ ui->helpMessage->moveCursor(QTextCursor::Start);
+ ui->scrollArea->setVisible(false);
+ ui->aboutLogo->setVisible(false);
}
}
HelpMessageDialog::~HelpMessageDialog()
{
- GUIUtil::saveWindowGeometry("nHelpMessageDialogWindow", this);
delete ui;
}
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-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.
#ifndef BITCOIN_QT_UTILITYDIALOG_H
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "walletframe.h"
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_WALLETFRAME_H
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "walletmodel.h"
#include "addresstablemodel.h"
#include "guiconstants.h"
+#include "guiutil.h"
+#include "paymentserver.h"
#include "recentrequeststablemodel.h"
#include "transactiontablemodel.h"
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl)
{
CAmount total = 0;
+ bool fSubtractFeeFromAmount = false;
QList<SendCoinsRecipient> recipients = transaction.getRecipients();
- std::vector<std::pair<CScript, CAmount> > vecSend;
+ std::vector<CRecipient> vecSend;
if(recipients.empty())
{
// Pre-check input data for validity
foreach(const SendCoinsRecipient &rcp, recipients)
{
+ if (rcp.fSubtractFeeFromAmount)
+ fSubtractFeeFromAmount = true;
+
if (rcp.paymentRequest.IsInitialized())
{ // PaymentRequest...
CAmount subtotal = 0;
subtotal += out.amount();
const unsigned char* scriptStr = (const unsigned char*)out.script().data();
CScript scriptPubKey(scriptStr, scriptStr+out.script().size());
- vecSend.push_back(std::pair<CScript, CAmount>(scriptPubKey, out.amount()));
+ CAmount nAmount = out.amount();
+ CRecipient recipient = {scriptPubKey, nAmount, rcp.fSubtractFeeFromAmount};
+ vecSend.push_back(recipient);
}
if (subtotal <= 0)
{
++nAddresses;
CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
- vecSend.push_back(std::pair<CScript, CAmount>(scriptPubKey, rcp.amount));
+ CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount};
+ vecSend.push_back(recipient);
total += rcp.amount;
}
LOCK2(cs_main, wallet->cs_wallet);
transaction.newPossibleKeyChange(wallet);
+
CAmount nFeeRequired = 0;
+ int nChangePosRet = -1;
std::string strFailReason;
CWalletTx *newTx = transaction.getTransaction();
CReserveKey *keyChange = transaction.getPossibleKeyChange();
- bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, strFailReason, coinControl);
+ bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
transaction.setTransactionFee(nFeeRequired);
+ if (fSubtractFeeFromAmount && fCreated)
+ transaction.reassignAmounts(nChangePosRet);
if(!fCreated)
{
- if((total + nFeeRequired) > nBalance)
+ if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance)
{
return SendCoinsReturn(AmountWithFeeExceedsBalance);
}
return TransactionCreationFailed;
}
- // reject insane fee > 0.1 bitcoin
+ // reject absurdly high fee > 0.1 bitcoin
if (nFeeRequired > 10000000)
- return InsaneFee;
+ return AbsurdFee;
}
return SendCoinsReturn(OK);
LOCK2(cs_main, wallet->cs_wallet);
CWalletTx *newTx = transaction.getTransaction();
- // Store PaymentRequests in wtx.vOrderForm in wallet.
foreach(const SendCoinsRecipient &rcp, transaction.getRecipients())
{
if (rcp.paymentRequest.IsInitialized())
{
+ // Make sure any payment requests involved are still valid.
+ if (PaymentServer::verifyExpired(rcp.paymentRequest.getDetails())) {
+ return PaymentRequestExpired;
+ }
+
+ // Store PaymentRequests in wtx.vOrderForm in wallet.
std::string key("PaymentRequest");
std::string value;
rcp.paymentRequest.SerializeToString(&value);
QString strLabel = QString::fromStdString(label);
QString strPurpose = QString::fromStdString(purpose);
- qDebug() << "NotifyAddressBookChanged : " + strAddress + " " + strLabel + " isMine=" + QString::number(isMine) + " purpose=" + strPurpose + " status=" + QString::number(status);
+ qDebug() << "NotifyAddressBookChanged: " + strAddress + " " + strLabel + " isMine=" + QString::number(isMine) + " purpose=" + strPurpose + " status=" + QString::number(status);
QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
Q_ARG(QString, strAddress),
Q_ARG(QString, strLabel),
-// Copyright (c) 2011-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-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.
#ifndef BITCOIN_QT_WALLETMODEL_H
class SendCoinsRecipient
{
public:
- explicit SendCoinsRecipient() : amount(0), nVersion(SendCoinsRecipient::CURRENT_VERSION) { }
+ explicit SendCoinsRecipient() : amount(0), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) { }
explicit SendCoinsRecipient(const QString &addr, const QString &label, const CAmount& amount, const QString &message):
- address(addr), label(label), amount(amount), message(message), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
+ address(addr), label(label), amount(amount), message(message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
- // If from an insecure payment request, this is used for storing
+ // If from an unauthenticated payment request, this is used for storing
// the addresses, e.g. address-A<br />address-B<br />address-C.
// Info: As we don't need to process addresses in here when using
// payment requests, we can abuse it for displaying an address list.
// Empty if no authentication or invalid signature/cert/etc.
QString authenticatedMerchant;
+ bool fSubtractFeeFromAmount; // memory only
+
static const int CURRENT_VERSION = 1;
int nVersion;
DuplicateAddress,
TransactionCreationFailed, // Error returned when wallet is still locked
TransactionCommitFailed,
- InsaneFee
+ AbsurdFee,
+ PaymentRequestExpired
};
enum EncryptionStatus
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "walletmodeltransaction.h"
fee = newFee;
}
+void WalletModelTransaction::reassignAmounts(int nChangePosRet)
+{
+ int i = 0;
+ for (QList<SendCoinsRecipient>::iterator it = recipients.begin(); it != recipients.end(); ++it)
+ {
+ SendCoinsRecipient& rcp = (*it);
+
+ if (rcp.paymentRequest.IsInitialized())
+ {
+ CAmount subtotal = 0;
+ const payments::PaymentDetails& details = rcp.paymentRequest.getDetails();
+ for (int j = 0; j < details.outputs_size(); j++)
+ {
+ const payments::Output& out = details.outputs(j);
+ if (out.amount() <= 0) continue;
+ if (i == nChangePosRet)
+ i++;
+ subtotal += walletTransaction->vout[i].nValue;
+ i++;
+ }
+ rcp.amount = subtotal;
+ }
+ else // normal recipient (no payment request)
+ {
+ if (i == nChangePosRet)
+ i++;
+ rcp.amount = walletTransaction->vout[i].nValue;
+ i++;
+ }
+ }
+}
+
CAmount WalletModelTransaction::getTotalTransactionAmount()
{
CAmount totalTransactionAmount = 0;
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_WALLETMODELTRANSACTION_H
void newPossibleKeyChange(CWallet *wallet);
CReserveKey *getPossibleKeyChange();
+ void reassignAmounts(int nChangePosRet); // needed for the subtract-fee-from-amount feature
+
private:
- const QList<SendCoinsRecipient> recipients;
+ QList<SendCoinsRecipient> recipients;
CWalletTx *walletTransaction;
CReserveKey *keyChange;
CAmount fee;
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "walletview.h"
#include "optionsmodel.h"
#include "overviewpage.h"
#include "receivecoinsdialog.h"
+#include "scicon.h"
#include "sendcoinsdialog.h"
#include "signverifymessagedialog.h"
#include "transactiontablemodel.h"
QPushButton *exportButton = new QPushButton(tr("&Export"), this);
exportButton->setToolTip(tr("Export the data in the current tab to a file"));
#ifndef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
- exportButton->setIcon(QIcon(":/icons/export"));
+ exportButton->setIcon(SingleColorIcon(":/icons/export"));
#endif
hbox_buttons->addStretch();
hbox_buttons->addWidget(exportButton);
-// Copyright (c) 2011-2013 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_QT_WALLETVIEW_H
-// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// 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.
#include "winshutdownmonitor.h"
-// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// 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.
#ifndef BITCOIN_QT_WINSHUTDOWNMONITOR_H
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "random.h"
+#include "support/cleanse.h"
#ifdef WIN32
#include "compat.h" // for Windows API
#endif
#include <sys/time.h>
#endif
-#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>
// Seed with CPU performance counter
int64_t nCounter = GetPerformanceCounter();
RAND_add(&nCounter, sizeof(nCounter), 1.5);
- OPENSSL_cleanse((void*)&nCounter, sizeof(nCounter));
+ memory_cleanse((void*)&nCounter, sizeof(nCounter));
}
void RandAddSeedPerfmon()
{
RandAddSeed();
+#ifdef WIN32
+ // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
+ // Seed with the entire set of perfmon data
+
// This can take up to 2 seconds, so only do it every 10 minutes
static int64_t nLastPerfmon;
if (GetTime() < nLastPerfmon + 10 * 60)
return;
nLastPerfmon = GetTime();
-#ifdef WIN32
- // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
- // Seed with the entire set of perfmon data
std::vector<unsigned char> vData(250000, 0);
long ret = 0;
unsigned long nSize = 0;
RegCloseKey(HKEY_PERFORMANCE_DATA);
if (ret == ERROR_SUCCESS) {
RAND_add(begin_ptr(vData), nSize, nSize / 100.0);
- OPENSSL_cleanse(begin_ptr(vData), nSize);
+ memory_cleanse(begin_ptr(vData), nSize);
LogPrint("rand", "%s: %lu bytes\n", __func__, nSize);
} else {
static bool warned = false; // Warn only once
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_RANDOM_H
/**
* Seed insecure_rand using the random pool.
- * @param Deterministic Use a determinstic seed
+ * @param Deterministic Use a deterministic seed
*/
void seed_insecure_rand(bool fDeterministic = false);
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "core/block.h"
-#include "core/transaction.h"
+#include "primitives/block.h"
+#include "primitives/transaction.h"
#include "main.h"
#include "rpcserver.h"
#include "streams.h"
using namespace json_spirit;
enum RetFormat {
+ RF_UNDEF,
RF_BINARY,
RF_HEX,
RF_JSON,
static const struct {
enum RetFormat rf;
- const char *name;
+ const char* name;
} rf_names[] = {
- { RF_BINARY, "binary" }, // default, if match not found
- { RF_HEX, "hex" },
- { RF_JSON, "json" },
+ {RF_UNDEF, ""},
+ {RF_BINARY, "bin"},
+ {RF_HEX, "hex"},
+ {RF_JSON, "json"},
};
-class RestErr {
+class RestErr
+{
public:
enum HTTPStatusCode status;
string message;
};
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry);
-extern Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex);
+extern Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false);
static RestErr RESTERR(enum HTTPStatusCode status, string message)
{
return re;
}
-static enum RetFormat ParseDataFormat(const string& format)
+static enum RetFormat ParseDataFormat(vector<string>& params, const string strReq)
{
- for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
- if (format == rf_names[i].name)
- return rf_names[i].rf;
+ boost::split(params, strReq, boost::is_any_of("."));
+ if (params.size() > 1) {
+ for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
+ if (params[1] == rf_names[i].name)
+ return rf_names[i].rf;
+ }
return rf_names[0].rf;
}
+static string AvailableDataFormatsString()
+{
+ string formats = "";
+ for (unsigned int i = 0; i < ARRAYLEN(rf_names); i++)
+ if (strlen(rf_names[i].name) > 0) {
+ formats.append(".");
+ formats.append(rf_names[i].name);
+ formats.append(", ");
+ }
+
+ if (formats.length() > 0)
+ return formats.substr(0, formats.length() - 2);
+
+ return formats;
+}
+
static bool ParseHashStr(const string& strReq, uint256& v)
{
if (!IsHex(strReq) || (strReq.size() != 64))
return true;
}
-static bool rest_block(AcceptedConnection *conn,
- string& strReq,
- map<string, string>& mapHeaders,
- bool fRun)
+static bool rest_headers(AcceptedConnection* conn,
+ const std::string& strReq,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
{
vector<string> params;
- boost::split(params, strReq, boost::is_any_of("/"));
+ const RetFormat rf = ParseDataFormat(params, strReq);
+ vector<string> path;
+ boost::split(path, params[0], boost::is_any_of("/"));
+
+ if (path.size() != 2)
+ throw RESTERR(HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers/<count>/<hash>.<ext>.");
+
+ long count = strtol(path[0].c_str(), NULL, 10);
+ if (count < 1 || count > 2000)
+ throw RESTERR(HTTP_BAD_REQUEST, "Header count out of range: " + path[0]);
+
+ string hashStr = path[1];
+ uint256 hash;
+ if (!ParseHashStr(hashStr, hash))
+ throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
+
+ std::vector<CBlockHeader> headers;
+ headers.reserve(count);
+ {
+ LOCK(cs_main);
+ BlockMap::const_iterator it = mapBlockIndex.find(hash);
+ const CBlockIndex *pindex = (it != mapBlockIndex.end()) ? it->second : NULL;
+ while (pindex != NULL && chainActive.Contains(pindex)) {
+ headers.push_back(pindex->GetBlockHeader());
+ if (headers.size() == (unsigned long)count)
+ break;
+ pindex = chainActive.Next(pindex);
+ }
+ }
+
+ CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION);
+ BOOST_FOREACH(const CBlockHeader &header, headers) {
+ ssHeader << header;
+ }
+
+ switch (rf) {
+ case RF_BINARY: {
+ string binaryHeader = ssHeader.str();
+ conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryHeader.size(), "application/octet-stream") << binaryHeader << std::flush;
+ return true;
+ }
+
+ case RF_HEX: {
+ string strHex = HexStr(ssHeader.begin(), ssHeader.end()) + "\n";
+ conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush;
+ return true;
+ }
+
+ default: {
+ throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: .bin, .hex)");
+ }
+ }
- enum RetFormat rf = ParseDataFormat(params.size() > 1 ? params[1] : string(""));
+ // not reached
+ return true; // continue to process further HTTP reqs on this cxn
+}
+
+static bool rest_block(AcceptedConnection* conn,
+ const std::string& strReq,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun,
+ bool showTxDetails)
+{
+ vector<string> params;
+ const RetFormat rf = ParseDataFormat(params, strReq);
string hashStr = params[0];
uint256 hash;
switch (rf) {
case RF_BINARY: {
string binaryBlock = ssBlock.str();
- conn->stream() << HTTPReply(HTTP_OK, binaryBlock, fRun, true, "application/octet-stream") << binaryBlock << std::flush;
+ conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryBlock.size(), "application/octet-stream") << binaryBlock << std::flush;
return true;
}
case RF_HEX: {
- string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n";;
+ string strHex = HexStr(ssBlock.begin(), ssBlock.end()) + "\n";
conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush;
return true;
}
case RF_JSON: {
- Object objBlock = blockToJSON(block, pblockindex);
+ Object objBlock = blockToJSON(block, pblockindex, showTxDetails);
string strJSON = write_string(Value(objBlock), false) + "\n";
conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
return true;
- }
+ }
+
+ default: {
+ throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
+ }
}
// not reached
- return true; // continue to process further HTTP reqs on this cxn
+ return true; // continue to process further HTTP reqs on this cxn
}
-static bool rest_tx(AcceptedConnection *conn,
- string& strReq,
- map<string, string>& mapHeaders,
- bool fRun)
+static bool rest_block_extended(AcceptedConnection* conn,
+ const std::string& strReq,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
+{
+ return rest_block(conn, strReq, mapHeaders, fRun, true);
+}
+
+static bool rest_block_notxdetails(AcceptedConnection* conn,
+ const std::string& strReq,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
+{
+ return rest_block(conn, strReq, mapHeaders, fRun, false);
+}
+
+static bool rest_chaininfo(AcceptedConnection* conn,
+ const std::string& strReq,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
{
vector<string> params;
- boost::split(params, strReq, boost::is_any_of("/"));
+ const RetFormat rf = ParseDataFormat(params, strReq);
+
+ switch (rf) {
+ case RF_JSON: {
+ Array rpcParams;
+ Value chainInfoObject = getblockchaininfo(rpcParams, false);
+
+ string strJSON = write_string(chainInfoObject, false) + "\n";
+ conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
+ return true;
+ }
+ default: {
+ throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)");
+ }
+ }
+
+ // not reached
+ return true; // continue to process further HTTP reqs on this cxn
+}
- enum RetFormat rf = ParseDataFormat(params.size() > 1 ? params[1] : string(""));
+static bool rest_tx(AcceptedConnection* conn,
+ const std::string& strReq,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
+{
+ vector<string> params;
+ const RetFormat rf = ParseDataFormat(params, strReq);
string hashStr = params[0];
uint256 hash;
throw RESTERR(HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
CTransaction tx;
- uint256 hashBlock = 0;
+ uint256 hashBlock = uint256();
if (!GetTransaction(hash, tx, hashBlock, true))
throw RESTERR(HTTP_NOT_FOUND, hashStr + " not found");
switch (rf) {
case RF_BINARY: {
string binaryTx = ssTx.str();
- conn->stream() << HTTPReply(HTTP_OK, binaryTx, fRun, true, "application/octet-stream") << binaryTx << std::flush;
+ conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, binaryTx.size(), "application/octet-stream") << binaryTx << std::flush;
return true;
}
case RF_HEX: {
- string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n";;
+ string strHex = HexStr(ssTx.begin(), ssTx.end()) + "\n";
conn->stream() << HTTPReply(HTTP_OK, strHex, fRun, false, "text/plain") << std::flush;
return true;
}
conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
return true;
}
+
+ default: {
+ throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
+ }
}
// not reached
- return true; // continue to process further HTTP reqs on this cxn
+ return true; // continue to process further HTTP reqs on this cxn
}
static const struct {
- const char *prefix;
- bool (*handler)(AcceptedConnection *conn,
- string& strURI,
- map<string, string>& mapHeaders,
+ const char* prefix;
+ bool (*handler)(AcceptedConnection* conn,
+ const std::string& strURI,
+ const std::map<std::string, std::string>& mapHeaders,
bool fRun);
} uri_prefixes[] = {
- { "/rest/tx/", rest_tx },
- { "/rest/block/", rest_block },
+ {"/rest/tx/", rest_tx},
+ {"/rest/block/notxdetails/", rest_block_notxdetails},
+ {"/rest/block/", rest_block_extended},
+ {"/rest/chaininfo", rest_chaininfo},
+ {"/rest/headers/", rest_headers},
};
-bool HTTPReq_REST(AcceptedConnection *conn,
- string& strURI,
- map<string, string>& mapHeaders,
+bool HTTPReq_REST(AcceptedConnection* conn,
+ const std::string& strURI,
+ const std::map<std::string, std::string>& mapHeaders,
bool fRun)
{
try {
+ std::string statusmessage;
+ if (RPCIsInWarmup(&statusmessage))
+ throw RESTERR(HTTP_SERVICE_UNAVAILABLE, "Service temporarily unavailable: " + statusmessage);
+
for (unsigned int i = 0; i < ARRAYLEN(uri_prefixes); i++) {
unsigned int plen = strlen(uri_prefixes[i].prefix);
if (strURI.substr(0, plen) == uri_prefixes[i].prefix) {
return uri_prefixes[i].handler(conn, strReq, mapHeaders, fRun);
}
}
- }
- catch (RestErr& re) {
+ } catch (const RestErr& re) {
conn->stream() << HTTPReply(re.status, re.message + "\r\n", false, false, "text/plain") << std::flush;
return false;
}
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
using namespace json_spirit;
using namespace std;
+extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry);
void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex);
double GetDifficulty(const CBlockIndex* blockindex)
}
-Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex)
+Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
{
Object result;
result.push_back(Pair("hash", block.GetHash().GetHex()));
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
Array txs;
BOOST_FOREACH(const CTransaction&tx, block.vtx)
- txs.push_back(tx.GetHash().GetHex());
+ {
+ if(txDetails)
+ {
+ Object objTx;
+ TxToJSON(tx, uint256(), objTx);
+ txs.push_back(objTx);
+ }
+ else
+ txs.push_back(tx.GetHash().GetHex());
+ }
result.push_back(Pair("tx", txs));
result.push_back(Pair("time", block.GetBlockTime()));
result.push_back(Pair("nonce", (uint64_t)block.nNonce));
+ HelpExampleRpc("getblockcount", "")
);
+ LOCK(cs_main);
return chainActive.Height();
}
+ HelpExampleRpc("getbestblockhash", "")
);
+ LOCK(cs_main);
return chainActive.Tip()->GetBlockHash().GetHex();
}
+ HelpExampleRpc("getdifficulty", "")
);
+ LOCK(cs_main);
return GetDifficulty();
}
+ HelpExampleRpc("getrawmempool", "true")
);
+ LOCK(cs_main);
+
bool fVerbose = false;
if (params.size() > 0)
fVerbose = params[0].get_bool();
+ HelpExampleRpc("getblockhash", "1000")
);
+ LOCK(cs_main);
+
int nHeight = params[0].get_int();
if (nHeight < 0 || nHeight > chainActive.Height())
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
+ HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
);
+ LOCK(cs_main);
+
std::string strHash = params[0].get_str();
- uint256 hash(strHash);
+ uint256 hash(uint256S(strHash));
bool fVerbose = true;
if (params.size() > 1)
+ HelpExampleRpc("gettxoutsetinfo", "")
);
+ LOCK(cs_main);
+
Object ret;
CCoinsStats stats;
- pcoinsTip->Flush();
+ FlushStateToDisk();
if (pcoinsTip->GetStats(stats)) {
ret.push_back(Pair("height", (int64_t)stats.nHeight));
ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
+ HelpExampleRpc("gettxout", "\"txid\", 1")
);
+ LOCK(cs_main);
+
Object ret;
std::string strHash = params[0].get_str();
- uint256 hash(strHash);
+ uint256 hash(uint256S(strHash));
int n = params[1].get_int();
bool fMempool = true;
if (params.size() > 2)
+ HelpExampleRpc("verifychain", "")
);
+ LOCK(cs_main);
+
int nCheckLevel = GetArg("-checklevel", 3);
int nCheckDepth = GetArg("-checkblocks", 288);
if (params.size() > 0)
+ HelpExampleRpc("getblockchaininfo", "")
);
+ LOCK(cs_main);
+
Object obj;
obj.push_back(Pair("chain", Params().NetworkIDString()));
obj.push_back(Pair("blocks", (int)chainActive.Height()));
" \"height\": xxxx, (numeric) height of the chain tip\n"
" \"hash\": \"xxxx\", (string) block hash of the tip\n"
" \"branchlen\": 0 (numeric) zero for main chain\n"
+ " \"status\": \"active\" (string) \"active\" for the main chain\n"
" },\n"
" {\n"
" \"height\": xxxx,\n"
" \"hash\": \"xxxx\",\n"
" \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
+ " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
" }\n"
"]\n"
+ "Possible values for status:\n"
+ "1. \"invalid\" This branch contains at least one invalid block\n"
+ "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
+ "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
+ "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
+ "5. \"active\" This is the tip of the active main chain, which is certainly valid\n"
"\nExamples:\n"
+ HelpExampleCli("getchaintips", "")
+ HelpExampleRpc("getchaintips", "")
);
+ LOCK(cs_main);
+
/* Build up a list of chain tips. We start with the list of all
known blocks, and successively remove blocks that appear as pprev
of another block. */
setTips.erase(pprev);
}
+ // Always report the currently active tip.
+ setTips.insert(chainActive.Tip());
+
/* Construct the output array. */
Array res;
BOOST_FOREACH(const CBlockIndex* block, setTips)
const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
obj.push_back(Pair("branchlen", branchLen));
+ string status;
+ if (chainActive.Contains(block)) {
+ // This block is part of the currently active chain.
+ status = "active";
+ } else if (block->nStatus & BLOCK_FAILED_MASK) {
+ // This block or one of its ancestors is invalid.
+ status = "invalid";
+ } else if (block->nChainTx == 0) {
+ // This block cannot be connected because full block data for it or one of its parents is missing.
+ status = "headers-only";
+ } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) {
+ // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized.
+ status = "valid-fork";
+ } else if (block->IsValid(BLOCK_VALID_TREE)) {
+ // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain.
+ status = "valid-headers";
+ } else {
+ // No clue.
+ status = "unknown";
+ }
+ obj.push_back(Pair("status", status));
+
res.push_back(obj);
}
return ret;
}
+Value invalidateblock(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "invalidateblock \"hash\"\n"
+ "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n"
+ "\nArguments:\n"
+ "1. hash (string, required) the hash of the block to mark as invalid\n"
+ "\nResult:\n"
+ "\nExamples:\n"
+ + HelpExampleCli("invalidateblock", "\"blockhash\"")
+ + HelpExampleRpc("invalidateblock", "\"blockhash\"")
+ );
+
+ std::string strHash = params[0].get_str();
+ uint256 hash(uint256S(strHash));
+ CValidationState state;
+
+ {
+ LOCK(cs_main);
+ if (mapBlockIndex.count(hash) == 0)
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
+
+ CBlockIndex* pblockindex = mapBlockIndex[hash];
+ InvalidateBlock(state, pblockindex);
+ }
+
+ if (state.IsValid()) {
+ ActivateBestChain(state);
+ }
+
+ if (!state.IsValid()) {
+ throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
+ }
+
+ return Value::null;
+}
+
+Value reconsiderblock(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "reconsiderblock \"hash\"\n"
+ "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n"
+ "This can be used to undo the effects of invalidateblock.\n"
+ "\nArguments:\n"
+ "1. hash (string, required) the hash of the block to reconsider\n"
+ "\nResult:\n"
+ "\nExamples:\n"
+ + HelpExampleCli("reconsiderblock", "\"blockhash\"")
+ + HelpExampleRpc("reconsiderblock", "\"blockhash\"")
+ );
+
+ std::string strHash = params[0].get_str();
+ uint256 hash(uint256S(strHash));
+ CValidationState state;
+
+ {
+ LOCK(cs_main);
+ if (mapBlockIndex.count(hash) == 0)
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
+
+ CBlockIndex* pblockindex = mapBlockIndex[hash];
+ ReconsiderBlock(state, pblockindex);
+ }
+
+ if (state.IsValid()) {
+ ActivateBestChain(state);
+ }
+
+ if (!state.IsValid()) {
+ throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
+ }
+
+ return Value::null;
+}
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
{ "getnetworkhashps", 0 },
{ "getnetworkhashps", 1 },
{ "sendtoaddress", 1 },
+ { "sendtoaddress", 4 },
{ "settxfee", 0 },
{ "getreceivedbyaddress", 1 },
{ "getreceivedbyaccount", 1 },
{ "listsinceblock", 2 },
{ "sendmany", 1 },
{ "sendmany", 2 },
+ { "sendmany", 4 },
{ "addmultisigaddress", 0 },
{ "addmultisigaddress", 1 },
{ "createmultisig", 0 },
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+ HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
EnsureWalletIsUnlocked();
string strSecret = params[0].get_str();
+ HelpExampleRpc("importaddress", "\"myaddress\", \"testing\", false")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
CScript script;
CBitcoinAddress address(params[0].get_str());
+ HelpExampleRpc("importwallet", "\"test\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
EnsureWalletIsUnlocked();
ifstream file;
+ HelpExampleRpc("dumpprivkey", "\"myaddress\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
EnsureWalletIsUnlocked();
string strAddress = params[0].get_str();
+ HelpExampleRpc("dumpwallet", "\"test\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
EnsureWalletIsUnlocked();
ofstream file;
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// If lookup is -1, then use blocks since last difficulty change.
if (lookup <= 0)
- lookup = pb->nHeight % 2016 + 1;
+ lookup = pb->nHeight % Params().DifficultyAdjustmentInterval() + 1;
// If lookup is larger than chain, then set it to chain length.
if (lookup > pb->nHeight)
if (minTime == maxTime)
return 0;
- uint256 workDiff = pb->nChainWork - pb0->nChainWork;
+ arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork;
int64_t timeDiff = maxTime - minTime;
return (int64_t)(workDiff.getdouble() / timeDiff);
+ HelpExampleRpc("getnetworkhashps", "")
);
+ LOCK(cs_main);
return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
}
+ HelpExampleRpc("getgenerate", "")
);
+ LOCK(cs_main);
return GetBoolArg("-gen", false);
}
return Value::null;
}
-
-Value gethashespersec(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "gethashespersec\n"
- "\nReturns a recent hashes per second performance measurement while generating.\n"
- "See the getgenerate and setgenerate calls to turn generation on and off.\n"
- "\nResult:\n"
- "n (numeric) The recent hashes per second when generation is on (will return 0 if generation is off)\n"
- "\nExamples:\n"
- + HelpExampleCli("gethashespersec", "")
- + HelpExampleRpc("gethashespersec", "")
- );
-
- if (GetTimeMillis() - nHPSTimerStart > 8000)
- return (int64_t)0;
- return (int64_t)dHashesPerSec;
-}
#endif
" \"errors\": \"...\" (string) Current errors\n"
" \"generate\": true|false (boolean) If the generation is on or off (see getgenerate or setgenerate calls)\n"
" \"genproclimit\": n (numeric) The processor limit for generation. -1 if no generation. (see getgenerate or setgenerate calls)\n"
- " \"hashespersec\": n (numeric) The hashes per second of the generation, or 0 if no generation.\n"
" \"pooledtx\": n (numeric) The size of the mem pool\n"
" \"testnet\": true|false (boolean) If using testnet or not\n"
" \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
+ HelpExampleRpc("getmininginfo", "")
);
+
+ LOCK(cs_main);
+
Object obj;
obj.push_back(Pair("blocks", (int)chainActive.Height()));
obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
obj.push_back(Pair("chain", Params().NetworkIDString()));
#ifdef ENABLE_WALLET
obj.push_back(Pair("generate", getgenerate(params, false)));
- obj.push_back(Pair("hashespersec", gethashespersec(params, false)));
#endif
return obj;
}
+// NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts
Value prioritisetransaction(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 3)
"2. priority delta (numeric, required) The priority to add or subtract.\n"
" The transaction selection algorithm considers the tx as it would have a higher priority.\n"
" (priority of a transaction is calculated: coinage * value_in_satoshis / txsize) \n"
- "3. fee delta (numeric, required) The absolute fee value to add or subtract in bitcoin.\n"
+ "3. fee delta (numeric, required) The fee value (in satoshis) to add (or subtract, if negative).\n"
" The fee is not actually paid, only the algorithm for selecting transactions into a block\n"
" considers the transaction as it would have paid a higher (or lower) fee.\n"
"\nResult\n"
"true (boolean) Returns true\n"
"\nExamples:\n"
- + HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 0.00010000")
- + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 0.00010000")
+ + HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000")
+ + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")
);
- uint256 hash;
- hash.SetHex(params[0].get_str());
+ LOCK(cs_main);
- CAmount nAmount = 0;
- if (params[2].get_real() != 0.0)
- nAmount = AmountFromValue(params[2]);
+ uint256 hash = ParseHashStr(params[0].get_str(), "txid");
+ CAmount nAmount = params[2].get_int64();
mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), nAmount);
return true;
+ HelpExampleRpc("getblocktemplate", "")
);
+ LOCK(cs_main);
+
std::string strMode = "template";
Value lpval = Value::null;
if (params.size() > 0)
}
// Release the wallet and main lock while waiting
-#ifdef ENABLE_WALLET
- if(pwalletMain)
- LEAVE_CRITICAL_SECTION(pwalletMain->cs_wallet);
-#endif
LEAVE_CRITICAL_SECTION(cs_main);
{
checktxtime = boost::get_system_time() + boost::posix_time::minutes(1);
}
}
ENTER_CRITICAL_SECTION(cs_main);
-#ifdef ENABLE_WALLET
- if(pwalletMain)
- ENTER_CRITICAL_SECTION(pwalletMain->cs_wallet);
-#endif
if (!IsRPCRunning())
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
Object aux;
aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
- uint256 hashTarget = uint256().SetCompact(pblock->nBits);
+ arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
static Array aMutable;
if (aMutable.empty())
throw runtime_error(
"estimatefee nblocks\n"
"\nEstimates the approximate fee per kilobyte\n"
- "needed for a transaction to get confirmed\n"
+ "needed for a transaction to begin confirmation\n"
"within nblocks blocks.\n"
"\nArguments:\n"
"1. nblocks (numeric)\n"
throw runtime_error(
"estimatepriority nblocks\n"
"\nEstimates the approximate priority\n"
- "a zero-fee transaction needs to get confirmed\n"
+ "a zero-fee transaction needs to begin confirmation\n"
"within nblocks blocks.\n"
"\nArguments:\n"
"1. nblocks (numeric)\n"
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "json/json_spirit_utils.h"
#include "json/json_spirit_value.h"
-using namespace boost;
-using namespace boost::assign;
using namespace json_spirit;
using namespace std;
+ HelpExampleRpc("getinfo", "")
);
+#ifdef ENABLE_WALLET
+ LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
+#else
+ LOCK(cs_main);
+#endif
+
proxyType proxy;
GetProxy(NET_IPV4, proxy);
"{\n"
" \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n"
" \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n"
+ " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n"
" \"ismine\" : true|false, (boolean) If the address is yours or not\n"
" \"isscript\" : true|false, (boolean) If the key is a script\n"
" \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
" \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
- " \"account\" : \"account\" (string) The account associated with the address, \"\" is the default account\n"
+ " \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
+ HelpExampleRpc("validateaddress", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"")
);
+#ifdef ENABLE_WALLET
+ LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
+#else
+ LOCK(cs_main);
+#endif
+
CBitcoinAddress address(params[0].get_str());
bool isValid = address.IsValid();
CTxDestination dest = address.Get();
string currentAddress = address.ToString();
ret.push_back(Pair("address", currentAddress));
+
+ CScript scriptPubKey = GetScriptForDestination(dest);
+ ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
+
#ifdef ENABLE_WALLET
isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
throw runtime_error(
strprintf("not enough keys supplied "
"(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
+ if (keys.size() > 16)
+ throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
std::vector<CPubKey> pubkeys;
pubkeys.resize(keys.size());
for (unsigned int i = 0; i < keys.size(); i++)
+ HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"")
);
+ LOCK(cs_main);
+
string strAddress = params[0].get_str();
string strSign = params[1].get_str();
string strMessage = params[2].get_str();
if (!Params().MineBlocksOnDemand())
throw runtime_error("setmocktime for regression testing (-regtest mode) only");
+ LOCK(cs_main);
+
RPCTypeCheck(params, boost::assign::list_of(int_type));
SetMockTime(params[0].get_int64());
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+ HelpExampleRpc("getconnectioncount", "")
);
- LOCK(cs_vNodes);
+ LOCK2(cs_main, cs_vNodes);
+
return (int)vNodes.size();
}
);
// Request that each node send a ping during next message processing pass
- LOCK(cs_vNodes);
+ LOCK2(cs_main, cs_vNodes);
+
BOOST_FOREACH(CNode* pNode, vNodes) {
pNode->fPingQueued = true;
}
" \"bytessent\": n, (numeric) The total bytes sent\n"
" \"bytesrecv\": n, (numeric) The total bytes received\n"
" \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
+ " \"timeoffset\": ttt, (numeric) The time offset in seconds\n"
" \"pingtime\": n, (numeric) ping time\n"
" \"pingwait\": n, (numeric) ping wait\n"
" \"version\": v, (numeric) The peer version, such as 7001\n"
+ HelpExampleRpc("getpeerinfo", "")
);
+ LOCK(cs_main);
+
vector<CNodeStats> vstats;
CopyNodeStats(vstats);
obj.push_back(Pair("bytessent", stats.nSendBytes));
obj.push_back(Pair("bytesrecv", stats.nRecvBytes));
obj.push_back(Pair("conntime", stats.nTimeConnected));
+ obj.push_back(Pair("timeoffset", stats.nTimeOffset));
obj.push_back(Pair("pingtime", stats.dPingTime));
if (stats.dPingWait > 0.0)
obj.push_back(Pair("pingwait", stats.dPingWait));
+ HelpExampleRpc("getnetworkinfo", "")
);
+ LOCK(cs_main);
+
Object obj;
obj.push_back(Pair("version", CLIENT_VERSION));
obj.push_back(Pair("subversion",
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "json/json_spirit_writer_template.h"
using namespace std;
-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
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
HTTP_FORBIDDEN = 403,
HTTP_NOT_FOUND = 404,
HTTP_INTERNAL_SERVER_ERROR = 500,
+ HTTP_SERVICE_UNAVAILABLE = 503,
};
//! Bitcoin RPC error codes
tcp::resolver::query query(server.c_str(), port.c_str());
endpoint_iterator = resolver.resolve(query);
#if BOOST_VERSION >= 104300
- } catch(boost::system::system_error &e)
- {
+ } catch (const boost::system::system_error&) {
// If we at first don't succeed, try blanket lookup (IPv4+IPv6 independent of configured interfaces)
tcp::resolver::query query(server.c_str(), port.c_str(), resolver_query_base::flags());
endpoint_iterator = resolver.resolve(query);
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "base58.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "core_io.h"
#include "init.h"
#include "keystore.h"
#include "json/json_spirit_utils.h"
#include "json/json_spirit_value.h"
-using namespace boost;
-using namespace boost::assign;
using namespace json_spirit;
using namespace std;
}
entry.push_back(Pair("vout", vout));
- if (hashBlock != 0) {
+ if (!hashBlock.IsNull()) {
entry.push_back(Pair("blockhash", hashBlock.GetHex()));
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
if (mi != mapBlockIndex.end() && (*mi).second) {
+ HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
);
+ LOCK(cs_main);
+
uint256 hash = ParseHashV(params[0], "parameter 1");
bool fVerbose = false;
fVerbose = (params[1].get_int() != 0);
CTransaction tx;
- uint256 hashBlock = 0;
+ uint256 hashBlock;
if (!GetTransaction(hash, tx, hashBlock, true))
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
" \"txid\" : \"txid\", (string) the transaction id \n"
" \"vout\" : n, (numeric) the vout value\n"
" \"address\" : \"address\", (string) the bitcoin address\n"
- " \"account\" : \"account\", (string) The associated account, or \"\" for the default account\n"
+ " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
" \"scriptPubKey\" : \"key\", (string) the script key\n"
" \"amount\" : x.xxx, (numeric) the transaction amount in btc\n"
" \"confirmations\" : n (numeric) The number of confirmations\n"
+ HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
);
- RPCTypeCheck(params, list_of(int_type)(int_type)(array_type));
+ RPCTypeCheck(params, boost::assign::list_of(int_type)(int_type)(array_type));
int nMinDepth = 1;
if (params.size() > 0)
Array results;
vector<COutput> vecOutputs;
assert(pwalletMain != NULL);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
pwalletMain->AvailableCoins(vecOutputs, false);
BOOST_FOREACH(const COutput& out, vecOutputs) {
if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth)
+ HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"address\\\":0.01}\"")
);
- RPCTypeCheck(params, list_of(array_type)(obj_type));
+ LOCK(cs_main);
+ RPCTypeCheck(params, boost::assign::list_of(array_type)(obj_type));
Array inputs = params[0].get_array();
Object sendTo = params[1].get_obj();
+ HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
);
- RPCTypeCheck(params, list_of(str_type));
+ LOCK(cs_main);
+ RPCTypeCheck(params, boost::assign::list_of(str_type));
CTransaction tx;
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
Object result;
- TxToJSON(tx, 0, result);
+ TxToJSON(tx, uint256(), result);
return result;
}
+ HelpExampleRpc("decodescript", "\"hexstring\"")
);
- RPCTypeCheck(params, list_of(str_type));
+ LOCK(cs_main);
+ RPCTypeCheck(params, boost::assign::list_of(str_type));
Object r;
CScript script;
+ HelpExampleRpc("signrawtransaction", "\"myhex\"")
);
- RPCTypeCheck(params, list_of(str_type)(array_type)(array_type)(str_type), true);
+#ifdef ENABLE_WALLET
+ LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL);
+#else
+ LOCK(cs_main);
+#endif
+ RPCTypeCheck(params, boost::assign::list_of(str_type)(array_type)(array_type)(str_type), true);
vector<unsigned char> txData(ParseHexV(params[0], "argument 1"));
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
ssData >> tx;
txVariants.push_back(tx);
}
- catch (const std::exception &) {
+ catch (const std::exception&) {
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
}
}
if (!fGood)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
CKey key = vchSecret.GetKey();
+ if (!key.IsValid())
+ throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range");
tempKeystore.AddKey(key);
}
}
#ifdef ENABLE_WALLET
- else
+ else if (pwalletMain)
EnsureWalletIsUnlocked();
#endif
Object prevOut = p.get_obj();
- RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type));
+ RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type));
uint256 txid = ParseHashO(prevOut, "txid");
// if redeemScript given and not using the local wallet (private keys
// given), add redeemScript to the tempKeystore so it can be signed:
if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) {
- RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type));
+ RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type));
Value v = find_value(prevOut, "redeemScript");
if (!(v == Value::null)) {
vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
}
- if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i)))
+ if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i)))
fComplete = false;
}
+ HelpExampleRpc("sendrawtransaction", "\"signedhex\"")
);
- RPCTypeCheck(params, list_of(str_type)(bool_type));
+ LOCK(cs_main);
+ RPCTypeCheck(params, boost::assign::list_of(str_type)(bool_type));
// parse hex string from parameter
CTransaction tx;
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "base58.h"
#include "init.h"
-#include "main.h"
+#include "random.h"
+#include "sync.h"
#include "ui_interface.h"
#include "util.h"
+#include "utilstrencodings.h"
#ifdef ENABLE_WALLET
#include "wallet.h"
#endif
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/shared_ptr.hpp>
+#include <boost/signals2/signal.hpp>
#include <boost/thread.hpp>
#include "json/json_spirit_writer_template.h"
-using namespace boost;
using namespace boost::asio;
using namespace json_spirit;
+using namespace RPCServer;
using namespace std;
static std::string strRPCUserColonPass;
static CCriticalSection cs_rpcWarmup;
//! These are created by StartRPCThreads, destroyed in StopRPCThreads
-static asio::io_service* rpc_io_service = NULL;
+static boost::asio::io_service* rpc_io_service = NULL;
static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers;
static ssl::context* rpc_ssl_context = NULL;
static boost::thread_group* rpc_worker_group = NULL;
static std::vector<CSubNet> rpc_allow_subnets; //!< List of subnets to allow RPC connections from
static std::vector< boost::shared_ptr<ip::tcp::acceptor> > rpc_acceptors;
+static struct CRPCSignals
+{
+ boost::signals2::signal<void ()> Started;
+ boost::signals2::signal<void ()> Stopped;
+ boost::signals2::signal<void (const CRPCCommand&)> PreCommand;
+ boost::signals2::signal<void (const CRPCCommand&)> PostCommand;
+} g_rpcSignals;
+
+void RPCServer::OnStarted(boost::function<void ()> slot)
+{
+ g_rpcSignals.Started.connect(slot);
+}
+
+void RPCServer::OnStopped(boost::function<void ()> slot)
+{
+ g_rpcSignals.Stopped.connect(slot);
+}
+
+void RPCServer::OnPreCommand(boost::function<void (const CRPCCommand&)> slot)
+{
+ g_rpcSignals.PreCommand.connect(boost::bind(slot, _1));
+}
+
+void RPCServer::OnPostCommand(boost::function<void (const CRPCCommand&)> slot)
+{
+ g_rpcSignals.PostCommand.connect(boost::bind(slot, _1));
+}
+
void RPCTypeCheck(const Array& params,
const list<Value_type>& typesExpected,
bool fAllowNull)
// We already filter duplicates, but these deprecated screw up the sort order
if (strMethod.find("label") != string::npos)
continue;
- if (strCommand != "" && strMethod != strCommand)
+ if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand)
continue;
#ifdef ENABLE_WALLET
if (pcmd->reqWallet && !pwalletMain)
if (setDone.insert(pfn).second)
(*pfn)(params, true);
}
- catch (std::exception& e)
+ catch (const std::exception& e)
{
// Help text is returned in an exception
string strHelp = string(e.what());
* Call Table
*/
static const CRPCCommand vRPCCommands[] =
-{ // category name actor (function) okSafeMode threadSafe reqWallet
- // --------------------- ------------------------ ----------------------- ---------- ---------- ---------
+{ // category name actor (function) okSafeMode reqWallet
+ // --------------------- ------------------------ ----------------------- ---------- ---------
/* Overall control/query calls */
- { "control", "getinfo", &getinfo, true, false, false }, /* uses wallet if enabled */
- { "control", "help", &help, true, true, false },
- { "control", "stop", &stop, true, true, false },
- { "control", "setmocktime", &setmocktime, true, false, false },
+ { "control", "getinfo", &getinfo, true, false }, /* uses wallet if enabled */
+ { "control", "help", &help, true, false },
+ { "control", "stop", &stop, true, false },
/* P2P networking */
- { "network", "getnetworkinfo", &getnetworkinfo, true, false, false },
- { "network", "addnode", &addnode, true, true, false },
- { "network", "getaddednodeinfo", &getaddednodeinfo, true, true, false },
- { "network", "getconnectioncount", &getconnectioncount, true, false, false },
- { "network", "getnettotals", &getnettotals, true, true, false },
- { "network", "getpeerinfo", &getpeerinfo, true, false, false },
- { "network", "ping", &ping, true, false, false },
+ { "network", "getnetworkinfo", &getnetworkinfo, true, false },
+ { "network", "addnode", &addnode, true, false },
+ { "network", "getaddednodeinfo", &getaddednodeinfo, true, false },
+ { "network", "getconnectioncount", &getconnectioncount, true, false },
+ { "network", "getnettotals", &getnettotals, true, false },
+ { "network", "getpeerinfo", &getpeerinfo, true, false },
+ { "network", "ping", &ping, true, false },
/* Block chain and UTXO */
- { "blockchain", "getblockchaininfo", &getblockchaininfo, true, false, false },
- { "blockchain", "getbestblockhash", &getbestblockhash, true, false, false },
- { "blockchain", "getblockcount", &getblockcount, true, false, false },
- { "blockchain", "getblock", &getblock, true, false, false },
- { "blockchain", "getblockhash", &getblockhash, true, false, false },
- { "blockchain", "getchaintips", &getchaintips, true, false, false },
- { "blockchain", "getdifficulty", &getdifficulty, true, false, false },
- { "blockchain", "getmempoolinfo", &getmempoolinfo, true, true, false },
- { "blockchain", "getrawmempool", &getrawmempool, true, false, false },
- { "blockchain", "gettxout", &gettxout, true, false, false },
- { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, false, false },
- { "blockchain", "verifychain", &verifychain, true, false, false },
+ { "blockchain", "getblockchaininfo", &getblockchaininfo, true, false },
+ { "blockchain", "getbestblockhash", &getbestblockhash, true, false },
+ { "blockchain", "getblockcount", &getblockcount, true, false },
+ { "blockchain", "getblock", &getblock, true, false },
+ { "blockchain", "getblockhash", &getblockhash, true, false },
+ { "blockchain", "getchaintips", &getchaintips, true, false },
+ { "blockchain", "getdifficulty", &getdifficulty, true, false },
+ { "blockchain", "getmempoolinfo", &getmempoolinfo, true, false },
+ { "blockchain", "getrawmempool", &getrawmempool, true, false },
+ { "blockchain", "gettxout", &gettxout, true, false },
+ { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, false },
+ { "blockchain", "verifychain", &verifychain, true, false },
/* Mining */
- { "mining", "getblocktemplate", &getblocktemplate, true, false, false },
- { "mining", "getmininginfo", &getmininginfo, true, false, false },
- { "mining", "getnetworkhashps", &getnetworkhashps, true, false, false },
- { "mining", "prioritisetransaction", &prioritisetransaction, true, false, false },
- { "mining", "submitblock", &submitblock, true, true, false },
+ { "mining", "getblocktemplate", &getblocktemplate, true, false },
+ { "mining", "getmininginfo", &getmininginfo, true, false },
+ { "mining", "getnetworkhashps", &getnetworkhashps, true, false },
+ { "mining", "prioritisetransaction", &prioritisetransaction, true, false },
+ { "mining", "submitblock", &submitblock, true, false },
#ifdef ENABLE_WALLET
/* Coin generation */
- { "generating", "getgenerate", &getgenerate, true, false, false },
- { "generating", "gethashespersec", &gethashespersec, true, false, false },
- { "generating", "setgenerate", &setgenerate, true, true, false },
+ { "generating", "getgenerate", &getgenerate, true, false },
+ { "generating", "setgenerate", &setgenerate, true, false },
#endif
/* Raw transactions */
- { "rawtransactions", "createrawtransaction", &createrawtransaction, true, false, false },
- { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, false, false },
- { "rawtransactions", "decodescript", &decodescript, true, false, false },
- { "rawtransactions", "getrawtransaction", &getrawtransaction, true, false, false },
- { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, false, false },
- { "rawtransactions", "signrawtransaction", &signrawtransaction, false, false, false }, /* uses wallet if enabled */
+ { "rawtransactions", "createrawtransaction", &createrawtransaction, true, false },
+ { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, false },
+ { "rawtransactions", "decodescript", &decodescript, true, false },
+ { "rawtransactions", "getrawtransaction", &getrawtransaction, true, false },
+ { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, false },
+ { "rawtransactions", "signrawtransaction", &signrawtransaction, false, false }, /* uses wallet if enabled */
/* Utility functions */
- { "util", "createmultisig", &createmultisig, true, true , false },
- { "util", "validateaddress", &validateaddress, true, false, false }, /* uses wallet if enabled */
- { "util", "verifymessage", &verifymessage, true, false, false },
- { "util", "estimatefee", &estimatefee, true, true, false },
- { "util", "estimatepriority", &estimatepriority, true, true, false },
+ { "util", "createmultisig", &createmultisig, true, false },
+ { "util", "validateaddress", &validateaddress, true, false }, /* uses wallet if enabled */
+ { "util", "verifymessage", &verifymessage, true, false },
+ { "util", "estimatefee", &estimatefee, true, false },
+ { "util", "estimatepriority", &estimatepriority, true, false },
+
+ /* Not shown in help */
+ { "hidden", "invalidateblock", &invalidateblock, true, false },
+ { "hidden", "reconsiderblock", &reconsiderblock, true, false },
+ { "hidden", "setmocktime", &setmocktime, true, false },
#ifdef ENABLE_WALLET
/* Wallet */
- { "wallet", "addmultisigaddress", &addmultisigaddress, true, false, true },
- { "wallet", "backupwallet", &backupwallet, true, false, true },
- { "wallet", "dumpprivkey", &dumpprivkey, true, false, true },
- { "wallet", "dumpwallet", &dumpwallet, true, false, true },
- { "wallet", "encryptwallet", &encryptwallet, true, false, true },
- { "wallet", "getaccountaddress", &getaccountaddress, true, false, true },
- { "wallet", "getaccount", &getaccount, true, false, true },
- { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, false, true },
- { "wallet", "getbalance", &getbalance, false, false, true },
- { "wallet", "getnewaddress", &getnewaddress, true, false, true },
- { "wallet", "getrawchangeaddress", &getrawchangeaddress, true, false, true },
- { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, false, true },
- { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, false, true },
- { "wallet", "gettransaction", &gettransaction, false, false, true },
- { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, false, true },
- { "wallet", "getwalletinfo", &getwalletinfo, false, false, true },
- { "wallet", "importprivkey", &importprivkey, true, false, true },
- { "wallet", "importwallet", &importwallet, true, false, true },
- { "wallet", "importaddress", &importaddress, true, false, true },
- { "wallet", "keypoolrefill", &keypoolrefill, true, false, true },
- { "wallet", "listaccounts", &listaccounts, false, false, true },
- { "wallet", "listaddressgroupings", &listaddressgroupings, false, false, true },
- { "wallet", "listlockunspent", &listlockunspent, false, false, true },
- { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, false, true },
- { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, false, true },
- { "wallet", "listsinceblock", &listsinceblock, false, false, true },
- { "wallet", "listtransactions", &listtransactions, false, false, true },
- { "wallet", "listunspent", &listunspent, false, false, true },
- { "wallet", "lockunspent", &lockunspent, true, false, true },
- { "wallet", "move", &movecmd, false, false, true },
- { "wallet", "sendfrom", &sendfrom, false, false, true },
- { "wallet", "sendmany", &sendmany, false, false, true },
- { "wallet", "sendtoaddress", &sendtoaddress, false, false, true },
- { "wallet", "setaccount", &setaccount, true, false, true },
- { "wallet", "settxfee", &settxfee, true, false, true },
- { "wallet", "signmessage", &signmessage, true, false, true },
- { "wallet", "walletlock", &walletlock, true, false, true },
- { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, false, true },
- { "wallet", "walletpassphrase", &walletpassphrase, true, false, true },
+ { "wallet", "addmultisigaddress", &addmultisigaddress, true, true },
+ { "wallet", "backupwallet", &backupwallet, true, true },
+ { "wallet", "dumpprivkey", &dumpprivkey, true, true },
+ { "wallet", "dumpwallet", &dumpwallet, true, true },
+ { "wallet", "encryptwallet", &encryptwallet, true, true },
+ { "wallet", "getaccountaddress", &getaccountaddress, true, true },
+ { "wallet", "getaccount", &getaccount, true, true },
+ { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, true },
+ { "wallet", "getbalance", &getbalance, false, true },
+ { "wallet", "getnewaddress", &getnewaddress, true, true },
+ { "wallet", "getrawchangeaddress", &getrawchangeaddress, true, true },
+ { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, true },
+ { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, true },
+ { "wallet", "gettransaction", &gettransaction, false, true },
+ { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, true },
+ { "wallet", "getwalletinfo", &getwalletinfo, false, true },
+ { "wallet", "importprivkey", &importprivkey, true, true },
+ { "wallet", "importwallet", &importwallet, true, true },
+ { "wallet", "importaddress", &importaddress, true, true },
+ { "wallet", "keypoolrefill", &keypoolrefill, true, true },
+ { "wallet", "listaccounts", &listaccounts, false, true },
+ { "wallet", "listaddressgroupings", &listaddressgroupings, false, true },
+ { "wallet", "listlockunspent", &listlockunspent, false, true },
+ { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, true },
+ { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, true },
+ { "wallet", "listsinceblock", &listsinceblock, false, true },
+ { "wallet", "listtransactions", &listtransactions, false, true },
+ { "wallet", "listunspent", &listunspent, false, true },
+ { "wallet", "lockunspent", &lockunspent, true, true },
+ { "wallet", "move", &movecmd, false, true },
+ { "wallet", "sendfrom", &sendfrom, false, true },
+ { "wallet", "sendmany", &sendmany, false, true },
+ { "wallet", "sendtoaddress", &sendtoaddress, false, true },
+ { "wallet", "setaccount", &setaccount, true, true },
+ { "wallet", "settxfee", &settxfee, true, true },
+ { "wallet", "signmessage", &signmessage, true, true },
+ { "wallet", "walletlock", &walletlock, true, true },
+ { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, true },
+ { "wallet", "walletpassphrase", &walletpassphrase, true, true },
#endif // ENABLE_WALLET
};
{
public:
AcceptedConnectionImpl(
- asio::io_service& io_service,
+ boost::asio::io_service& io_service,
ssl::context &context,
bool fUseSSL) :
sslStream(io_service, context),
}
typename Protocol::endpoint peer;
- asio::ssl::stream<typename Protocol::socket> sslStream;
+ boost::asio::ssl::stream<typename Protocol::socket> sslStream;
private:
SSLIOStreamDevice<Protocol> _d;
- iostreams::stream< SSLIOStreamDevice<Protocol> > _stream;
+ boost::iostreams::stream< SSLIOStreamDevice<Protocol> > _stream;
};
void ServiceConnection(AcceptedConnection *conn);
const boost::system::error_code& error)
{
// Immediately start accepting new connections, except when we're cancelled or our socket is closed.
- if (error != asio::error::operation_aborted && acceptor->is_open())
+ if (error != boost::asio::error::operation_aborted && acceptor->is_open())
RPCListen(acceptor, context, fUseSSL);
AcceptedConnectionImpl<ip::tcp>* tcp_conn = dynamic_cast< AcceptedConnectionImpl<ip::tcp>* >(conn.get());
std::string addr;
int port = defaultPort;
SplitHostPort(strEndpoint, port, addr);
- return ip::tcp::endpoint(asio::ip::address::from_string(addr), port);
+ return ip::tcp::endpoint(boost::asio::ip::address::from_string(addr), port);
}
void StartRPCThreads()
}
assert(rpc_io_service == NULL);
- rpc_io_service = new asio::io_service();
+ rpc_io_service = new boost::asio::io_service();
rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23);
const bool fUseSSL = GetBoolArg("-rpcssl", false);
if (fUseSSL)
{
- rpc_ssl_context->set_options(ssl::context::no_sslv2);
+ rpc_ssl_context->set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3);
- filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
- if (!pathCertFile.is_complete()) pathCertFile = filesystem::path(GetDataDir()) / pathCertFile;
- if (filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string());
+ boost::filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
+ if (!pathCertFile.is_complete()) pathCertFile = boost::filesystem::path(GetDataDir()) / pathCertFile;
+ if (boost::filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string());
else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string());
- filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
- if (!pathPKFile.is_complete()) pathPKFile = filesystem::path(GetDataDir()) / pathPKFile;
- if (filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem);
+ boost::filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
+ if (!pathPKFile.is_complete()) pathPKFile = boost::filesystem::path(GetDataDir()) / pathPKFile;
+ if (boost::filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem);
else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string());
string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH");
int defaultPort = GetArg("-rpcport", BaseParams().RPCPort());
if (!mapArgs.count("-rpcallowip")) // Default to loopback if not allowing external IPs
{
- vEndpoints.push_back(ip::tcp::endpoint(asio::ip::address_v6::loopback(), defaultPort));
- vEndpoints.push_back(ip::tcp::endpoint(asio::ip::address_v4::loopback(), defaultPort));
+ vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::loopback(), defaultPort));
+ vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::loopback(), defaultPort));
if (mapArgs.count("-rpcbind"))
{
LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n");
try {
vEndpoints.push_back(ParseEndpoint(addr, defaultPort));
}
- catch(const boost::system::system_error &)
+ catch (const boost::system::system_error&)
{
uiInterface.ThreadSafeMessageBox(
strprintf(_("Could not parse -rpcbind value %s as network address"), addr),
}
}
} else { // No specific bind address specified, bind to any
- vEndpoints.push_back(ip::tcp::endpoint(asio::ip::address_v6::any(), defaultPort));
- vEndpoints.push_back(ip::tcp::endpoint(asio::ip::address_v4::any(), defaultPort));
+ vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::any(), defaultPort));
+ vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::any(), defaultPort));
// Prefer making the socket dual IPv6/IPv4 instead of binding
// to both addresses seperately.
bBindAny = true;
bool fListening = false;
std::string strerr;
+ std::string straddress;
BOOST_FOREACH(const ip::tcp::endpoint &endpoint, vEndpoints)
{
- asio::ip::address bindAddress = endpoint.address();
- LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", bindAddress.to_string(), endpoint.port(), bBindAny);
- boost::system::error_code v6_only_error;
- boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service));
-
try {
+ boost::asio::ip::address bindAddress = endpoint.address();
+ straddress = bindAddress.to_string();
+ LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", straddress, endpoint.port(), bBindAny);
+ boost::system::error_code v6_only_error;
+ boost::shared_ptr<ip::tcp::acceptor> acceptor(new ip::tcp::acceptor(*rpc_io_service));
+
acceptor->open(endpoint.protocol());
acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
// Try making the socket dual IPv6/IPv4 when listening on the IPv6 "any" address
acceptor->set_option(boost::asio::ip::v6_only(
- !bBindAny || bindAddress != asio::ip::address_v6::any()), v6_only_error);
+ !bBindAny || bindAddress != boost::asio::ip::address_v6::any()), v6_only_error);
acceptor->bind(endpoint);
acceptor->listen(socket_base::max_connections);
fListening = true;
rpc_acceptors.push_back(acceptor);
// If dual IPv6/IPv4 bind successful, skip binding to IPv4 separately
- if(bBindAny && bindAddress == asio::ip::address_v6::any() && !v6_only_error)
+ if(bBindAny && bindAddress == boost::asio::ip::address_v6::any() && !v6_only_error)
break;
}
- catch(boost::system::system_error &e)
+ catch (const boost::system::system_error& e)
{
- LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", bindAddress.to_string(), endpoint.port(), e.what());
- strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), bindAddress.to_string(), endpoint.port(), e.what());
+ LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", straddress, endpoint.port(), e.what());
+ strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), straddress, endpoint.port(), e.what());
}
}
rpc_worker_group = new boost::thread_group();
for (int i = 0; i < GetArg("-rpcthreads", 4); i++)
- rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service));
+ rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service));
fRPCRunning = true;
+ g_rpcSignals.Started();
}
void StartDummyRPCThread()
{
if(rpc_io_service == NULL)
{
- rpc_io_service = new asio::io_service();
+ rpc_io_service = new boost::asio::io_service();
/* Create dummy "work" to keep the thread from exiting when no timeouts active,
* see http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/reference/io_service.html#boost_asio.reference.io_service.stopping_the_io_service_from_running_out_of_work */
- rpc_dummy_work = new asio::io_service::work(*rpc_io_service);
+ rpc_dummy_work = new boost::asio::io_service::work(*rpc_io_service);
rpc_worker_group = new boost::thread_group();
- rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service));
+ rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service));
fRPCRunning = true;
}
}
// First, cancel all timers and acceptors
// This is not done automatically by ->stop(), and in some cases the destructor of
- // asio::io_service can hang if this is skipped.
+ // boost::asio::io_service can hang if this is skipped.
boost::system::error_code ec;
BOOST_FOREACH(const boost::shared_ptr<ip::tcp::acceptor> &acceptor, rpc_acceptors)
{
deadlineTimers.clear();
rpc_io_service->stop();
- cvBlockChange.notify_all();
+ g_rpcSignals.Stopped();
if (rpc_worker_group != NULL)
rpc_worker_group->join_all();
delete rpc_dummy_work; rpc_dummy_work = NULL;
fRPCInWarmup = false;
}
+bool RPCIsInWarmup(std::string *outStatus)
+{
+ LOCK(cs_rpcWarmup);
+ if (outStatus)
+ *outStatus = rpcWarmupStatus;
+ return fRPCInWarmup;
+}
+
void RPCRunHandler(const boost::system::error_code& err, boost::function<void(void)> func)
{
if (!err)
deadlineTimers.insert(make_pair(name,
boost::shared_ptr<deadline_timer>(new deadline_timer(*rpc_io_service))));
}
- deadlineTimers[name]->expires_from_now(posix_time::seconds(nSeconds));
+ deadlineTimers[name]->expires_from_now(boost::posix_time::seconds(nSeconds));
deadlineTimers[name]->async_wait(boost::bind(RPCRunHandler, _1, func));
}
throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
strMethod = valMethod.get_str();
if (strMethod != "getblocktemplate")
- LogPrint("rpc", "ThreadRPCServer method=%s\n", strMethod);
+ LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod));
// Parse params
Value valParams = find_value(request, "params");
Value result = tableRPC.execute(jreq.strMethod, jreq.params);
rpc_result = JSONRPCReplyObj(result, Value::null, jreq.id);
}
- catch (Object& objError)
+ catch (const Object& objError)
{
rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id);
}
- catch (std::exception& e)
+ catch (const std::exception& e)
{
rpc_result = JSONRPCReplyObj(Value::null,
JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, strReply.size()) << strReply << std::flush;
}
- catch (Object& objError)
+ catch (const Object& objError)
{
ErrorReply(conn->stream(), objError, jreq.id);
return false;
}
- catch (std::exception& e)
+ catch (const std::exception& e)
{
ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
return false;
ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto, MAX_SIZE);
// HTTP Keep-Alive is false; close connection immediately
- if (mapHeaders["connection"] == "close")
+ if ((mapHeaders["connection"] == "close") || (!GetBoolArg("-rpckeepalive", true)))
fRun = false;
// Process via JSON-RPC API
break;
// Process via HTTP REST API
- } else if (strURI.substr(0, 6) == "/rest/") {
+ } else if (strURI.substr(0, 6) == "/rest/" && GetBoolArg("-rest", false)) {
if (!HTTPReq_REST(conn, strURI, mapHeaders, fRun))
break;
const CRPCCommand *pcmd = tableRPC[strMethod];
if (!pcmd)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
-#ifdef ENABLE_WALLET
- if (pcmd->reqWallet && !pwalletMain)
- throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
-#endif
- // Observe safe mode
- string strWarning = GetWarnings("rpc");
- if (strWarning != "" && !GetBoolArg("-disablesafemode", false) &&
- !pcmd->okSafeMode)
- throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);
+ g_rpcSignals.PreCommand(*pcmd);
try
{
// Execute
- Value result;
- {
- if (pcmd->threadSafe)
- result = pcmd->actor(params, false);
-#ifdef ENABLE_WALLET
- else if (!pwalletMain) {
- LOCK(cs_main);
- result = pcmd->actor(params, false);
- } else {
- LOCK2(cs_main, pwalletMain->cs_wallet);
- result = pcmd->actor(params, false);
- }
-#else // ENABLE_WALLET
- else {
- LOCK(cs_main);
- result = pcmd->actor(params, false);
- }
-#endif // !ENABLE_WALLET
- }
- return result;
+ return pcmd->actor(params, false);
}
- catch (std::exception& e)
+ catch (const std::exception& e)
{
throw JSONRPCError(RPC_MISC_ERROR, e.what());
}
+
+ g_rpcSignals.PostCommand(*pcmd);
}
std::string HelpExampleCli(string methodname, string args){
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "json/json_spirit_utils.h"
#include "json/json_spirit_writer_template.h"
+class CRPCCommand;
+
+namespace RPCServer
+{
+ void OnStarted(boost::function<void ()> slot);
+ void OnStopped(boost::function<void ()> slot);
+ void OnPreCommand(boost::function<void (const CRPCCommand&)> slot);
+ void OnPostCommand(boost::function<void (const CRPCCommand&)> slot);
+}
+
class CBlockIndex;
class CNetAddr;
/* Mark warmup as done. RPC calls will be processed from now on. */
void SetRPCWarmupFinished();
+/* returns the current warmup state. */
+bool RPCIsInWarmup(std::string *statusOut);
+
/**
* Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
* the right number of arguments are passed, just that any passed are the correct type.
std::string name;
rpcfn_type actor;
bool okSafeMode;
- bool threadSafe;
bool reqWallet;
};
extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp
extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
-extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getchaintips(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value invalidateblock(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value reconsiderblock(const json_spirit::Array& params, bool fHelp);
// in rest.cpp
extern bool HTTPReq_REST(AcceptedConnection *conn,
- std::string& strURI,
- std::map<std::string, std::string>& mapHeaders,
+ const std::string& strURI,
+ const std::map<std::string, std::string>& mapHeaders,
bool fRun);
#endif // BITCOIN_RPCSERVER_H
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "netbase.h"
#include "timedata.h"
#include "util.h"
+#include "utilmoneystr.h"
#include "wallet.h"
#include "walletdb.h"
#include <stdint.h>
#include <boost/assign/list_of.hpp>
+
#include "json/json_spirit_utils.h"
#include "json/json_spirit_value.h"
using namespace std;
-using namespace boost;
-using namespace boost::assign;
using namespace json_spirit;
int64_t nWalletUnlockTime;
throw runtime_error(
"getnewaddress ( \"account\" )\n"
"\nReturns a new Bitcoin address for receiving payments.\n"
- "If 'account' is specified (recommended), it is added to the address book \n"
+ "If 'account' is specified (DEPRECATED), it is added to the address book \n"
"so payments received with the address will be credited to 'account'.\n"
"\nArguments:\n"
- "1. \"account\" (string, optional) The account name for the address to be linked to. if not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n"
+ "1. \"account\" (string, optional) DEPRECATED. The account name for the address to be linked to. If not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n"
"\nResult:\n"
"\"bitcoinaddress\" (string) The new bitcoin address\n"
"\nExamples:\n"
+ HelpExampleCli("getnewaddress", "")
- + HelpExampleCli("getnewaddress", "\"\"")
- + HelpExampleCli("getnewaddress", "\"myaccount\"")
- + HelpExampleRpc("getnewaddress", "\"myaccount\"")
+ + HelpExampleRpc("getnewaddress", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
// Parse the account first so we don't generate a key if there's an error
string strAccount;
if (params.size() > 0)
if (fHelp || params.size() != 1)
throw runtime_error(
"getaccountaddress \"account\"\n"
- "\nReturns the current Bitcoin address for receiving payments to this account.\n"
+ "\nDEPRECATED. Returns the current Bitcoin address for receiving payments to this account.\n"
"\nArguments:\n"
"1. \"account\" (string, required) The account name for the address. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created and a new address created if there is no account by the given name.\n"
"\nResult:\n"
+ HelpExampleRpc("getaccountaddress", "\"myaccount\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
// Parse the account first so we don't generate a key if there's an error
string strAccount = AccountFromValue(params[0]);
Value ret;
ret = GetAccountAddress(strAccount).ToString();
-
return ret;
}
+ HelpExampleRpc("getrawchangeaddress", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (!pwalletMain->IsLocked())
pwalletMain->TopUpKeyPool();
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"setaccount \"bitcoinaddress\" \"account\"\n"
- "\nSets the account associated with the given address.\n"
+ "\nDEPRECATED. Sets the account associated with the given address.\n"
"\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address to be associated with an account.\n"
"2. \"account\" (string, required) The account to assign the address to.\n"
+ HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"tabby\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
-
string strAccount;
if (params.size() > 1)
strAccount = AccountFromValue(params[1]);
if (fHelp || params.size() != 1)
throw runtime_error(
"getaccount \"bitcoinaddress\"\n"
- "\nReturns the account associated with the given address.\n"
+ "\nDEPRECATED. Returns the account associated with the given address.\n"
"\nArguments:\n"
"1. \"bitcoinaddress\" (string, required) The bitcoin address for account lookup.\n"
"\nResult:\n"
+ HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
if (fHelp || params.size() != 1)
throw runtime_error(
"getaddressesbyaccount \"account\"\n"
- "\nReturns the list of addresses for the given account.\n"
+ "\nDEPRECATED. Returns the list of addresses for the given account.\n"
"\nArguments:\n"
"1. \"account\" (string, required) The account name.\n"
"\nResult:\n"
+ HelpExampleRpc("getaddressesbyaccount", "\"tabby\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strAccount = AccountFromValue(params[0]);
// Find all addresses that have the given account
return ret;
}
+static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew)
+{
+ CAmount curBalance = pwalletMain->GetBalance();
+
+ // Check amount
+ if (nValue <= 0)
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount");
+
+ if (nValue > curBalance)
+ throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
+
+ // Parse Bitcoin address
+ CScript scriptPubKey = GetScriptForDestination(address);
+
+ // Create and send the transaction
+ CReserveKey reservekey(pwalletMain);
+ CAmount nFeeRequired;
+ std::string strError;
+ vector<CRecipient> vecSend;
+ int nChangePosRet = -1;
+ CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
+ vecSend.push_back(recipient);
+ if (!pwalletMain->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError)) {
+ if (!fSubtractFeeFromAmount && nValue + nFeeRequired > pwalletMain->GetBalance())
+ strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired));
+ throw JSONRPCError(RPC_WALLET_ERROR, strError);
+ }
+ if (!pwalletMain->CommitTransaction(wtxNew, reservekey))
+ throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
+}
+
Value sendtoaddress(const Array& params, bool fHelp)
{
- if (fHelp || params.size() < 2 || params.size() > 4)
+ if (fHelp || params.size() < 2 || params.size() > 5)
throw runtime_error(
- "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" )\n"
+ "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n"
"\nSend an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n"
+ HelpRequiringPassphrase() +
"\nArguments:\n"
"4. \"comment-to\" (string, optional) A comment to store the name of the person or organization \n"
" to which you're sending the transaction. This is not part of the \n"
" transaction, just kept in your wallet.\n"
+ "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n"
+ " The recipient will receive less bitcoins than you enter in the amount field.\n"
"\nResult:\n"
"\"transactionid\" (string) The transaction id.\n"
"\nExamples:\n"
+ HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
+ HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
+ + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true")
+ HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
wtx.mapValue["to"] = params[3].get_str();
+ bool fSubtractFeeFromAmount = false;
+ if (params.size() > 4)
+ fSubtractFeeFromAmount = params[4].get_bool();
+
EnsureWalletIsUnlocked();
- string strError = pwalletMain->SendMoney(address.Get(), nAmount, wtx);
- if (strError != "")
- throw JSONRPCError(RPC_WALLET_ERROR, strError);
+ SendMoney(address.Get(), nAmount, fSubtractFeeFromAmount, wtx);
return wtx.GetHash().GetHex();
}
" [\n"
" \"bitcoinaddress\", (string) The bitcoin address\n"
" amount, (numeric) The amount in btc\n"
- " \"account\" (string, optional) The account\n"
+ " \"account\" (string, optional) The account (DEPRECATED)\n"
" ]\n"
" ,...\n"
" ]\n"
+ HelpExampleRpc("listaddressgroupings", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
Array jsonGroupings;
map<CTxDestination, CAmount> balances = pwalletMain->GetAddressBalances();
BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings())
+ HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"my message\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
EnsureWalletIsUnlocked();
string strAddress = params[0].get_str();
+ HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", 6")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
// Bitcoin address
CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
if (!address.IsValid())
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"getreceivedbyaccount \"account\" ( minconf )\n"
- "\nReturns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
+ "\nDEPRECATED. Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
"\nArguments:\n"
"1. \"account\" (string, required) The selected account, may be the default account using \"\".\n"
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
+ HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
// Minimum confirmations
int nMinDepth = 1;
if (params.size() > 1)
throw runtime_error(
"getbalance ( \"account\" minconf includeWatchonly )\n"
"\nIf account is not specified, returns the server's total available balance.\n"
- "If account is specified, returns the balance in the account.\n"
+ "If account is specified (DEPRECATED), returns the balance in the account.\n"
"Note that the account \"\" is not the same as leaving the parameter out.\n"
"The server total may be different to the balance in the default \"\" account.\n"
"\nArguments:\n"
- "1. \"account\" (string, optional) The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n"
+ "1. \"account\" (string, optional) DEPRECATED. The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n"
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
"3. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n"
"\nResult:\n"
"amount (numeric) The total amount in btc received for this account.\n"
"\nExamples:\n"
- "\nThe total amount in the server across all accounts\n"
+ "\nThe total amount in the wallet\n"
+ HelpExampleCli("getbalance", "") +
- "\nThe total amount in the server across all accounts, with at least 5 confirmations\n"
+ "\nThe total amount in the wallet at least 5 blocks confirmed\n"
+ HelpExampleCli("getbalance", "\"*\" 6") +
- "\nThe total amount in the default account with at least 1 confirmation\n"
- + HelpExampleCli("getbalance", "\"\"") +
- "\nThe total amount in the account named tabby with at least 6 confirmations\n"
- + HelpExampleCli("getbalance", "\"tabby\" 6") +
"\nAs a json rpc call\n"
- + HelpExampleRpc("getbalance", "\"tabby\", 6")
+ + HelpExampleRpc("getbalance", "\"*\", 6")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (params.size() == 0)
return ValueFromAmount(pwalletMain->GetBalance());
throw runtime_error(
"getunconfirmedbalance\n"
"Returns the server's total unconfirmed balance\n");
+
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
return ValueFromAmount(pwalletMain->GetUnconfirmedBalance());
}
if (fHelp || params.size() < 3 || params.size() > 5)
throw runtime_error(
"move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
- "\nMove a specified amount from one account in your wallet to another.\n"
+ "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n"
"\nArguments:\n"
"1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n"
"2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n"
+ HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strFrom = AccountFromValue(params[0]);
string strTo = AccountFromValue(params[1]);
CAmount nAmount = AmountFromValue(params[2]);
if (fHelp || params.size() < 3 || params.size() > 6)
throw runtime_error(
"sendfrom \"fromaccount\" \"tobitcoinaddress\" amount ( minconf \"comment\" \"comment-to\" )\n"
- "\nSent an amount from an account to a bitcoin address.\n"
+ "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address.\n"
"The amount is a real and is rounded to the nearest 0.00000001."
+ HelpRequiringPassphrase() + "\n"
"\nArguments:\n"
+ HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strAccount = AccountFromValue(params[0]);
CBitcoinAddress address(params[1].get_str());
if (!address.IsValid())
if (nAmount > nBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
- // Send
- string strError = pwalletMain->SendMoney(address.Get(), nAmount, wtx);
- if (strError != "")
- throw JSONRPCError(RPC_WALLET_ERROR, strError);
+ SendMoney(address.Get(), nAmount, false, wtx);
return wtx.GetHash().GetHex();
}
Value sendmany(const Array& params, bool fHelp)
{
- if (fHelp || params.size() < 2 || params.size() > 4)
+ if (fHelp || params.size() < 2 || params.size() > 5)
throw runtime_error(
- "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" )\n"
+ "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n"
"\nSend multiple times. Amounts are double-precision floating point numbers."
+ HelpRequiringPassphrase() + "\n"
"\nArguments:\n"
- "1. \"fromaccount\" (string, required) The account to send the funds from, can be \"\" for the default account\n"
+ "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n"
"2. \"amounts\" (string, required) A json object with addresses and amounts\n"
" {\n"
" \"address\":amount (numeric) The bitcoin address is the key, the numeric amount in btc is the value\n"
" }\n"
"3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
"4. \"comment\" (string, optional) A comment\n"
+ "5. subtractfeefromamount (string, optional) A json array with addresses.\n"
+ " The fee will be equally deducted from the amount of each selected address.\n"
+ " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
+ " If no addresses are specified here, the sender pays the fee.\n"
+ " [\n"
+ " \"address\" (string) Subtract fee from this address\n"
+ " ,...\n"
+ " ]\n"
"\nResult:\n"
"\"transactionid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
" the number of addresses.\n"
"\nExamples:\n"
"\nSend two amounts to two different addresses:\n"
- + HelpExampleCli("sendmany", "\"tabby\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
+ + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
"\nSend two amounts to two different addresses setting the confirmation and comment:\n"
- + HelpExampleCli("sendmany", "\"tabby\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
+ + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
+ "\nSend two amounts to two different addresses, subtract fee from amount:\n"
+ + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") +
"\nAs a json rpc call\n"
- + HelpExampleRpc("sendmany", "\"tabby\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
+ + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strAccount = AccountFromValue(params[0]);
Object sendTo = params[1].get_obj();
int nMinDepth = 1;
if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
wtx.mapValue["comment"] = params[3].get_str();
+ Array subtractFeeFromAmount;
+ if (params.size() > 4)
+ subtractFeeFromAmount = params[4].get_array();
+
set<CBitcoinAddress> setAddress;
- vector<pair<CScript, CAmount> > vecSend;
+ vector<CRecipient> vecSend;
CAmount totalAmount = 0;
BOOST_FOREACH(const Pair& s, sendTo)
CAmount nAmount = AmountFromValue(s.value_);
totalAmount += nAmount;
- vecSend.push_back(make_pair(scriptPubKey, nAmount));
+ bool fSubtractFeeFromAmount = false;
+ BOOST_FOREACH(const Value& addr, subtractFeeFromAmount)
+ if (addr.get_str() == s.name_)
+ fSubtractFeeFromAmount = true;
+
+ CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount};
+ vecSend.push_back(recipient);
}
EnsureWalletIsUnlocked();
// Send
CReserveKey keyChange(pwalletMain);
CAmount nFeeRequired = 0;
+ int nChangePosRet = -1;
string strFailReason;
- bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, strFailReason);
+ bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason);
if (!fCreated)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
if (!pwalletMain->CommitTransaction(wtx, keyChange))
string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n"
"\nAdd a nrequired-to-sign multisignature address to the wallet.\n"
"Each key is a Bitcoin address or hex-encoded public key.\n"
- "If 'account' is specified, assign address to that account.\n"
+ "If 'account' is specified (DEPRECATED), assign address to that account.\n"
"\nArguments:\n"
"1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
" \"address\" (string) bitcoin address or hex-encoded public key\n"
" ...,\n"
" ]\n"
- "3. \"account\" (string, optional) An account to assign the addresses to.\n"
+ "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
"\nResult:\n"
"\"bitcoinaddress\" (string) A bitcoin address associated with the keys.\n"
throw runtime_error(msg);
}
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strAccount;
if (params.size() > 2)
strAccount = AccountFromValue(params[2]);
"\nResult:\n"
"[\n"
" {\n"
- " \"involvesWatchonly\" : \"true\", (bool) Only returned if imported addresses were involved in transaction\n"
+ " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
" \"address\" : \"receivingaddress\", (string) The receiving address\n"
- " \"account\" : \"accountname\", (string) The account of the receiving address. The default account is \"\".\n"
+ " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n"
" \"amount\" : x.xxx, (numeric) The total amount in btc received by the address\n"
" \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n"
" }\n"
+ HelpExampleRpc("listreceivedbyaddress", "6, true, true")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
return ListReceived(params, false);
}
if (fHelp || params.size() > 3)
throw runtime_error(
"listreceivedbyaccount ( minconf includeempty includeWatchonly)\n"
- "\nList balances by account.\n"
+ "\nDEPRECATED. List balances by account.\n"
"\nArguments:\n"
"1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
"2. includeempty (boolean, optional, default=false) Whether to include accounts that haven't received any payments.\n"
"\nResult:\n"
"[\n"
" {\n"
- " \"involvesWatchonly\" : \"true\", (bool) Only returned if imported addresses were involved in transaction\n"
+ " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
" \"account\" : \"accountname\", (string) The account name of the receiving account\n"
" \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n"
" \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n"
+ HelpExampleRpc("listreceivedbyaccount", "6, true, true")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
return ListReceived(params, true);
}
"listtransactions ( \"account\" count from includeWatchonly)\n"
"\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
"\nArguments:\n"
- "1. \"account\" (string, optional) The account name. If not included, it will list all transactions for all accounts.\n"
- " If \"\" is set, it will list transactions for the default account.\n"
+ "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n"
"2. count (numeric, optional, default=10) The number of transactions to return\n"
"3. from (numeric, optional, default=0) The number of transactions to skip\n"
"4. includeWatchonly (bool, optional, default=false) Include transactions to watchonly addresses (see 'importaddress')\n"
"\nResult:\n"
"[\n"
" {\n"
- " \"account\":\"accountname\", (string) The account name associated with the transaction. \n"
+ " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n"
" It will be \"\" for the default account.\n"
" \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for \n"
" move transactions (category = move).\n"
"\nExamples:\n"
"\nList the most recent 10 transactions in the systems\n"
+ HelpExampleCli("listtransactions", "") +
- "\nList the most recent 10 transactions for the tabby account\n"
- + HelpExampleCli("listtransactions", "\"tabby\"") +
- "\nList transactions 100 to 120 from the tabby account\n"
- + HelpExampleCli("listtransactions", "\"tabby\" 20 100") +
+ "\nList transactions 100 to 120\n"
+ + HelpExampleCli("listtransactions", "\"*\" 20 100") +
"\nAs a json rpc call\n"
- + HelpExampleRpc("listtransactions", "\"tabby\", 20, 100")
+ + HelpExampleRpc("listtransactions", "\"*\", 20, 100")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strAccount = "*";
if (params.size() > 0)
strAccount = params[0].get_str();
if (fHelp || params.size() > 2)
throw runtime_error(
"listaccounts ( minconf includeWatchonly)\n"
- "\nReturns Object that has account names as keys, account balances as values.\n"
+ "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n"
"\nArguments:\n"
"1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n"
"2. includeWatchonly (bool, optional, default=false) Include balances in watchonly addresses (see 'importaddress')\n"
+ HelpExampleRpc("listaccounts", "6")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
int nMinDepth = 1;
if (params.size() > 0)
nMinDepth = params[0].get_int();
"\nResult:\n"
"{\n"
" \"transactions\": [\n"
- " \"account\":\"accountname\", (string) The account name associated with the transaction. Will be \"\" for the default account.\n"
+ " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
" \"address\":\"bitcoinaddress\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n"
" \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
" \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the 'move' category for moves \n"
+ HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
CBlockIndex *pindex = NULL;
int target_confirms = 1;
isminefilter filter = ISMINE_SPENDABLE;
if (params.size() > 0)
{
- uint256 blockId = 0;
+ uint256 blockId;
blockId.SetHex(params[0].get_str());
BlockMap::iterator it = mapBlockIndex.find(blockId);
}
CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
- uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : 0;
+ uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256();
Object ret;
ret.push_back(Pair("transactions", transactions));
" \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
" \"details\" : [\n"
" {\n"
- " \"account\" : \"accountname\", (string) The account name involved in the transaction, can be \"\" for the default account.\n"
+ " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
" \"address\" : \"bitcoinaddress\", (string) The bitcoin address involved in the transaction\n"
" \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
" \"amount\" : x.xxx (numeric) The amount in btc\n"
+ HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
uint256 hash;
hash.SetHex(params[0].get_str());
+ HelpExampleRpc("backupwallet", "\"backup.dat\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
string strDest = params[0].get_str();
if (!BackupWallet(*pwalletMain, strDest))
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
+ HelpExampleRpc("keypoolrefill", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
// 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
unsigned int kpSize = 0;
if (params.size() > 0) {
+ HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (fHelp)
return true;
if (!pwalletMain->IsCrypted())
+ HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (fHelp)
return true;
if (!pwalletMain->IsCrypted())
+ HelpExampleRpc("walletlock", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (fHelp)
return true;
if (!pwalletMain->IsCrypted())
+ HelpExampleRpc("encryptwallet", "\"my pass phrase\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (fHelp)
return true;
if (pwalletMain->IsCrypted())
+ HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
if (params.size() == 1)
- RPCTypeCheck(params, list_of(bool_type));
+ RPCTypeCheck(params, boost::assign::list_of(bool_type));
else
- RPCTypeCheck(params, list_of(bool_type)(array_type));
+ RPCTypeCheck(params, boost::assign::list_of(bool_type)(array_type));
bool fUnlock = params[0].get_bool();
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
const Object& o = output.get_obj();
- RPCTypeCheck(o, map_list_of("txid", str_type)("vout", int_type));
+ RPCTypeCheck(o, boost::assign::map_list_of("txid", str_type)("vout", int_type));
string txid = find_value(o, "txid").get_str();
if (!IsHex(txid))
if (nOutput < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
- COutPoint outpt(uint256(txid), nOutput);
+ COutPoint outpt(uint256S(txid), nOutput);
if (fUnlock)
pwalletMain->UnlockCoin(outpt);
+ HelpExampleRpc("listlockunspent", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
vector<COutPoint> vOutpts;
pwalletMain->ListLockedCoins(vOutpts);
+ HelpExampleRpc("settxfee", "0.00001")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
// Amount
CAmount nAmount = 0;
if (params[0].get_real() != 0.0)
"\nResult:\n"
"{\n"
" \"walletversion\": xxxxx, (numeric) the wallet version\n"
- " \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n"
+ " \"balance\": xxxxxxx, (numeric) the total confirmed bitcoin balance of the wallet\n"
+ " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed bitcoin balance of the wallet\n"
+ " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet\n"
" \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n"
" \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n"
" \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n"
+ HelpExampleRpc("getwalletinfo", "")
);
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+
Object obj;
obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
+ obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance())));
+ obj.push_back(Pair("immature_balance", ValueFromAmount(pwalletMain->GetImmatureBalance())));
obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size()));
obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "bitcoinconsensus.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "script/interpreter.h"
#include "version.h"
// 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 VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, TransactionSignatureChecker(&tx, nIn), NULL);
+ } catch (const std::exception&) {
return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing
}
}
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
{
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0,
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts
+ bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance
};
/// Returns 1 if the input nIn of the serialized transaction pointed to by
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "interpreter.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "crypto/ripemd160.h"
#include "crypto/sha1.h"
-#include "crypto/sha2.h"
+#include "crypto/sha256.h"
#include "eccryptoverify.h"
#include "pubkey.h"
#include "script/script.h"
using namespace std;
typedef vector<unsigned char> valtype;
-static const valtype vchFalse(0);
-static const valtype vchZero(0);
-static const valtype vchTrue(1, 1);
-static const CScriptNum bnZero(0);
-static const CScriptNum bnOne(1);
-static const CScriptNum bnFalse(0);
-static const CScriptNum bnTrue(1);
namespace {
static inline void popstack(vector<valtype>& stack)
{
if (stack.empty())
- throw runtime_error("popstack() : stack empty");
+ throw runtime_error("popstack(): stack empty");
stack.pop_back();
}
* in which case a single 0 byte is necessary and even required).
*
* See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
+ *
+ * This function is consensus-critical since BIP66.
*/
-bool static IsDERSignature(const valtype &vchSig) {
+bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
+ // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash]
+ // * total-length: 1-byte length descriptor of everything that follows,
+ // excluding the sighash byte.
+ // * R-length: 1-byte length descriptor of the R value that follows.
+ // * R: arbitrary-length big-endian encoded R value. It must use the shortest
+ // possible encoding for a positive integers (which means no null bytes at
+ // the start, except a single one when the next byte has its highest bit set).
+ // * S-length: 1-byte length descriptor of the S value that follows.
+ // * S: arbitrary-length big-endian encoded S value. The same rules apply.
+ // * sighash: 1-byte value indicating what data is hashed (not part of the DER
+ // signature)
- if (vchSig.size() < 9) {
- // Non-canonical signature: too short
- return false;
- }
- if (vchSig.size() > 73) {
- // Non-canonical signature: too long
- return false;
- }
- if (vchSig[0] != 0x30) {
- // Non-canonical signature: wrong type
- return false;
- }
- if (vchSig[1] != vchSig.size()-3) {
- // Non-canonical signature: wrong length marker
- return false;
- }
- unsigned int nLenR = vchSig[3];
- if (5 + nLenR >= vchSig.size()) {
- // Non-canonical signature: S length misplaced
- return false;
- }
- unsigned int nLenS = vchSig[5+nLenR];
- if ((unsigned long)(nLenR+nLenS+7) != vchSig.size()) {
- // Non-canonical signature: R+S length mismatch
- return false;
- }
+ // Minimum and maximum size constraints.
+ if (sig.size() < 9) return false;
+ if (sig.size() > 73) return false;
- const unsigned char *R = &vchSig[4];
- if (R[-2] != 0x02) {
- // Non-canonical signature: R value type mismatch
- return false;
- }
- if (nLenR == 0) {
- // Non-canonical signature: R length is zero
- return false;
- }
- if (R[0] & 0x80) {
- // Non-canonical signature: R value negative
- return false;
- }
- if (nLenR > 1 && (R[0] == 0x00) && !(R[1] & 0x80)) {
- // Non-canonical signature: R value excessively padded
- return false;
- }
+ // A signature is of type 0x30 (compound).
+ if (sig[0] != 0x30) return false;
+
+ // Make sure the length covers the entire signature.
+ if (sig[1] != sig.size() - 3) return false;
+
+ // Extract the length of the R element.
+ unsigned int lenR = sig[3];
+
+ // Make sure the length of the S element is still inside the signature.
+ if (5 + lenR >= sig.size()) return false;
+
+ // Extract the length of the S element.
+ unsigned int lenS = sig[5 + lenR];
+
+ // Verify that the length of the signature matches the sum of the length
+ // of the elements.
+ if ((size_t)(lenR + lenS + 7) != sig.size()) return false;
+
+ // Check whether the R element is an integer.
+ if (sig[2] != 0x02) return false;
+
+ // Zero-length integers are not allowed for R.
+ if (lenR == 0) return false;
+
+ // Negative numbers are not allowed for R.
+ if (sig[4] & 0x80) return false;
+
+ // Null bytes at the start of R are not allowed, unless R would
+ // otherwise be interpreted as a negative number.
+ if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false;
+
+ // Check whether the S element is an integer.
+ if (sig[lenR + 4] != 0x02) return false;
+
+ // Zero-length integers are not allowed for S.
+ if (lenS == 0) return false;
+
+ // Negative numbers are not allowed for S.
+ if (sig[lenR + 6] & 0x80) return false;
+
+ // Null bytes at the start of S are not allowed, unless S would otherwise be
+ // interpreted as a negative number.
+ if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false;
- const unsigned char *S = &vchSig[6+nLenR];
- if (S[-2] != 0x02) {
- // Non-canonical signature: S value type mismatch
- return false;
- }
- if (nLenS == 0) {
- // Non-canonical signature: S length is zero
- return false;
- }
- if (S[0] & 0x80) {
- // Non-canonical signature: S value negative
- return false;
- }
- if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80)) {
- // Non-canonical signature: S value excessively padded
- return false;
- }
return true;
}
bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) {
- if (!IsDERSignature(vchSig)) {
+ if (!IsValidSignatureEncoding(vchSig)) {
return set_error(serror, SCRIPT_ERR_SIG_DER);
}
unsigned int nLenR = vchSig[3];
}
bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) {
- if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsDERSignature(vchSig)) {
+ // Empty signature. Not strictly DER encoded, but allowed to provide a
+ // compact way to provide an invalid signature for use with CHECK(MULTI)SIG
+ if (vchSig.size() == 0) {
+ return true;
+ }
+ if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSig)) {
return set_error(serror, SCRIPT_ERR_SIG_DER);
} else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) {
// serror is set
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror)
{
+ static const CScriptNum bnZero(0);
+ static const CScriptNum bnOne(1);
+ static const CScriptNum bnFalse(0);
+ static const CScriptNum bnTrue(1);
+ static const valtype vchFalse(0);
+ static const valtype vchZero(0);
+ static const valtype vchTrue(1, 1);
+
CScript::const_iterator pc = script.begin();
CScript::const_iterator pend = script.end();
CScript::const_iterator pbegincodehash = script.begin();
uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
{
+ static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
if (nIn >= txTo.vin.size()) {
// nIn out of range
- return 1;
+ return one;
}
// Check for invalid use of SIGHASH_SINGLE
if ((nHashType & 0x1f) == SIGHASH_SINGLE) {
if (nIn >= txTo.vout.size()) {
// nOut out of range
- return 1;
+ return one;
}
}
return ss.GetHash();
}
-bool SignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
+bool TransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
{
return pubkey.Verify(sighash, vchSig);
}
-bool SignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vector<unsigned char>& vchPubKey, const CScript& scriptCode) const
+bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vector<unsigned char>& vchPubKey, const CScript& scriptCode) const
{
CPubKey pubkey(vchPubKey);
if (!pubkey.IsValid())
int nHashType = vchSig.back();
vchSig.pop_back();
- uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType);
+ uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType);
if (!VerifySignature(vchSig, pubkey, sighash))
return false;
return false;
if (stack.empty())
return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
-
if (CastToBool(stack.back()) == false)
return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
if (!scriptSig.IsPushOnly())
return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY);
- // stackCopy cannot be empty here, because if it was the
+ // Restore stack.
+ swap(stack, stackCopy);
+
+ // stack cannot be empty here, because if it was the
// P2SH HASH <> EQUAL scriptPubKey would be evaluated with
// an empty stack and the EvalScript above would return false.
- assert(!stackCopy.empty());
+ assert(!stack.empty());
- const valtype& pubKeySerialized = stackCopy.back();
+ const valtype& pubKeySerialized = stack.back();
CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end());
- popstack(stackCopy);
+ popstack(stack);
- if (!EvalScript(stackCopy, pubKey2, flags, checker, serror))
+ if (!EvalScript(stack, pubKey2, flags, checker, serror))
// serror is set
return false;
- if (stackCopy.empty())
+ if (stack.empty())
return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
- if (!CastToBool(stackCopy.back()))
+ if (!CastToBool(stack.back()))
return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
- else
- return set_success(serror);
+ }
+
+ // The CLEANSTACK check is only performed after potential P2SH evaluation,
+ // as the non-P2SH evaluation of a P2SH script will obviously not result in
+ // a clean stack (the P2SH inputs remain).
+ if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) {
+ // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK
+ // would be possible, which is not a softfork (and P2SH should be one).
+ assert((flags & SCRIPT_VERIFY_P2SH) != 0);
+ if (stack.size() != 1) {
+ return set_error(serror, SCRIPT_ERR_CLEANSTACK);
+ }
}
return set_success(serror);
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#define BITCOIN_SCRIPT_INTERPRETER_H
#include "script_error.h"
+#include "primitives/transaction.h"
#include <vector>
#include <stdint.h>
// 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)
-
+ SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7),
+
+ // Require that only a single stack element remains after evaluation. This changes the success criterion from
+ // "At least one stack element must remain, and when interpreted as a boolean, it must be true" to
+ // "Exactly one stack element must remain, and when interpreted as a boolean, it must be true".
+ // (softfork safe, BIP62 rule 6)
+ // Note: CLEANSTACK should never be used without P2SH.
+ SCRIPT_VERIFY_CLEANSTACK = (1U << 8),
};
uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
virtual ~BaseSignatureChecker() {}
};
-class SignatureChecker : public BaseSignatureChecker
+class TransactionSignatureChecker : public BaseSignatureChecker
{
private:
- const CTransaction& txTo;
+ const CTransaction* txTo;
unsigned int nIn;
protected:
virtual bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
public:
- SignatureChecker(const CTransaction& txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {}
+ TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {}
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const;
};
+class MutableTransactionSignatureChecker : public TransactionSignatureChecker
+{
+private:
+ const CTransaction txTo;
+
+public:
+ MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn) : TransactionSignatureChecker(&txTo, nInIn), txTo(*txToIn) {}
+};
+
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string.h>
#include <string>
#include <vector>
+#include "crypto/common.h"
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
CScript& operator<<(opcodetype opcode)
{
if (opcode < 0 || opcode > 0xff)
- throw std::runtime_error("CScript::operator<<() : invalid opcode");
+ throw std::runtime_error("CScript::operator<<(): invalid opcode");
insert(end(), (unsigned char)opcode);
return *this;
}
else if (b.size() <= 0xffff)
{
insert(end(), OP_PUSHDATA2);
- unsigned short nSize = b.size();
- insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
+ uint8_t data[2];
+ WriteLE16(data, b.size());
+ insert(end(), data, data + sizeof(data));
}
else
{
insert(end(), OP_PUSHDATA4);
- unsigned int nSize = b.size();
- insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
+ uint8_t data[4];
+ WriteLE32(data, b.size());
+ insert(end(), data, data + sizeof(data));
}
insert(end(), b.begin(), b.end());
return *this;
{
if (end() - pc < 2)
return false;
- nSize = 0;
- memcpy(&nSize, &pc[0], 2);
+ nSize = ReadLE16(&pc[0]);
pc += 2;
}
else if (opcode == OP_PUSHDATA4)
{
if (end() - pc < 4)
return false;
- memcpy(&nSize, &pc[0], 4);
+ nSize = ReadLE32(&pc[0]);
pc += 4;
}
if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize)
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#ifndef BITCOIN_SCRIPT_ERROR_H
-#define BITCOIN_SCRIPT_ERROR_H
+#ifndef BITCOIN_SCRIPT_SCRIPT_ERROR_H
+#define BITCOIN_SCRIPT_SCRIPT_ERROR_H
typedef enum ScriptError_t
{
SCRIPT_ERR_SIG_HIGH_S,
SCRIPT_ERR_SIG_NULLDUMMY,
SCRIPT_ERR_PUBKEYTYPE,
+ SCRIPT_ERR_CLEANSTACK,
/* softfork safeness */
SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS,
const char* ScriptErrorString(const ScriptError error);
-#endif // BITCOIN_SCRIPT_ERROR_H
+#endif // BITCOIN_SCRIPT_SCRIPT_ERROR_H
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
}
-bool CachingSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
+bool CachingTransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
{
static CSignatureCache signatureCache;
if (signatureCache.Get(sighash, vchSig, pubkey))
return true;
- if (!SignatureChecker::VerifySignature(vchSig, pubkey, sighash))
+ if (!TransactionSignatureChecker::VerifySignature(vchSig, pubkey, sighash))
return false;
if (store)
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
class CPubKey;
-class CachingSignatureChecker : public SignatureChecker
+class CachingTransactionSignatureChecker : public TransactionSignatureChecker
{
private:
bool store;
public:
- CachingSignatureChecker(const CTransaction& txToIn, unsigned int nInIn, bool storeIn=true) : SignatureChecker(txToIn, nInIn), store(storeIn) {}
+ CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, bool storeIn=true) : TransactionSignatureChecker(txToIn, nInIn), store(storeIn) {}
bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
};
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "script/sign.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "key.h"
#include "keystore.h"
#include "script/standard.h"
}
// Test solution
- return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(txTo, nIn));
+ return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&txTo, nIn));
}
bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
if (sigs.count(pubkey))
continue; // Already got a sig for this pubkey
- if (SignatureChecker(txTo, nIn).CheckSig(sig, pubkey, scriptPubKey))
+ if (TransactionSignatureChecker(&txTo, nIn).CheckSig(sig, pubkey, scriptPubKey))
{
sigs[pubkey] = sig;
break;
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;
-CScriptID::CScriptID(const CScript& in) : uint160(in.size() ? Hash160(in.begin(), in.end()) : 0) {}
+CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {}
const char* GetTxnOutputType(txnouttype t)
{
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
class CScriptID : public uint160
{
public:
- CScriptID() : uint160(0) {}
+ CScriptID() : uint160() {}
CScriptID(const CScript& in);
CScriptID(const uint160& in) : uint160(in) {}
};
-static const unsigned int MAX_OP_RETURN_RELAY = 40; //! bytes
+static const unsigned int MAX_OP_RETURN_RELAY = 80; //! bytes
extern unsigned nMaxDatacarrierBytes;
/**
* blocks and we must accept those blocks.
*/
static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS |
+ SCRIPT_VERIFY_DERSIG |
SCRIPT_VERIFY_STRICTENC |
SCRIPT_VERIFY_MINIMALDATA |
SCRIPT_VERIFY_NULLDUMMY |
- SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS;
+ SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS |
+ SCRIPT_VERIFY_CLEANSTACK;
/** 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;
bench_inv
bench_sign
bench_verify
+bench_recover
tests
*.exe
*.so
-language: cpp
-compiler: gcc
+language: c
+compiler:
+ - clang
+ - gcc
install:
- sudo apt-get install -qq libssl-dev
- - if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" -o "$FIELD" = "gmp" ]; then sudo apt-get install -qq libgmp-dev; fi
- - if [ "$FIELD" = "64bit_asm" ]; then sudo apt-get install -qq yasm; fi
+ - if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" ]; then sudo apt-get install --no-install-recommends --no-upgrade -qq libgmp-dev; fi
+ - if [ -n "$EXTRAPACKAGES" ]; then sudo apt-get update && sudo apt-get install --no-install-recommends --no-upgrade $EXTRAPACKAGES; fi
env:
global:
- - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no BUILD=check EXTRAFLAGS=
+ - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no ASM=no BUILD=check EXTRAFLAGS= HOST= EXTRAPACKAGES=
matrix:
- SCALAR=32bit
- SCALAR=64bit
- - FIELD=gmp
- - FIELD=gmp ENDOMORPHISM=yes
- - FIELD=64bit_asm
- - FIELD=64bit_asm ENDOMORPHISM=yes
- FIELD=64bit
- FIELD=64bit ENDOMORPHISM=yes
+ - FIELD=64bit ASM=x86_64
+ - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64
- FIELD=32bit
- FIELD=32bit ENDOMORPHISM=yes
+ - BIGNUM=no
+ - BIGNUM=no ENDOMORPHISM=yes
- BUILD=distcheck
- EXTRAFLAGS=CFLAGS=-DDETERMINISTIC
+ - HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib"
+ - HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib" ENDOMORPHISM=yes
before_script: ./autogen.sh
-script: ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR $EXTRAFLAGS && make -j2 $BUILD
+script:
+ - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi
+ - if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi
+ - ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR $EXTRAFLAGS $USE_HOST && make -j2 $BUILD
os: linux
ACLOCAL_AMFLAGS = -I build-aux/m4
lib_LTLIBRARIES = libsecp256k1.la
-if USE_ASM
-COMMON_LIB = libsecp256k1_common.la
-else
-COMMON_LIB =
-endif
-noinst_LTLIBRARIES = $(COMMON_LIB)
include_HEADERS = include/secp256k1.h
noinst_HEADERS =
noinst_HEADERS += src/scalar.h
noinst_HEADERS += src/util.h
noinst_HEADERS += src/testrand.h
noinst_HEADERS += src/testrand_impl.h
-noinst_HEADERS += src/field_gmp.h
-noinst_HEADERS += src/field_gmp_impl.h
+noinst_HEADERS += src/hash.h
+noinst_HEADERS += src/hash_impl.h
noinst_HEADERS += src/field.h
noinst_HEADERS += src/field_impl.h
+noinst_HEADERS += src/bench.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libsecp256k1.pc
-if USE_ASM
-libsecp256k1_common_la_SOURCES = src/field_5x52_asm.asm
-endif
-
libsecp256k1_la_SOURCES = src/secp256k1.c
libsecp256k1_la_CPPFLAGS = -I$(top_srcdir)/include $(SECP_INCLUDES)
-libsecp256k1_la_LIBADD = $(COMMON_LIB) $(SECP_LIBS)
+libsecp256k1_la_LIBADD = $(SECP_LIBS)
noinst_PROGRAMS =
if USE_BENCHMARK
-noinst_PROGRAMS += bench_verify bench_sign bench_inv
+noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_inv
bench_verify_SOURCES = src/bench_verify.c
bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS)
bench_verify_LDFLAGS = -static
+bench_recover_SOURCES = src/bench_recover.c
+bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS)
+bench_recover_LDFLAGS = -static
bench_sign_SOURCES = src/bench_sign.c
bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS)
bench_sign_LDFLAGS = -static
bench_inv_SOURCES = src/bench_inv.c
-bench_inv_LDADD = $(COMMON_LIB) $(SECP_LIBS)
+bench_inv_LDADD = $(SECP_LIBS)
bench_inv_LDFLAGS = -static
+bench_inv_CPPFLAGS = $(SECP_INCLUDES)
endif
if USE_TESTS
noinst_PROGRAMS += tests
tests_SOURCES = src/tests.c
-tests_CPPFLAGS = -DVERIFY $(SECP_TEST_INCLUDES)
-tests_LDADD = $(COMMON_LIB) $(SECP_LIBS) $(SECP_TEST_LIBS)
+tests_CPPFLAGS = -DVERIFY $(SECP_INCLUDES) $(SECP_TEST_INCLUDES)
+tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS)
tests_LDFLAGS = -static
TESTS = tests
endif
-EXTRA_DIST = autogen.sh nasm_lt.sh
-
-#x86_64 only
-if USE_ASM
-.asm.lo:
- $(LIBTOOL) --mode=compile --tag YASM $(srcdir)/nasm_lt.sh $(YASM) -f $(YASM_BINFMT) $(YAFLAGS) -I$(srcdir) -I. $< -o $@
-endif
+EXTRA_DIST = autogen.sh
dnl libsecp25k1 helper checks
AC_DEFUN([SECP_INT128_CHECK],[
has_int128=$ac_cv_type___int128
-if test x"$has_int128" != x"yes" && test x"$set_field" = x"64bit"; then
- AC_MSG_ERROR([$set_field field support explicitly requested but is not compatible with this host])
-fi
-if test x"$has_int128" != x"yes" && test x"$set_scalar" = x"64bit"; then
- AC_MSG_ERROR([$set_scalar scalar support explicitly requested but is not compatible with this host])
-fi
])
dnl
AC_DEFUN([SECP_64BIT_ASM_CHECK],[
-if test x"$host_cpu" == x"x86_64"; then
- AC_CHECK_PROG(YASM, yasm, yasm)
-else
- if test x"$set_field" = x"64bit_asm"; then
- AC_MSG_ERROR([$set_field field support explicitly requested but is not compatible with this host])
- fi
-fi
-if test x$YASM = x; then
- if test x"$set_field" = x"64bit_asm"; then
- AC_MSG_ERROR([$set_field field support explicitly requested but yasm was not found])
- fi
- has_64bit_asm=no
-else
- case x"$host_os" in
- xdarwin*)
- YASM_BINFMT=macho64
- ;;
- x*-gnux32)
- YASM_BINFMT=elfx32
- ;;
- *)
- YASM_BINFMT=elf64
- ;;
- esac
- if $YASM -f help | grep -q $YASM_BINFMT; then
- has_64bit_asm=yes
- else
- if test x"$set_field" = x"64bit_asm"; then
- AC_MSG_ERROR([$set_field field support explicitly requested but yasm doesn't support $YASM_BINFMT format])
- fi
- AC_MSG_WARN([yasm too old for $YASM_BINFMT format])
- has_64bit_asm=no
- fi
-fi
+AC_MSG_CHECKING(for x86_64 assembly availability)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #include <stdint.h>]],[[
+ uint64_t a = 11, tmp;
+ __asm__ __volatile__("movq $0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx");
+ ]])],[has_64bit_asm=yes],[has_64bit_asm=no])
+AC_MSG_RESULT([$has_64bit_asm])
])
dnl
if test x"$use_pkgconfig" = x"yes"; then
: #NOP
m4_ifdef([PKG_CHECK_MODULES],[
- PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes; AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])],[has_libcrypto=no])
- : #NOP
+ PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes],[has_libcrypto=no])
+ if test x"$has_libcrypto" = x"yes"; then
+ TEMP_LIBS="$LIBS"
+ LIBS="$LIBS $CRYPTO_LIBS"
+ AC_CHECK_LIB(crypto, main,[AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])],[has_libcrypto=no])
+ LIBS="$TEMP_LIBS"
+ fi
])
else
AC_CHECK_HEADER(openssl/crypto.h,[AC_CHECK_LIB(crypto, main,[has_libcrypto=yes; CRYPTO_LIBS=-lcrypto; AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])]
)])
LIBS=
fi
-if test x"$has_libcrypto" == x"yes" && test x"$has_openssl_ec" = x; then
+if test x"$has_libcrypto" = x"yes" && test x"$has_openssl_ec" = x; then
AC_MSG_CHECKING(for EC functions in libcrypto)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <openssl/ec.h>
dnl
AC_DEFUN([SECP_GMP_CHECK],[
if test x"$has_gmp" != x"yes"; then
- AC_CHECK_HEADER(gmp.h,[AC_CHECK_LIB(gmp, __gmpz_init,[has_gmp=yes; GMP_LIBS=-lgmp; AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed])])])
-fi
-if test x"$set_field" = x"gmp" && test x"$has_gmp" != x"yes"; then
- AC_MSG_ERROR([$set_field field support explicitly requested but libgmp was not found])
-fi
-if test x"$set_bignum" = x"gmp" && test x"$has_gmp" != x"yes"; then
- AC_MSG_ERROR([$set_bignum field support explicitly requested but libgmp was not found])
+ CPPFLAGS_TEMP="$CPPFLAGS"
+ CPPFLAGS="$GMP_CPPFLAGS $CPPFLAGS"
+ LIBS_TEMP="$LIBS"
+ LIBS="$GMP_LIBS $LIBS"
+ AC_CHECK_HEADER(gmp.h,[AC_CHECK_LIB(gmp, __gmpz_init,[has_gmp=yes; GMP_LIBS="$GMP_LIBS -lgmp"; AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed])])])
+ CPPFLAGS="$CPPFLAGS_TEMP"
+ LIBS="$LIBS_TEMP"
fi
])
-
AH_TOP([#ifndef LIBSECP256K1_CONFIG_H])
AH_TOP([#define LIBSECP256K1_CONFIG_H])
AH_BOTTOM([#endif //LIBSECP256K1_CONFIG_H])
-AM_INIT_AUTOMAKE([foreign])
+AM_INIT_AUTOMAKE([foreign subdir-objects])
LT_INIT
dnl make the compilation flags quiet unless V=1 is used
AC_PATH_TOOL(RANLIB, ranlib)
AC_PATH_TOOL(STRIP, strip)
+if test "x$CFLAGS" = "x"; then
+ CFLAGS="-O3 -g"
+fi
+
AC_PROG_CC_C99
-if test x"$ac_cv_prog_cc_c99" == x"no"; then
+if test x"$ac_cv_prog_cc_c99" = x"no"; then
AC_MSG_ERROR([c99 compiler support required])
fi
esac
case $host_os in
- darwin*)
- CPPFLAGS="$CPPFLAGS -I/opt/local/include"
- LDFLAGS="$LDFLAGS -L/opt/local/lib"
- ;;
+ *darwin*)
+ if test x$cross_compiling != xyes; then
+ AC_PATH_PROG([BREW],brew,)
+ if test x$BREW != x; then
+ dnl These Homebrew packages may be keg-only, meaning that they won't be found
+ dnl in expected paths because they may conflict with system files. Ask
+ dnl Homebrew where each one is located, then adjust paths accordingly.
+
+ openssl_prefix=`$BREW --prefix openssl 2>/dev/null`
+ gmp_prefix=`$BREW --prefix gmp 2>/dev/null`
+ if test x$openssl_prefix != x; then
+ PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH"
+ export PKG_CONFIG_PATH
+ fi
+ if test x$gmp_prefix != x; then
+ GMP_CPPFLAGS="-I$gmp_prefix/include"
+ GMP_LIBS="-L$gmp_prefix/lib"
+ fi
+ else
+ AC_PATH_PROG([PORT],port,)
+ dnl if homebrew isn't installed and macports is, add the macports default paths
+ dnl as a last resort.
+ if test x$PORT != x; then
+ CPPFLAGS="$CPPFLAGS -isystem /opt/local/include"
+ LDFLAGS="$LDFLAGS -L/opt/local/lib"
+ fi
+ fi
+ fi
+ ;;
esac
CFLAGS="$CFLAGS -W"
AC_ARG_ENABLE(benchmark,
- AS_HELP_STRING([--enable-benchmark],[compile benchmark (default is yes)]),
+ AS_HELP_STRING([--enable-benchmark],[compile benchmark (default is no)]),
[use_benchmark=$enableval],
- [use_benchmark=yes])
+ [use_benchmark=no])
AC_ARG_ENABLE(tests,
AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]),
[use_endomorphism=$enableval],
[use_endomorphism=no])
-AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=gmp|64bit|64bit_asm|32bit|auto],
+AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto],
[Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto])
-AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|auto],
+AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|no|auto],
[Specify Bignum Implementation. Default is auto])],[req_bignum=$withval], [req_bignum=auto])
AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto],
[Specify scalar implementation. Default is auto])],[req_scalar=$withval], [req_scalar=auto])
+AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|no|auto]
+[Specify assembly optimizations to use. Default is auto])],[req_asm=$withval], [req_asm=auto])
+
AC_CHECK_TYPES([__int128])
-AC_CHECK_DECL(__builtin_expect,AC_DEFINE(HAVE_BUILTIN_EXPECT,1,[Define this symbol if __builtin_expect is available]),,)
+AC_MSG_CHECKING([for __builtin_expect])
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])],
+ [ AC_MSG_RESULT([yes]);AC_DEFINE(HAVE_BUILTIN_EXPECT,1,[Define this symbol if __builtin_expect is available]) ],
+ [ AC_MSG_RESULT([no])
+ ])
-if test x"$req_field" = x"auto"; then
+if test x"$req_asm" = x"auto"; then
SECP_64BIT_ASM_CHECK
if test x"$has_64bit_asm" = x"yes"; then
- set_field=64bit_asm
+ set_asm=x86_64
fi
+ if test x"$set_asm" = x; then
+ set_asm=no
+ fi
+else
+ set_asm=$req_asm
+ case $set_asm in
+ x86_64)
+ SECP_64BIT_ASM_CHECK
+ if test x"$has_64bit_asm" != x"yes"; then
+ AC_MSG_ERROR([x86_64 assembly optimization requested but not available])
+ fi
+ ;;
+ no)
+ ;;
+ *)
+ AC_MSG_ERROR([invalid assembly optimization selection])
+ ;;
+ esac
+fi
+if test x"$req_field" = x"auto"; then
+ if test x"set_asm" = x"x86_64"; then
+ set_field=64bit
+ fi
if test x"$set_field" = x; then
SECP_INT128_CHECK
if test x"$has_int128" = x"yes"; then
set_field=64bit
fi
fi
-
- if test x"$set_field" = x; then
- SECP_GMP_CHECK
- if test x"$has_gmp" = x"yes"; then
- set_field=gmp
- fi
- fi
-
if test x"$set_field" = x; then
set_field=32bit
fi
else
set_field=$req_field
case $set_field in
- 64bit_asm)
- SECP_64BIT_ASM_CHECK
- ;;
64bit)
- SECP_INT128_CHECK
- ;;
- gmp)
- SECP_GMP_CHECK
+ if test x"$set_asm" != x"x86_64"; then
+ SECP_INT128_CHECK
+ if test x"$has_int128" != x"yes"; then
+ AC_MSG_ERROR([64bit field explicitly requested but neither __int128 support or x86_64 assembly available])
+ fi
+ fi
;;
32bit)
;;
fi
if test x"$req_scalar" = x"auto"; then
- if test x"$set_scalar" = x; then
- SECP_INT128_CHECK
- if test x"$has_int128" = x"yes"; then
- set_scalar=64bit
- fi
+ SECP_INT128_CHECK
+ if test x"$has_int128" = x"yes"; then
+ set_scalar=64bit
fi
if test x"$set_scalar" = x; then
set_scalar=32bit
case $set_scalar in
64bit)
SECP_INT128_CHECK
+ if test x"$has_int128" != x"yes"; then
+ AC_MSG_ERROR([64bit scalar explicitly requested but __int128 support not available])
+ fi
;;
32bit)
;;
fi
if test x"$set_bignum" = x; then
- AC_MSG_ERROR([no working bignum implementation found])
+ set_bignum=no
fi
else
set_bignum=$req_bignum
case $set_bignum in
gmp)
SECP_GMP_CHECK
+ if test x"$has_gmp" != x"yes"; then
+ AC_MSG_ERROR([gmp bignum explicitly requested but libgmp not available])
+ fi
;;
- openssl)
- SECP_OPENSSL_CHECK
+ no)
;;
*)
AC_MSG_ERROR([invalid bignum implementation selection])
esac
fi
+# select assembly optimization
+case $set_asm in
+x86_64)
+ AC_DEFINE(USE_ASM_X86_64, 1, [Define this symbol to enable x86_64 assembly optimizations])
+ ;;
+no)
+ ;;
+*)
+ AC_MSG_ERROR([invalid assembly optimizations])
+ ;;
+esac
+
# select field implementation
case $set_field in
-64bit_asm)
- AC_DEFINE(USE_FIELD_5X52_ASM, 1, [Define this symbol to use the assembly version for the 5x52 field implementation])
- AC_DEFINE(USE_FIELD_5X52, 1, [Define this symbol to use the FIELD_5X52 implementation])
- ;;
64bit)
- AC_DEFINE(USE_FIELD_5X52_INT128, 1, [Define this symbol to use the __int128 version for the 5x52 field implementation])
AC_DEFINE(USE_FIELD_5X52, 1, [Define this symbol to use the FIELD_5X52 implementation])
;;
-gmp)
- AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed])
- AC_DEFINE(USE_FIELD_GMP, 1, [Define this symbol to use the FIELD_GMP implementation])
- ;;
32bit)
AC_DEFINE(USE_FIELD_10X26, 1, [Define this symbol to use the FIELD_10X26 implementation])
;;
# select bignum implementation
case $set_bignum in
gmp)
- AC_DEFINE(HAVE_LIBGMP,1,[Define this symbol if libgmp is installed])
- AC_DEFINE(USE_NUM_GMP, 1, [Define this symbol to use the gmp implementation])
- AC_DEFINE(USE_FIELD_INV_NUM, 1, [Define this symbol to use the USE_FIELD_INV_NUM implementation])
+ AC_DEFINE(HAVE_LIBGMP, 1, [Define this symbol if libgmp is installed])
+ AC_DEFINE(USE_NUM_GMP, 1, [Define this symbol to use the gmp implementation for num])
+ AC_DEFINE(USE_FIELD_INV_NUM, 1, [Define this symbol to use the num-based field inverse implementation])
+ AC_DEFINE(USE_SCALAR_INV_NUM, 1, [Define this symbol to use the num-based scalar inverse implementation])
+ ;;
+no)
+ AC_DEFINE(USE_NUM_NONE, 1, [Define this symbol to use no num implementation])
+ AC_DEFINE(USE_FIELD_INV_BUILTIN, 1, [Define this symbol to use the native field inverse implementation])
+ AC_DEFINE(USE_SCALAR_INV_BUILTIN, 1, [Define this symbol to use the native scalar inverse implementation])
;;
*)
AC_MSG_ERROR([invalid bignum implementation])
if test x"$use_tests" = x"yes"; then
SECP_OPENSSL_CHECK
- if test x"$has_openssl_ec" == x"yes"; then
+ if test x"$has_openssl_ec" = x"yes"; then
AC_DEFINE(ENABLE_OPENSSL_TESTS, 1, [Define this symbol if OpenSSL EC functions are available])
SECP_TEST_INCLUDES="$SSL_CFLAGS $CRYPTO_CFLAGS"
SECP_TEST_LIBS="$CRYPTO_LIBS"
fi
fi
-if test x"$set_field" = x"gmp" || test x"$set_bignum" = x"gmp"; then
+if test x"$set_bignum" = x"gmp"; then
SECP_LIBS="$SECP_LIBS $GMP_LIBS"
+ SECP_INCLUDES="$SECP_INCLUDES $GMP_CPPFLAGS"
fi
if test x"$use_endomorphism" = x"yes"; then
- AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism])
+ AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization])
fi
+AC_MSG_NOTICE([Using assembly optimizations: $set_asm])
AC_MSG_NOTICE([Using field implementation: $set_field])
AC_MSG_NOTICE([Using bignum implementation: $set_bignum])
AC_MSG_NOTICE([Using scalar implementation: $set_scalar])
+AC_MSG_NOTICE([Using endomorphism optimizations: $use_endomorphism])
AC_CONFIG_HEADERS([src/libsecp256k1-config.h])
AC_CONFIG_FILES([Makefile libsecp256k1.pc])
AC_SUBST(SECP_LIBS)
AC_SUBST(SECP_TEST_LIBS)
AC_SUBST(SECP_TEST_INCLUDES)
-AC_SUBST(YASM_BINFMT)
-AM_CONDITIONAL([USE_ASM], [test x"$set_field" == x"64bit_asm"])
AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"])
-AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" != x"no"])
+AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"])
+
+dnl make sure nothing new is exported so that we don't break the cache
+PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH"
+unset PKG_CONFIG_PATH
+PKG_CONFIG_PATH="$PKGCONFIG_PATH_TEMP"
+
AC_OUTPUT
# endif
# endif
-# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
-# if SECP256K1_GNUC_PREREQ(3,0)
-# define SECP256K1_RESTRICT __restrict__
-# elif (defined(_MSC_VER) && _MSC_VER >= 1400)
-# define SECP256K1_RESTRICT __restrict
-# else
-# define SECP256K1_RESTRICT
-# endif
-# else
-# define SECP256K1_RESTRICT restrict
-# endif
-
# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
# if SECP256K1_GNUC_PREREQ(2,7)
# define SECP256K1_INLINE __inline__
* 0: incorrect signature
* -1: invalid public key
* -2: invalid signature
- * In: msg: the message being verified (cannot be NULL)
- * msglen: the length of the message (at most 32)
+ * In: msg32: the 32-byte message hash being verified (cannot be NULL)
* sig: the signature being verified (cannot be NULL)
* siglen: the length of the signature
* pubkey: the public key to verify with (cannot be NULL)
* Requires starting using SECP256K1_START_VERIFY.
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
- const unsigned char *msg,
- int msglen,
+ const unsigned char *msg32,
const unsigned char *sig,
int siglen,
const unsigned char *pubkey,
int pubkeylen
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
+
+/** A pointer to a function to deterministically generate a nonce.
+ * Returns: 1 if a nonce was succesfully generated. 0 will cause signing to fail.
+ * In: msg32: the 32-byte message hash being verified (will not be NULL)
+ * key32: pointer to a 32-byte secret key (will not be NULL)
+ * attempt: how many iterations we have tried to find a nonce.
+ * This will almost always be 0, but different attempt values
+ * are required to result in a different nonce.
+ * data: Arbitrary data pointer that is passed through.
+ * Out: nonce32: pointer to a 32-byte array to be filled by the function.
+ * Except for test cases, this function should compute some cryptographic hash of
+ * the message, the key and the attempt.
+ */
+typedef int (*secp256k1_nonce_function_t)(
+ unsigned char *nonce32,
+ const unsigned char *msg32,
+ const unsigned char *key32,
+ unsigned int attempt,
+ const void *data
+);
+
+/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function. */
+extern const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979;
+
+/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */
+extern const secp256k1_nonce_function_t secp256k1_nonce_function_default;
+
/** Create an ECDSA signature.
* Returns: 1: signature created
- * 0: nonce invalid, try another one
- * In: msg: the message being signed (cannot be NULL)
- * msglen: the length of the message being signed (at most 32)
+ * 0: the nonce generation function failed
+ * In: msg32: the 32-byte message hash being signed (cannot be NULL)
* seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid)
- * nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG)
+ * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
+ * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
* In/Out: siglen: pointer to an int with the length of sig, which will be updated
* to contain the actual signature length (<=72).
* Requires starting using SECP256K1_START_SIGN.
*/
-SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign(
- const unsigned char *msg,
- int msglen,
+int secp256k1_ecdsa_sign(
+ const unsigned char *msg32,
unsigned char *sig,
int *siglen,
const unsigned char *seckey,
- const unsigned char *nonce
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
+ secp256k1_nonce_function_t noncefp,
+ const void *ndata
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Create a compact ECDSA signature (64 byte + recovery id).
* Returns: 1: signature created
- * 0: nonce invalid, try another one
- * In: msg: the message being signed (cannot be NULL)
- * msglen: the length of the message being signed (at most 32)
+ * 0: the nonce generation function failed
+ * In: msg32: the 32-byte message hash being signed (cannot be NULL)
* seckey: pointer to a 32-byte secret key (cannot be NULL, assumed to be valid)
- * nonce: pointer to a 32-byte nonce (cannot be NULL, generated with a cryptographic PRNG)
+ * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
+ * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
* Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL)
* recid: pointer to an int, which will be updated to contain the recovery id (can be NULL)
* Requires starting using SECP256K1_START_SIGN.
*/
-SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_sign_compact(
- const unsigned char *msg,
- int msglen,
+int secp256k1_ecdsa_sign_compact(
+ const unsigned char *msg32,
unsigned char *sig64,
const unsigned char *seckey,
- const unsigned char *nonce,
+ secp256k1_nonce_function_t noncefp,
+ const void *ndata,
int *recid
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Recover an ECDSA public key from a compact signature.
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
* 0: otherwise.
- * In: msg: the message assumed to be signed (cannot be NULL)
- * msglen: the length of the message (at most 32)
+ * In: msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
* sig64: signature as 64 byte array (cannot be NULL)
* compressed: whether to recover a compressed or uncompressed pubkey
* recid: the recovery id (0-3, as returned by ecdsa_sign_compact)
* Requires starting using SECP256K1_START_VERIFY.
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover_compact(
- const unsigned char *msg,
- int msglen,
+ const unsigned char *msg32,
const unsigned char *sig64,
unsigned char *pubkey,
int *pubkeylen,
int compressed,
int recid
-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Verify an ECDSA secret key.
* Returns: 1: secret key is valid
+++ /dev/null
-#! /bin/sh
-command=""
-infile=""
-o_opt=no
-pic=no
-while [ $# -gt 0 ]; do
- case "$1" in
- -DPIC|-fPIC|-fpic|-Kpic|-KPIC)
- if [ "$pic" != "yes" ] ; then
- command="$command -DPIC"
- pic=yes
- fi
- ;;
- -f|-fbin|-faout|-faoutb|-fcoff|-felf|-felf64|-fas86| \
- -fobj|-fwin32|-fwin64|-frdf|-fieee|-fmacho|-fmacho64)
- # it's a file format specifier for nasm.
- command="$command $1"
- ;;
- -f*)
- # maybe a code-generation flag for gcc.
- ;;
- -[Ii]*)
- incdir=`echo "$1" | sed 's/^-[Ii]//'`
- if [ "x$incdir" = x -a "x$2" != x ] ; then
- case "$2" in
- -*) ;;
- *) incdir="$2"; shift;;
- esac
- fi
- if [ "x$incdir" != x ] ; then
- # In the case of NASM, the trailing slash is necessary.
- incdir=`echo "$incdir" | sed 's%/*$%/%'`
- command="$command -I$incdir"
- fi
- ;;
- -o*)
- o_opt=yes
- command="$command $1"
- ;;
- *.asm)
- infile=$1
- command="$command $1"
- ;;
- *)
- command="$command $1"
- ;;
- esac
- shift
-done
-if [ "$o_opt" != yes ] ; then
- # By default, NASM creates an output file
- # in the same directory as the input file.
- outfile="-o `echo $infile | sed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.o"
- command="$command $outfile"
-fi
-echo $command
-exec $command
--- /dev/null
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_BENCH_H_
+#define _SECP256K1_BENCH_H_
+
+#include <stdio.h>
+#include <math.h>
+#include "sys/time.h"
+
+static double gettimedouble(void) {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return tv.tv_usec * 0.000001 + tv.tv_sec;
+}
+
+void run_benchmark(void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) {
+ double min = HUGE_VAL;
+ double sum = 0.0;
+ double max = 0.0;
+ for (int i = 0; i < count; i++) {
+ if (setup) setup(data);
+ double begin = gettimedouble();
+ benchmark(data);
+ double total = gettimedouble() - begin;
+ if (teardown) teardown(data);
+ if (total < min) min = total;
+ if (total > max) max = total;
+ sum += total;
+ }
+ printf("min %.3fus / avg %.3fus / max %.3fus\n", min * 1000000.0 / iter, (sum / count) * 1000000.0 / iter, max * 1000000.0 / iter);
+}
+
+#endif
#include "field_impl.h"
#include "group_impl.h"
#include "scalar_impl.h"
+#include "bench.h"
+
+typedef struct {
+ secp256k1_scalar_t base, x;
+} bench_inv_t;
+
+void bench_inv_setup(void* arg) {
+ bench_inv_t *data = (bench_inv_t*)arg;
-int main(void) {
static const unsigned char init[32] = {
0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13,
0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35,
0x3b, 0x3d, 0x43, 0x47, 0x49, 0x4f, 0x53, 0x59,
0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71, 0x7f, 0x83
};
- static const unsigned char fini[32] = {
- 0xba, 0x28, 0x58, 0xd8, 0xaa, 0x11, 0xd6, 0xf2,
- 0xfa, 0xce, 0x50, 0xb1, 0x67, 0x19, 0xb1, 0xa6,
- 0xe0, 0xaa, 0x84, 0x53, 0xf6, 0x80, 0xfc, 0x23,
- 0x88, 0x3c, 0xd6, 0x74, 0x9f, 0x27, 0x09, 0x03
- };
- secp256k1_ge_start();
- secp256k1_scalar_t base, x;
- secp256k1_scalar_set_b32(&base, init, NULL);
- secp256k1_scalar_set_b32(&x, init, NULL);
- for (int i=0; i<1000000; i++) {
- secp256k1_scalar_inverse(&x, &x);
- secp256k1_scalar_add(&x, &x, &base);
+
+ secp256k1_scalar_set_b32(&data->base, init, NULL);
+ secp256k1_scalar_set_b32(&data->x, init, NULL);
+}
+
+void bench_inv(void* arg) {
+ bench_inv_t *data = (bench_inv_t*)arg;
+
+ for (int i=0; i<20000; i++) {
+ secp256k1_scalar_inverse(&data->x, &data->x);
+ secp256k1_scalar_add(&data->x, &data->x, &data->base);
}
- unsigned char res[32];
- secp256k1_scalar_get_b32(res, &x);
- CHECK(memcmp(res, fini, 32) == 0);
+}
+
+int main(void) {
+ secp256k1_ge_start();
+
+ bench_inv_t data;
+ run_benchmark(bench_inv, bench_inv_setup, NULL, &data, 10, 20000);
+
+ secp256k1_ge_stop();
return 0;
}
--- /dev/null
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#include "include/secp256k1.h"
+#include "util.h"
+#include "bench.h"
+
+typedef struct {
+ unsigned char msg[32];
+ unsigned char sig[64];
+} bench_recover_t;
+
+void bench_recover(void* arg) {
+ bench_recover_t *data = (bench_recover_t*)arg;
+
+ unsigned char pubkey[33];
+ for (int i=0; i<20000; i++) {
+ int pubkeylen = 33;
+ CHECK(secp256k1_ecdsa_recover_compact(data->msg, data->sig, pubkey, &pubkeylen, 1, i % 2));
+ for (int j = 0; j < 32; j++) {
+ data->sig[j + 32] = data->msg[j]; /* Move former message to S. */
+ data->msg[j] = data->sig[j]; /* Move former R to message. */
+ data->sig[j] = pubkey[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */
+ }
+ }
+}
+
+void bench_recover_setup(void* arg) {
+ bench_recover_t *data = (bench_recover_t*)arg;
+
+ for (int i = 0; i < 32; i++) data->msg[i] = 1 + i;
+ for (int i = 0; i < 64; i++) data->sig[i] = 65 + i;
+}
+
+int main(void) {
+ secp256k1_start(SECP256K1_START_VERIFY);
+
+ bench_recover_t data;
+ run_benchmark(bench_recover, bench_recover_setup, NULL, &data, 10, 20000);
+
+ secp256k1_stop();
+ return 0;
+}
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
-#include <stdio.h>
-#include <string.h>
#include "include/secp256k1.h"
#include "util.h"
+#include "bench.h"
-int main(void) {
- secp256k1_start(SECP256K1_START_SIGN);
-
+typedef struct {
unsigned char msg[32];
- unsigned char nonce[32];
unsigned char key[32];
+} bench_sign_t;
- for (int i = 0; i < 32; i++) msg[i] = i + 1;
- for (int i = 0; i < 32; i++) nonce[i] = i + 33;
- for (int i = 0; i < 32; i++) key[i] = i + 65;
+static void bench_sign_setup(void* arg) {
+ bench_sign_t *data = (bench_sign_t*)arg;
- unsigned char sig[64];
+ for (int i = 0; i < 32; i++) data->msg[i] = i + 1;
+ for (int i = 0; i < 32; i++) data->key[i] = i + 65;
+}
+
+static void bench_sign(void* arg) {
+ bench_sign_t *data = (bench_sign_t*)arg;
- for (int i=0; i<1000000; i++) {
+ unsigned char sig[64];
+ for (int i=0; i<20000; i++) {
int recid = 0;
- CHECK(secp256k1_ecdsa_sign_compact(msg, 32, sig, key, nonce, &recid));
+ CHECK(secp256k1_ecdsa_sign_compact(data->msg, sig, data->key, NULL, NULL, &recid));
for (int j = 0; j < 32; j++) {
- nonce[j] = key[j]; /* Move former key to nonce */
- msg[j] = sig[j]; /* Move former R to message. */
- key[j] = sig[j + 32]; /* Move former S to key. */
+ data->msg[j] = sig[j]; /* Move former R to message. */
+ data->key[j] = sig[j + 32]; /* Move former S to key. */
}
}
+}
+
+int main(void) {
+ secp256k1_start(SECP256K1_START_SIGN);
- static const unsigned char fini[64] = {
- 0x92, 0x03, 0xef, 0xf1, 0x58, 0x0b, 0x49, 0x8d,
- 0x22, 0x3d, 0x49, 0x0e, 0xbf, 0x26, 0x50, 0x0e,
- 0x2d, 0x62, 0x90, 0xd7, 0x82, 0xbd, 0x3d, 0x5c,
- 0xa9, 0x10, 0xa5, 0x49, 0xb1, 0xd8, 0x8c, 0xc0,
- 0x5b, 0x5e, 0x9e, 0x68, 0x51, 0x3d, 0xe8, 0xec,
- 0x82, 0x30, 0x82, 0x88, 0x8c, 0xfd, 0xe7, 0x71,
- 0x15, 0x92, 0xfc, 0x14, 0x59, 0x78, 0x31, 0xb3,
- 0xf6, 0x07, 0x91, 0x18, 0x00, 0x8d, 0x4c, 0xb2
- };
- CHECK(memcmp(sig, fini, 64) == 0);
+ bench_sign_t data;
+ run_benchmark(bench_sign, bench_sign_setup, NULL, &data, 10, 20000);
secp256k1_stop();
return 0;
#include "include/secp256k1.h"
#include "util.h"
+#include "bench.h"
-int main(void) {
- secp256k1_start(SECP256K1_START_VERIFY);
-
+typedef struct {
unsigned char msg[32];
- unsigned char sig[64];
-
- for (int i = 0; i < 32; i++) msg[i] = 1 + i;
- for (int i = 0; i < 64; i++) sig[i] = 65 + i;
-
+ unsigned char key[32];
+ unsigned char sig[72];
+ int siglen;
unsigned char pubkey[33];
- for (int i=0; i<1000000; i++) {
- int pubkeylen = 33;
- CHECK(secp256k1_ecdsa_recover_compact(msg, 32, sig, pubkey, &pubkeylen, 1, i % 2));
- for (int j = 0; j < 32; j++) {
- sig[j + 32] = msg[j]; /* Move former message to S. */
- msg[j] = sig[j]; /* Move former R to message. */
- sig[j] = pubkey[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */
- }
+ int pubkeylen;
+} benchmark_verify_t;
+
+static void benchmark_verify(void* arg) {
+ benchmark_verify_t* data = (benchmark_verify_t*)arg;
+
+ for (int i=0; i<20000; i++) {
+ data->sig[data->siglen - 1] ^= (i & 0xFF);
+ data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
+ data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
+ CHECK(secp256k1_ecdsa_verify(data->msg, data->sig, data->siglen, data->pubkey, data->pubkeylen) == (i == 0));
+ data->sig[data->siglen - 1] ^= (i & 0xFF);
+ data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
+ data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
}
+}
+
+int main(void) {
+ secp256k1_start(SECP256K1_START_VERIFY | SECP256K1_START_SIGN);
+
+ benchmark_verify_t data;
+
+ for (int i = 0; i < 32; i++) data.msg[i] = 1 + i;
+ for (int i = 0; i < 32; i++) data.key[i] = 33 + i;
+ data.siglen = 72;
+ secp256k1_ecdsa_sign(data.msg, data.sig, &data.siglen, data.key, NULL, NULL);
+ data.pubkeylen = 33;
+ CHECK(secp256k1_ec_pubkey_create(data.pubkey, &data.pubkeylen, data.key, 1));
- static const unsigned char fini[33] = {
- 0x02,
- 0x52, 0x63, 0xae, 0x9a, 0x9d, 0x47, 0x1f, 0x1a,
- 0xb2, 0x36, 0x65, 0x89, 0x11, 0xe7, 0xcc, 0x86,
- 0xa3, 0xab, 0x97, 0xb6, 0xf1, 0xaf, 0xfd, 0x8f,
- 0x9b, 0x38, 0xb6, 0x18, 0x55, 0xe5, 0xc2, 0x43
- };
- CHECK(memcmp(fini, pubkey, 33) == 0);
+ run_benchmark(benchmark_verify, NULL, NULL, &data, 10, 20000);
secp256k1_stop();
return 0;
#ifndef _SECP256K1_ECDSA_
#define _SECP256K1_ECDSA_
-#include "num.h"
+#include "scalar.h"
+#include "group.h"
+
+static void secp256k1_ecsda_start(void);
+static void secp256k1_ecdsa_stop(void);
typedef struct {
- secp256k1_num_t r, s;
+ secp256k1_scalar_t r, s;
} secp256k1_ecdsa_sig_t;
static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size);
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a);
-static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_num_t *message);
+static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message);
static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid);
-static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_num_t *message, int recid);
-static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *r, const secp256k1_num_t *s);
+static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid);
+static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s);
#endif
#ifndef _SECP256K1_ECDSA_IMPL_H_
#define _SECP256K1_ECDSA_IMPL_H_
-#include "num.h"
+#include "scalar.h"
#include "field.h"
#include "group.h"
#include "ecmult.h"
#include "ecmult_gen.h"
#include "ecdsa.h"
+typedef struct {
+ secp256k1_fe_t order_as_fe;
+ secp256k1_fe_t p_minus_order;
+} secp256k1_ecdsa_consts_t;
+
+static const secp256k1_ecdsa_consts_t *secp256k1_ecdsa_consts = NULL;
+
+static void secp256k1_ecdsa_start(void) {
+ if (secp256k1_ecdsa_consts != NULL)
+ return;
+
+ /* Allocate. */
+ secp256k1_ecdsa_consts_t *ret = (secp256k1_ecdsa_consts_t*)checked_malloc(sizeof(secp256k1_ecdsa_consts_t));
+
+ static const unsigned char order[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+ 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
+ 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41
+ };
+
+ secp256k1_fe_set_b32(&ret->order_as_fe, order);
+ secp256k1_fe_negate(&ret->p_minus_order, &ret->order_as_fe, 1);
+ secp256k1_fe_normalize_var(&ret->p_minus_order);
+
+ /* Set the global pointer. */
+ secp256k1_ecdsa_consts = ret;
+}
+
+static void secp256k1_ecdsa_stop(void) {
+ if (secp256k1_ecdsa_consts == NULL)
+ return;
+
+ secp256k1_ecdsa_consts_t *c = (secp256k1_ecdsa_consts_t*)secp256k1_ecdsa_consts;
+ secp256k1_ecdsa_consts = NULL;
+ free(c);
+}
+
static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size) {
if (sig[0] != 0x30) return 0;
int lenr = sig[3];
if (lenr == 0) return 0;
if (sig[lenr+4] != 0x02) return 0;
if (lens == 0) return 0;
- secp256k1_num_set_bin(&r->r, sig+4, lenr);
- secp256k1_num_set_bin(&r->s, sig+6+lenr, lens);
+ const unsigned char *sp = sig + 6 + lenr;
+ while (lens > 0 && sp[0] == 0) {
+ lens--;
+ sp++;
+ }
+ if (lens > 32) return 0;
+ const unsigned char *rp = sig + 4;
+ while (lenr > 0 && rp[0] == 0) {
+ lenr--;
+ rp++;
+ }
+ if (lenr > 32) return 0;
+ unsigned char ra[32] = {0}, sa[32] = {0};
+ memcpy(ra + 32 - lenr, rp, lenr);
+ memcpy(sa + 32 - lens, sp, lens);
+ int overflow = 0;
+ secp256k1_scalar_set_b32(&r->r, ra, &overflow);
+ if (overflow) return 0;
+ secp256k1_scalar_set_b32(&r->s, sa, &overflow);
+ if (overflow) return 0;
return 1;
}
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a) {
- int lenR = (secp256k1_num_bits(&a->r) + 7)/8;
- if (lenR == 0 || secp256k1_num_get_bit(&a->r, lenR*8-1))
- lenR++;
- int lenS = (secp256k1_num_bits(&a->s) + 7)/8;
- if (lenS == 0 || secp256k1_num_get_bit(&a->s, lenS*8-1))
- lenS++;
+ unsigned char r[33] = {0}, s[33] = {0};
+ secp256k1_scalar_get_b32(&r[1], &a->r);
+ secp256k1_scalar_get_b32(&s[1], &a->s);
+ unsigned char *rp = r, *sp = s;
+ int lenR = 33, lenS = 33;
+ while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; }
+ while (lenS > 1 && sp[0] == 0 && sp[1] < 0x80) { lenS--; sp++; }
if (*size < 6+lenS+lenR)
return 0;
*size = 6 + lenS + lenR;
sig[1] = 4 + lenS + lenR;
sig[2] = 0x02;
sig[3] = lenR;
- secp256k1_num_get_bin(sig+4, lenR, &a->r);
+ memcpy(sig+4, rp, lenR);
sig[4+lenR] = 0x02;
sig[5+lenR] = lenS;
- secp256k1_num_get_bin(sig+lenR+6, lenS, &a->s);
+ memcpy(sig+lenR+6, sp, lenS);
return 1;
}
-static int secp256k1_ecdsa_sig_recompute(secp256k1_num_t *r2, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_num_t *message) {
- const secp256k1_ge_consts_t *c = secp256k1_ge_consts;
-
- if (secp256k1_num_is_neg(&sig->r) || secp256k1_num_is_neg(&sig->s))
- return 0;
- if (secp256k1_num_is_zero(&sig->r) || secp256k1_num_is_zero(&sig->s))
- return 0;
- if (secp256k1_num_cmp(&sig->r, &c->order) >= 0 || secp256k1_num_cmp(&sig->s, &c->order) >= 0)
+static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) {
+ if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s))
return 0;
- int ret = 0;
- secp256k1_num_t sn, u1, u2;
- secp256k1_num_init(&sn);
- secp256k1_num_init(&u1);
- secp256k1_num_init(&u2);
- secp256k1_num_mod_inverse(&sn, &sig->s, &c->order);
- secp256k1_num_mod_mul(&u1, &sn, message, &c->order);
- secp256k1_num_mod_mul(&u2, &sn, &sig->r, &c->order);
+ secp256k1_scalar_t sn, u1, u2;
+ secp256k1_scalar_inverse_var(&sn, &sig->s);
+ secp256k1_scalar_mul(&u1, &sn, message);
+ secp256k1_scalar_mul(&u2, &sn, &sig->r);
secp256k1_gej_t pubkeyj; secp256k1_gej_set_ge(&pubkeyj, pubkey);
secp256k1_gej_t pr; secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1);
- if (!secp256k1_gej_is_infinity(&pr)) {
- secp256k1_fe_t xr; secp256k1_gej_get_x_var(&xr, &pr);
- secp256k1_fe_normalize(&xr);
- unsigned char xrb[32]; secp256k1_fe_get_b32(xrb, &xr);
- secp256k1_num_set_bin(r2, xrb, 32);
- secp256k1_num_mod(r2, &c->order);
- ret = 1;
+ if (secp256k1_gej_is_infinity(&pr)) {
+ return 0;
}
- secp256k1_num_free(&sn);
- secp256k1_num_free(&u1);
- secp256k1_num_free(&u2);
- return ret;
-}
-
-static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_num_t *message, int recid) {
- const secp256k1_ge_consts_t *c = secp256k1_ge_consts;
+ unsigned char c[32];
+ secp256k1_scalar_get_b32(c, &sig->r);
+ secp256k1_fe_t xr;
+ secp256k1_fe_set_b32(&xr, c);
- if (secp256k1_num_is_neg(&sig->r) || secp256k1_num_is_neg(&sig->s))
- return 0;
- if (secp256k1_num_is_zero(&sig->r) || secp256k1_num_is_zero(&sig->s))
+ // We now have the recomputed R point in pr, and its claimed x coordinate (modulo n)
+ // in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p),
+ // compute the remainder modulo n, and compare it to xr. However:
+ //
+ // xr == X(pr) mod n
+ // <=> exists h. (xr + h * n < p && xr + h * n == X(pr))
+ // [Since 2 * n > p, h can only be 0 or 1]
+ // <=> (xr == X(pr)) || (xr + n < p && xr + n == X(pr))
+ // [In Jacobian coordinates, X(pr) is pr.x / pr.z^2 mod p]
+ // <=> (xr == pr.x / pr.z^2 mod p) || (xr + n < p && xr + n == pr.x / pr.z^2 mod p)
+ // [Multiplying both sides of the equations by pr.z^2 mod p]
+ // <=> (xr * pr.z^2 mod p == pr.x) || (xr + n < p && (xr + n) * pr.z^2 mod p == pr.x)
+ //
+ // Thus, we can avoid the inversion, but we have to check both cases separately.
+ // secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test.
+ if (secp256k1_gej_eq_x_var(&xr, &pr)) {
+ // xr.x == xr * xr.z^2 mod p, so the signature is valid.
+ return 1;
+ }
+ if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_consts->p_minus_order) >= 0) {
+ // xr + p >= n, so we can skip testing the second case.
return 0;
- if (secp256k1_num_cmp(&sig->r, &c->order) >= 0 || secp256k1_num_cmp(&sig->s, &c->order) >= 0)
+ }
+ secp256k1_fe_add(&xr, &secp256k1_ecdsa_consts->order_as_fe);
+ if (secp256k1_gej_eq_x_var(&xr, &pr)) {
+ // (xr + n) * pr.z^2 mod p == pr.x, so the signature is valid.
+ return 1;
+ }
+ return 0;
+}
+
+static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) {
+ if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s))
return 0;
- secp256k1_num_t rx;
- secp256k1_num_init(&rx);
- secp256k1_num_copy(&rx, &sig->r);
+ unsigned char brx[32];
+ secp256k1_scalar_get_b32(brx, &sig->r);
+ secp256k1_fe_t fx;
+ VERIFY_CHECK(secp256k1_fe_set_b32(&fx, brx)); /* brx comes from a scalar, so is less than the order; certainly less than p */
if (recid & 2) {
- secp256k1_num_add(&rx, &rx, &c->order);
- if (secp256k1_num_cmp(&rx, &secp256k1_fe_consts->p) >= 0)
+ if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_consts->p_minus_order) >= 0)
return 0;
+ secp256k1_fe_add(&fx, &secp256k1_ecdsa_consts->order_as_fe);
}
- unsigned char brx[32];
- secp256k1_num_get_bin(brx, 32, &rx);
- secp256k1_num_free(&rx);
- secp256k1_fe_t fx;
- secp256k1_fe_set_b32(&fx, brx);
secp256k1_ge_t x;
- if (!secp256k1_ge_set_xo(&x, &fx, recid & 1))
+ if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1))
return 0;
secp256k1_gej_t xj;
secp256k1_gej_set_ge(&xj, &x);
- secp256k1_num_t rn, u1, u2;
- secp256k1_num_init(&rn);
- secp256k1_num_init(&u1);
- secp256k1_num_init(&u2);
- secp256k1_num_mod_inverse(&rn, &sig->r, &c->order);
- secp256k1_num_mod_mul(&u1, &rn, message, &c->order);
- secp256k1_num_sub(&u1, &c->order, &u1);
- secp256k1_num_mod_mul(&u2, &rn, &sig->s, &c->order);
+ secp256k1_scalar_t rn, u1, u2;
+ secp256k1_scalar_inverse_var(&rn, &sig->r);
+ secp256k1_scalar_mul(&u1, &rn, message);
+ secp256k1_scalar_negate(&u1, &u1);
+ secp256k1_scalar_mul(&u2, &rn, &sig->s);
secp256k1_gej_t qj;
secp256k1_ecmult(&qj, &xj, &u2, &u1);
secp256k1_ge_set_gej_var(pubkey, &qj);
- secp256k1_num_free(&rn);
- secp256k1_num_free(&u1);
- secp256k1_num_free(&u2);
return !secp256k1_gej_is_infinity(&qj);
}
-static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_num_t *message) {
- secp256k1_num_t r2;
- secp256k1_num_init(&r2);
- int ret = 0;
- ret = secp256k1_ecdsa_sig_recompute(&r2, sig, pubkey, message) && secp256k1_num_cmp(&sig->r, &r2) == 0;
- secp256k1_num_free(&r2);
- return ret;
-}
-
static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) {
secp256k1_gej_t rp;
secp256k1_ecmult_gen(&rp, nonce);
secp256k1_fe_normalize(&r.y);
secp256k1_fe_get_b32(b, &r.x);
int overflow = 0;
- secp256k1_scalar_t sigr;
- secp256k1_scalar_set_b32(&sigr, b, &overflow);
+ secp256k1_scalar_set_b32(&sig->r, b, &overflow);
+ if (secp256k1_scalar_is_zero(&sig->r)) {
+ /* P.x = order is on the curve, so technically sig->r could end up zero, which would be an invalid signature. */
+ secp256k1_gej_clear(&rp);
+ secp256k1_ge_clear(&r);
+ return 0;
+ }
if (recid)
*recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0);
secp256k1_scalar_t n;
- secp256k1_scalar_mul(&n, &sigr, seckey);
+ secp256k1_scalar_mul(&n, &sig->r, seckey);
secp256k1_scalar_add(&n, &n, message);
- secp256k1_scalar_t sigs;
- secp256k1_scalar_inverse(&sigs, nonce);
- secp256k1_scalar_mul(&sigs, &sigs, &n);
+ secp256k1_scalar_inverse(&sig->s, nonce);
+ secp256k1_scalar_mul(&sig->s, &sig->s, &n);
secp256k1_scalar_clear(&n);
secp256k1_gej_clear(&rp);
secp256k1_ge_clear(&r);
- if (secp256k1_scalar_is_zero(&sigs))
+ if (secp256k1_scalar_is_zero(&sig->s))
return 0;
- if (secp256k1_scalar_is_high(&sigs)) {
- secp256k1_scalar_negate(&sigs, &sigs);
+ if (secp256k1_scalar_is_high(&sig->s)) {
+ secp256k1_scalar_negate(&sig->s, &sig->s);
if (recid)
*recid ^= 1;
}
- secp256k1_scalar_get_num(&sig->s, &sigs);
- secp256k1_scalar_get_num(&sig->r, &sigr);
return 1;
}
-static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *r, const secp256k1_num_t *s) {
- secp256k1_num_copy(&sig->r, r);
- secp256k1_num_copy(&sig->s, s);
+static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s) {
+ sig->r = *r;
+ sig->s = *s;
}
#endif
#include "group.h"
#include "scalar.h"
-#include "num.h"
static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size);
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed);
static int secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed);
static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak);
-static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_num_t *tweak);
+static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak);
static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak);
-static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_num_t *tweak);
+static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak);
#endif
#include "eckey.h"
-#include "num.h"
+#include "scalar.h"
#include "field.h"
#include "group.h"
#include "ecmult_gen.h"
static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size) {
if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) {
secp256k1_fe_t x;
- secp256k1_fe_set_b32(&x, pub+1);
- return secp256k1_ge_set_xo(elem, &x, pub[0] == 0x03);
+ return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == 0x03);
} else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) {
secp256k1_fe_t x, y;
- secp256k1_fe_set_b32(&x, pub+1);
- secp256k1_fe_set_b32(&y, pub+33);
+ if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) {
+ return 0;
+ }
secp256k1_ge_set_xy(elem, &x, &y);
if ((pub[0] == 0x06 || pub[0] == 0x07) && secp256k1_fe_is_odd(&y) != (pub[0] == 0x07))
return 0;
- return secp256k1_ge_is_valid(elem);
+ return secp256k1_ge_is_valid_var(elem);
} else {
return 0;
}
if (secp256k1_ge_is_infinity(elem)) {
return 0;
}
- secp256k1_fe_normalize(&elem->x);
- secp256k1_fe_normalize(&elem->y);
+ secp256k1_fe_normalize_var(&elem->x);
+ secp256k1_fe_normalize_var(&elem->y);
secp256k1_fe_get_b32(&pub[1], &elem->x);
if (compressed) {
*size = 33;
return 1;
}
-static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_num_t *tweak) {
- if (secp256k1_num_cmp(tweak, &secp256k1_ge_consts->order) >= 0)
- return 0;
-
+static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) {
secp256k1_gej_t pt;
secp256k1_gej_set_ge(&pt, key);
- secp256k1_num_t one;
- secp256k1_num_init(&one);
- secp256k1_num_set_int(&one, 1);
+ secp256k1_scalar_t one;
+ secp256k1_scalar_set_int(&one, 1);
secp256k1_ecmult(&pt, &pt, &one, tweak);
- secp256k1_num_free(&one);
if (secp256k1_gej_is_infinity(&pt))
return 0;
return 1;
}
-static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_num_t *tweak) {
- if (secp256k1_num_is_zero(tweak))
- return 0;
- if (secp256k1_num_cmp(tweak, &secp256k1_ge_consts->order) >= 0)
+static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) {
+ if (secp256k1_scalar_is_zero(tweak))
return 0;
- secp256k1_num_t zero;
- secp256k1_num_init(&zero);
- secp256k1_num_set_int(&zero, 0);
+ secp256k1_scalar_t zero;
+ secp256k1_scalar_set_int(&zero, 0);
secp256k1_gej_t pt;
secp256k1_gej_set_ge(&pt, key);
secp256k1_ecmult(&pt, &pt, tweak, &zero);
- secp256k1_num_free(&zero);
secp256k1_ge_set_gej(key, &pt);
return 1;
}
static void secp256k1_ecmult_stop(void);
/** Double multiply: R = na*A + ng*G */
-static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_num_t *na, const secp256k1_num_t *ng);
+static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng);
#endif
* precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0..63).
* None of the resulting prec group elements have a known scalar, and neither do any of
* the intermediate sums while computing a*G.
- * To make memory access uniform, the bytes of prec(i, n_i) are sliced per value of n_i. */
- unsigned char prec[64][sizeof(secp256k1_ge_t)][16]; /* prec[j][k][i] = k'th byte of (16^j * i * G + U_i) */
+ */
+ secp256k1_fe_t prec[64][16][2]; /* prec[j][i] = (16^j * i * G + U_i).{x,y} */
} secp256k1_ecmult_gen_consts_t;
static const secp256k1_ecmult_gen_consts_t *secp256k1_ecmult_gen_consts = NULL;
return;
/* Allocate the precomputation table. */
- secp256k1_ecmult_gen_consts_t *ret = (secp256k1_ecmult_gen_consts_t*)malloc(sizeof(secp256k1_ecmult_gen_consts_t));
+ secp256k1_ecmult_gen_consts_t *ret = (secp256k1_ecmult_gen_consts_t*)checked_malloc(sizeof(secp256k1_ecmult_gen_consts_t));
/* get the generator */
const secp256k1_ge_t *g = &secp256k1_ge_consts->g;
{
static const unsigned char nums_b32[32] = "The scalar for this x is unknown";
secp256k1_fe_t nums_x;
- secp256k1_fe_set_b32(&nums_x, nums_b32);
+ VERIFY_CHECK(secp256k1_fe_set_b32(&nums_x, nums_b32));
secp256k1_ge_t nums_ge;
- VERIFY_CHECK(secp256k1_ge_set_xo(&nums_ge, &nums_x, 0));
+ VERIFY_CHECK(secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0));
secp256k1_gej_set_ge(&nums_gej, &nums_ge);
/* Add G to make the bits in x uniformly distributed. */
secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, g);
}
for (int j=0; j<64; j++) {
for (int i=0; i<16; i++) {
- const unsigned char* raw = (const unsigned char*)(&prec[j*16 + i]);
- for (size_t k=0; k<sizeof(secp256k1_ge_t); k++)
- ret->prec[j][k][i] = raw[k];
+ VERIFY_CHECK(!secp256k1_ge_is_infinity(&prec[j*16 + i]));
+ ret->prec[j][i][0] = prec[j*16 + i].x;
+ ret->prec[j][i][1] = prec[j*16 + i].y;
}
}
const secp256k1_ecmult_gen_consts_t *c = secp256k1_ecmult_gen_consts;
secp256k1_gej_set_infinity(r);
secp256k1_ge_t add;
+ add.infinity = 0;
int bits;
for (int j=0; j<64; j++) {
bits = secp256k1_scalar_get_bits(gn, j * 4, 4);
- for (size_t k=0; k<sizeof(secp256k1_ge_t); k++)
- ((unsigned char*)(&add))[k] = c->prec[j][k][bits];
+ for (int i=0; i<16; i++) {
+ secp256k1_fe_cmov(&add.x, &c->prec[j][i][0], i == bits);
+ secp256k1_fe_cmov(&add.y, &c->prec[j][i][1], i == bits);
+ }
secp256k1_gej_add_ge(r, r, &add);
}
bits = 0;
#ifndef _SECP256K1_ECMULT_IMPL_H_
#define _SECP256K1_ECMULT_IMPL_H_
-#include "num.h"
#include "group.h"
+#include "scalar.h"
#include "ecmult.h"
/* optimal for 128-bit and 256-bit exponents. */
#define WINDOW_A 5
/** larger numbers may result in slightly better performance, at the cost of
- exponentially larger precomputed tables. WINDOW_G == 14 results in 640 KiB. */
-#define WINDOW_G 14
+ exponentially larger precomputed tables. */
+#ifdef USE_ENDOMORPHISM
+/** Two tables for window size 15: 1.375 MiB. */
+#define WINDOW_G 15
+#else
+/** One table for window size 16: 1.375 MiB. */
+#define WINDOW_G 16
+#endif
/** Fill a table 'pre' with precomputed odd multiples of a. W determines the size of the table.
* pre will contains the values [1*a,3*a,5*a,...,(2^(w-1)-1)*a], so it needs place for
static void secp256k1_ecmult_table_precomp_ge_var(secp256k1_ge_t *pre, const secp256k1_gej_t *a, int w) {
const int table_size = 1 << (w-2);
- secp256k1_gej_t prej[table_size];
+ secp256k1_gej_t *prej = checked_malloc(sizeof(secp256k1_gej_t) * table_size);
prej[0] = *a;
secp256k1_gej_t d; secp256k1_gej_double_var(&d, a);
for (int i=1; i<table_size; i++) {
secp256k1_gej_add_var(&prej[i], &d, &prej[i-1]);
}
secp256k1_ge_set_all_gej_var(table_size, pre, prej);
+ free(prej);
}
/** The number of entries a table with precomputed multiples needs to have. */
typedef struct {
/* For accelerating the computation of a*P + b*G: */
secp256k1_ge_t pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of the generator */
+#ifdef USE_ENDOMORPHISM
secp256k1_ge_t pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of 2^128*generator */
+#endif
} secp256k1_ecmult_consts_t;
static const secp256k1_ecmult_consts_t *secp256k1_ecmult_consts = NULL;
return;
/* Allocate the precomputation table. */
- secp256k1_ecmult_consts_t *ret = (secp256k1_ecmult_consts_t*)malloc(sizeof(secp256k1_ecmult_consts_t));
+ secp256k1_ecmult_consts_t *ret = (secp256k1_ecmult_consts_t*)checked_malloc(sizeof(secp256k1_ecmult_consts_t));
/* get the generator */
const secp256k1_ge_t *g = &secp256k1_ge_consts->g;
secp256k1_gej_t gj; secp256k1_gej_set_ge(&gj, g);
+#ifdef USE_ENDOMORPHISM
/* calculate 2^128*generator */
secp256k1_gej_t g_128j = gj;
for (int i=0; i<128; i++)
secp256k1_gej_double_var(&g_128j, &g_128j);
+#endif
/* precompute the tables with odd multiples */
secp256k1_ecmult_table_precomp_ge_var(ret->pre_g, &gj, WINDOW_G);
+#ifdef USE_ENDOMORPHISM
secp256k1_ecmult_table_precomp_ge_var(ret->pre_g_128, &g_128j, WINDOW_G);
+#endif
/* Set the global pointer to the precomputation table. */
secp256k1_ecmult_consts = ret;
* with the following guarantees:
* - each wnaf[i] is either 0, or an odd integer between -(1<<(w-1) - 1) and (1<<(w-1) - 1)
* - two non-zero entries in wnaf are separated by at least w-1 zeroes.
- * - the index of the highest non-zero entry in wnaf (=return value-1) is at most bits, where
- * bits is the number of bits necessary to represent the absolute value of the input.
+ * - the number of set values in wnaf is returned. This number is at most 256, and at most one more
+ * - than the number of bits in the (absolute value) of the input.
*/
-static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_num_t *a, int w) {
- int ret = 0;
- int zeroes = 0;
- secp256k1_num_t x;
- secp256k1_num_copy(&x, a);
+static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w) {
+ secp256k1_scalar_t s = *a;
+
int sign = 1;
- if (secp256k1_num_is_neg(&x)) {
+ if (secp256k1_scalar_get_bits(&s, 255, 1)) {
+ secp256k1_scalar_negate(&s, &s);
sign = -1;
- secp256k1_num_negate(&x);
}
- while (!secp256k1_num_is_zero(&x)) {
- while (!secp256k1_num_is_odd(&x)) {
- zeroes++;
- secp256k1_num_shift(&x, 1);
+
+ int set_bits = 0;
+ int bit = 0;
+ while (bit < 256) {
+ if (secp256k1_scalar_get_bits(&s, bit, 1) == 0) {
+ bit++;
+ continue;
+ }
+ while (set_bits < bit) {
+ wnaf[set_bits++] = 0;
}
- int word = secp256k1_num_shift(&x, w);
- while (zeroes) {
- wnaf[ret++] = 0;
- zeroes--;
+ int now = w;
+ if (bit + now > 256) {
+ now = 256 - bit;
}
+ int word = secp256k1_scalar_get_bits_var(&s, bit, now);
if (word & (1 << (w-1))) {
- secp256k1_num_inc(&x);
- wnaf[ret++] = sign * (word - (1 << w));
+ secp256k1_scalar_add_bit(&s, bit + w);
+ wnaf[set_bits++] = sign * (word - (1 << w));
} else {
- wnaf[ret++] = sign * word;
+ wnaf[set_bits++] = sign * word;
}
- zeroes = w-1;
+ bit += now;
}
- return ret;
+ return set_bits;
}
-static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_num_t *na, const secp256k1_num_t *ng) {
+static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng) {
const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts;
#ifdef USE_ENDOMORPHISM
- secp256k1_num_t na_1, na_lam;
+ secp256k1_scalar_t na_1, na_lam;
/* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */
- secp256k1_gej_split_exp_var(&na_1, &na_lam, na);
+ secp256k1_scalar_split_lambda_var(&na_1, &na_lam, na);
/* build wnaf representation for na_1 and na_lam. */
- int wnaf_na_1[129]; int bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A);
- int wnaf_na_lam[129]; int bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, &na_lam, WINDOW_A);
+ int wnaf_na_1[130]; int bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A);
+ int wnaf_na_lam[130]; int bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, &na_lam, WINDOW_A);
+ VERIFY_CHECK(bits_na_1 <= 130);
+ VERIFY_CHECK(bits_na_lam <= 130);
int bits = bits_na_1;
if (bits_na_lam > bits) bits = bits_na_lam;
#else
/* build wnaf representation for na. */
- int wnaf_na[257]; int bits_na = secp256k1_ecmult_wnaf(wnaf_na, na, WINDOW_A);
+ int wnaf_na[256]; int bits_na = secp256k1_ecmult_wnaf(wnaf_na, na, WINDOW_A);
int bits = bits_na;
#endif
secp256k1_gej_t pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)];
for (int i=0; i<ECMULT_TABLE_SIZE(WINDOW_A); i++)
secp256k1_gej_mul_lambda(&pre_a_lam[i], &pre_a[i]);
-#endif
/* Splitted G factors. */
- secp256k1_num_t ng_1, ng_128;
+ secp256k1_scalar_t ng_1, ng_128;
/* split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit) */
- secp256k1_num_split(&ng_1, &ng_128, ng, 128);
+ secp256k1_scalar_split_128(&ng_1, &ng_128, ng);
/* Build wnaf representation for ng_1 and ng_128 */
int wnaf_ng_1[129]; int bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G);
int wnaf_ng_128[129]; int bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, &ng_128, WINDOW_G);
if (bits_ng_1 > bits) bits = bits_ng_1;
if (bits_ng_128 > bits) bits = bits_ng_128;
+#else
+ int wnaf_ng[257]; int bits_ng = secp256k1_ecmult_wnaf(wnaf_ng, ng, WINDOW_G);
+ if (bits_ng > bits) bits = bits_ng;
+#endif
secp256k1_gej_set_infinity(r);
secp256k1_gej_t tmpj;
ECMULT_TABLE_GET_GEJ(&tmpj, pre_a_lam, n, WINDOW_A);
secp256k1_gej_add_var(r, r, &tmpj);
}
-#else
- if (i < bits_na && (n = wnaf_na[i])) {
- ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A);
- secp256k1_gej_add_var(r, r, &tmpj);
- }
-#endif
if (i < bits_ng_1 && (n = wnaf_ng_1[i])) {
ECMULT_TABLE_GET_GE(&tmpa, c->pre_g, n, WINDOW_G);
secp256k1_gej_add_ge_var(r, r, &tmpa);
ECMULT_TABLE_GET_GE(&tmpa, c->pre_g_128, n, WINDOW_G);
secp256k1_gej_add_ge_var(r, r, &tmpa);
}
+#else
+ if (i < bits_na && (n = wnaf_na[i])) {
+ ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A);
+ secp256k1_gej_add_var(r, r, &tmpj);
+ }
+ if (i < bits_ng && (n = wnaf_ng[i])) {
+ ECMULT_TABLE_GET_GE(&tmpa, c->pre_g, n, WINDOW_G);
+ secp256k1_gej_add_ge_var(r, r, &tmpa);
+ }
+#endif
}
}
#include "libsecp256k1-config.h"
#endif
-#if defined(USE_FIELD_GMP)
-#include "field_gmp.h"
-#elif defined(USE_FIELD_10X26)
+#if defined(USE_FIELD_10X26)
#include "field_10x26.h"
#elif defined(USE_FIELD_5X52)
#include "field_5x52.h"
#endif
typedef struct {
+#ifndef USE_NUM_NONE
secp256k1_num_t p;
+#endif
+ secp256k1_fe_t order;
} secp256k1_fe_consts_t;
static const secp256k1_fe_consts_t *secp256k1_fe_consts = NULL;
/** Normalize a field element. */
static void secp256k1_fe_normalize(secp256k1_fe_t *r);
+/** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */
+static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r);
+
+/** Normalize a field element, without constant-time guarantee. */
+static void secp256k1_fe_normalize_var(secp256k1_fe_t *r);
+
+/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field
+ * implementation may optionally normalize the input, but this should not be relied upon. */
+static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r);
+
+/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field
+ * implementation may optionally normalize the input, but this should not be relied upon. */
+static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r);
+
/** Set a field element equal to a small integer. Resulting field element is normalized. */
static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a);
/** Check the "oddness" of a field element. Requires the input to be normalized. */
static int secp256k1_fe_is_odd(const secp256k1_fe_t *a);
+/** Compare two field elements. Requires magnitude-1 inputs. */
+static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
+
/** Compare two field elements. Requires both inputs to be normalized */
-static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
+static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
-/** Set a field element equal to 32-byte big endian value. Resulting field element is normalized. */
-static void secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a);
+/** Set a field element equal to 32-byte big endian value. If succesful, the resulting field element is normalized. */
+static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a);
/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */
static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a);
/** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8.
* The output magnitude is 1 (but not guaranteed to be normalized). */
-static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t *b);
+static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b);
/** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8.
* The output magnitude is 1 (but not guaranteed to be normalized). */
/** Sets a field element to be the (modular) square root (if any exist) of another. Requires the
* input's magnitude to be at most 8. The output magnitude is 1 (but not guaranteed to be
* normalized). Return value indicates whether a square root was found. */
-static int secp256k1_fe_sqrt(secp256k1_fe_t *r, const secp256k1_fe_t *a);
+static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a);
/** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be
* at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */
/** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be
* at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and
* outputs must not overlap in memory. */
-static void secp256k1_fe_inv_all(size_t len, secp256k1_fe_t r[len], const secp256k1_fe_t a[len]);
-
-/** Potentially faster version of secp256k1_fe_inv_all, without constant-time guarantee. */
static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t r[len], const secp256k1_fe_t a[len]);
-
/** Convert a field element to a hexadecimal string. */
static void secp256k1_fe_get_hex(char *r, int *rlen, const secp256k1_fe_t *a);
/** Convert a hexadecimal string to a field element. */
-static void secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen);
+static int secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen);
+
+/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */
+static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag);
#endif
r &= (d[8] <= 0x3FFFFFFUL * m);
r &= (d[9] <= 0x03FFFFFUL * m);
r &= (a->magnitude >= 0);
+ r &= (a->magnitude <= 32);
if (a->normalized) {
r &= (a->magnitude <= 1);
if (r && (d[9] == 0x03FFFFFUL)) {
#endif
}
+static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) {
+ uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
+ t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
+
+ /* Reduce t9 at the start so there will be at most a single carry from the first pass */
+ uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x3D1UL; t1 += (x << 6);
+ t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL;
+
+ /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t9 >> 23 == 0);
+
+ r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
+ r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9;
+
+#ifdef VERIFY
+ r->magnitude = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) {
+ uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
+ t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
+
+ /* Reduce t9 at the start so there will be at most a single carry from the first pass */
+ uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
+ uint32_t m;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x3D1UL; t1 += (x << 6);
+ t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8;
+
+ /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t9 >> 23 == 0);
+
+ /* At most a single final reduction is needed; check if the value is >= the field characteristic */
+ x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL)
+ & ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL));
+
+ if (x) {
+ t0 += 0x3D1UL; t1 += (x << 6);
+ t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL;
+
+ /* If t9 didn't carry to bit 22 already, then it should have after any final reduction */
+ VERIFY_CHECK(t9 >> 22 == x);
+
+ /* Mask off the possible multiple of 2^256 from the final reduction */
+ t9 &= 0x03FFFFFUL;
+ }
+
+ r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
+ r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9;
+
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) {
+ uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
+ t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
+
+ /* Reduce t9 at the start so there will be at most a single carry from the first pass */
+ uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
+
+ /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
+ uint32_t z0, z1;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x3D1UL; t1 += (x << 6);
+ t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL; z0 = t0; z1 = t0 ^ 0x3D0UL;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8;
+ z0 |= t9; z1 &= t9 ^ 0x3C00000UL;
+
+ /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t9 >> 23 == 0);
+
+ return (z0 == 0) | (z1 == 0x3FFFFFFUL);
+}
+
+static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) {
+ uint32_t t0 = r->n[0], t9 = r->n[9];
+
+ /* Reduce t9 at the start so there will be at most a single carry from the first pass */
+ uint32_t x = t9 >> 22;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x3D1UL;
+
+ /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
+ uint32_t z0 = t0 & 0x3FFFFFFUL, z1 = z0 ^ 0x3D0UL;
+
+ /* Fast return path should catch the majority of cases */
+ if ((z0 != 0UL) & (z1 != 0x3FFFFFFUL))
+ return 0;
+
+ uint32_t t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
+ t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8];
+ t9 &= 0x03FFFFFUL;
+ t1 += (x << 6);
+
+ t1 += (t0 >> 26); t0 = z0;
+ t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL;
+ t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2;
+ t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3;
+ t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; z0 |= t4; z1 &= t4;
+ t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; z0 |= t5; z1 &= t5;
+ t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; z0 |= t6; z1 &= t6;
+ t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; z0 |= t7; z1 &= t7;
+ t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; z0 |= t8; z1 &= t8;
+ z0 |= t9; z1 &= t9 ^ 0x3C00000UL;
+
+ /* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t9 >> 23 == 0);
+
+ return (z0 == 0) | (z1 == 0x3FFFFFFUL);
+}
+
SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
r->n[0] = a;
r->n[1] = r->n[2] = r->n[3] = r->n[4] = r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0;
}
}
-SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
+static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
#ifdef VERIFY
VERIFY_CHECK(a->normalized);
VERIFY_CHECK(b->normalized);
secp256k1_fe_verify(a);
secp256k1_fe_verify(b);
#endif
- const uint32_t *t = a->n, *u = b->n;
- return ((t[0]^u[0]) | (t[1]^u[1]) | (t[2]^u[2]) | (t[3]^u[3]) | (t[4]^u[4])
- | (t[5]^u[5]) | (t[6]^u[6]) | (t[7]^u[7]) | (t[8]^u[8]) | (t[9]^u[9])) == 0;
+ for (int i = 9; i >= 0; i--) {
+ if (a->n[i] > b->n[i]) return 1;
+ if (a->n[i] < b->n[i]) return -1;
+ }
+ return 0;
}
-static void secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
+static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0;
r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0;
for (int i=0; i<32; i++) {
r->n[limb] |= (uint32_t)((a[31-i] >> (2*j)) & 0x3) << shift;
}
}
+ if (r->n[9] == 0x3FFFFFUL && (r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL && (r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL) {
+ return 0;
+ }
#ifdef VERIFY
r->magnitude = 1;
r->normalized = 1;
secp256k1_fe_verify(r);
#endif
+ return 1;
}
/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */
#define VERIFY_BITS(x, n) do { } while(0)
#endif
-SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint32_t *a, const uint32_t *b, uint32_t *r) {
+SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b) {
VERIFY_BITS(a[0], 30);
VERIFY_BITS(a[1], 30);
VERIFY_BITS(a[2], 30);
/* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */
}
-SECP256K1_INLINE static void secp256k1_fe_sqr_inner(const uint32_t *a, uint32_t *r) {
+SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a) {
VERIFY_BITS(a[0], 30);
VERIFY_BITS(a[1], 30);
VERIFY_BITS(a[2], 30);
}
-static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
+static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) {
#ifdef VERIFY
VERIFY_CHECK(a->magnitude <= 8);
VERIFY_CHECK(b->magnitude <= 8);
secp256k1_fe_verify(a);
secp256k1_fe_verify(b);
+ VERIFY_CHECK(r != b);
#endif
- secp256k1_fe_mul_inner(a->n, b->n, r->n);
+ secp256k1_fe_mul_inner(r->n, a->n, b->n);
#ifdef VERIFY
r->magnitude = 1;
r->normalized = 0;
VERIFY_CHECK(a->magnitude <= 8);
secp256k1_fe_verify(a);
#endif
- secp256k1_fe_sqr_inner(a->n, r->n);
+ secp256k1_fe_sqr_inner(r->n, a->n);
#ifdef VERIFY
r->magnitude = 1;
r->normalized = 0;
#endif
}
+static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) {
+ uint32_t mask0 = flag + ~((uint32_t)0), mask1 = ~mask0;
+ r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
+ r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
+ r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
+ r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
+ r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1);
+ r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1);
+ r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1);
+ r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1);
+ r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1);
+ r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1);
+#ifdef VERIFY
+ if (flag) {
+ r->magnitude = a->magnitude;
+ r->normalized = a->normalized;
+ }
+#endif
+}
+
#endif
+++ /dev/null
- ;; Added by Diederik Huys, March 2013
- ;;
- ;; Provided public procedures:
- ;; secp256k1_fe_mul_inner
- ;; secp256k1_fe_sqr_inner
- ;;
- ;; Needed tools: YASM (http://yasm.tortall.net)
- ;;
- ;;
-
- BITS 64
-
-%ifidn __OUTPUT_FORMAT__,macho64
-%define SYM(x) _ %+ x
-%else
-%define SYM(x) x
-%endif
-
- ;; Procedure ExSetMult
- ;; Register Layout:
- ;; INPUT: rdi = a->n
- ;; rsi = b->n
- ;; rdx = r->a
- ;;
- ;; INTERNAL: rdx:rax = multiplication accumulator
- ;; r9:r8 = c
- ;; r10-r13 = t0-t3
- ;; r14 = b.n[0] / t4
- ;; r15 = b.n[1] / t5
- ;; rbx = b.n[2] / t6
- ;; rcx = b.n[3] / t7
- ;; rbp = Constant 0FFFFFFFFFFFFFh / t8
- ;; rsi = b.n / b.n[4] / t9
-
- GLOBAL SYM(secp256k1_fe_mul_inner)
- ALIGN 32
-SYM(secp256k1_fe_mul_inner):
- push rbp
- push rbx
- push r12
- push r13
- push r14
- push r15
- push rdx
- mov r14,[rsi+8*0] ; preload b.n[0]. This will be the case until
- ; b.n[0] is no longer needed, then we reassign
- ; r14 to t4
- ;; c=a.n[0] * b.n[0]
- mov rax,[rdi+0*8] ; load a.n[0]
- mov rbp,0FFFFFFFFFFFFFh
- mul r14 ; rdx:rax=a.n[0]*b.n[0]
- mov r15,[rsi+1*8]
- mov r10,rbp ; load modulus into target register for t0
- mov r8,rax
- and r10,rax ; only need lower qword of c
- shrd r8,rdx,52
- xor r9,r9 ; c < 2^64, so we ditch the HO part
-
- ;; c+=a.n[0] * b.n[1] + a.n[1] * b.n[0]
- mov rax,[rdi+0*8]
- mul r15
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+1*8]
- mul r14
- mov r11,rbp
- mov rbx,[rsi+2*8]
- add r8,rax
- adc r9,rdx
- and r11,r8
- shrd r8,r9,52
- xor r9,r9
-
- ;; c+=a.n[0 1 2] * b.n[2 1 0]
- mov rax,[rdi+0*8]
- mul rbx
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+1*8]
- mul r15
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+2*8]
- mul r14
- mov r12,rbp
- mov rcx,[rsi+3*8]
- add r8,rax
- adc r9,rdx
- and r12,r8
- shrd r8,r9,52
- xor r9,r9
-
- ;; c+=a.n[0 1 2 3] * b.n[3 2 1 0]
- mov rax,[rdi+0*8]
- mul rcx
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+1*8]
- mul rbx
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+2*8]
- mul r15
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+3*8]
- mul r14
- mov r13,rbp
- mov rsi,[rsi+4*8] ; load b.n[4] and destroy pointer
- add r8,rax
- adc r9,rdx
- and r13,r8
-
- shrd r8,r9,52
- xor r9,r9
-
-
- ;; c+=a.n[0 1 2 3 4] * b.n[4 3 2 1 0]
- mov rax,[rdi+0*8]
- mul rsi
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+1*8]
- mul rcx
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+2*8]
- mul rbx
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+3*8]
- mul r15
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+4*8]
- mul r14
- mov r14,rbp ; load modulus into t4 and destroy a.n[0]
- add r8,rax
- adc r9,rdx
- and r14,r8
- shrd r8,r9,52
- xor r9,r9
-
- ;; c+=a.n[1 2 3 4] * b.n[4 3 2 1]
- mov rax,[rdi+1*8]
- mul rsi
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+2*8]
- mul rcx
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+3*8]
- mul rbx
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+4*8]
- mul r15
- mov r15,rbp
- add r8,rax
- adc r9,rdx
-
- and r15,r8
- shrd r8,r9,52
- xor r9,r9
-
- ;; c+=a.n[2 3 4] * b.n[4 3 2]
- mov rax,[rdi+2*8]
- mul rsi
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+3*8]
- mul rcx
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+4*8]
- mul rbx
- mov rbx,rbp
- add r8,rax
- adc r9,rdx
-
- and rbx,r8
- shrd r8,r9,52
- xor r9,r9
-
- ;; c+=a.n[3 4] * b.n[4 3]
- mov rax,[rdi+3*8]
- mul rsi
- add r8,rax
- adc r9,rdx
-
- mov rax,[rdi+4*8]
- mul rcx
- mov rcx,rbp
- add r8,rax
- adc r9,rdx
- and rcx,r8
- shrd r8,r9,52
- xor r9,r9
-
- ;; c+=a.n[4] * b.n[4]
- mov rax,[rdi+4*8]
- mul rsi
- ;; mov rbp,rbp ; modulus already there!
- add r8,rax
- adc r9,rdx
- and rbp,r8
- shrd r8,r9,52
- xor r9,r9
-
- mov rsi,r8 ; load c into t9 and destroy b.n[4]
-
- ;; *******************************************************
-common_exit_norm:
- mov rdi,01000003D10h ; load constant
-
- mov rax,r15 ; get t5
- mul rdi
- add rax,r10 ; +t0
- adc rdx,0
- mov r10,0FFFFFFFFFFFFFh ; modulus. Sadly, we ran out of registers!
- mov r8,rax ; +c
- and r10,rax
- shrd r8,rdx,52
- xor r9,r9
-
- mov rax,rbx ; get t6
- mul rdi
- add rax,r11 ; +t1
- adc rdx,0
- mov r11,0FFFFFFFFFFFFFh ; modulus
- add r8,rax ; +c
- adc r9,rdx
- and r11,r8
- shrd r8,r9,52
- xor r9,r9
-
- mov rax,rcx ; get t7
- mul rdi
- add rax,r12 ; +t2
- adc rdx,0
- pop rbx ; retrieve pointer to this.n
- mov r12,0FFFFFFFFFFFFFh ; modulus
- add r8,rax ; +c
- adc r9,rdx
- and r12,r8
- mov [rbx+2*8],r12 ; mov into this.n[2]
- shrd r8,r9,52
- xor r9,r9
-
- mov rax,rbp ; get t8
- mul rdi
- add rax,r13 ; +t3
- adc rdx,0
- mov r13,0FFFFFFFFFFFFFh ; modulus
- add r8,rax ; +c
- adc r9,rdx
- and r13,r8
- mov [rbx+3*8],r13 ; -> this.n[3]
- shrd r8,r9,52
- xor r9,r9
-
- mov rax,rsi ; get t9
- mul rdi
- add rax,r14 ; +t4
- adc rdx,0
- mov r14,0FFFFFFFFFFFFh ; !!!
- add r8,rax ; +c
- adc r9,rdx
- and r14,r8
- mov [rbx+4*8],r14 ; -> this.n[4]
- shrd r8,r9,48 ; !!!
- xor r9,r9
-
- mov rax,01000003D1h
- mul r8
- add rax,r10
- adc rdx,0
- mov r10,0FFFFFFFFFFFFFh ; modulus
- mov r8,rax
- and rax,r10
- shrd r8,rdx,52
- mov [rbx+0*8],rax ; -> this.n[0]
- add r8,r11
- mov [rbx+1*8],r8 ; -> this.n[1]
-
- pop r15
- pop r14
- pop r13
- pop r12
- pop rbx
- pop rbp
- ret
-
-
- ;; PROC ExSetSquare
- ;; Register Layout:
- ;; INPUT: rdi = a.n
- ;; rsi = this.a
- ;; INTERNAL: rdx:rax = multiplication accumulator
- ;; r9:r8 = c
- ;; r10-r13 = t0-t3
- ;; r14 = a.n[0] / t4
- ;; r15 = a.n[1] / t5
- ;; rbx = a.n[2] / t6
- ;; rcx = a.n[3] / t7
- ;; rbp = 0FFFFFFFFFFFFFh / t8
- ;; rsi = a.n[4] / t9
- GLOBAL SYM(secp256k1_fe_sqr_inner)
- ALIGN 32
-SYM(secp256k1_fe_sqr_inner):
- push rbp
- push rbx
- push r12
- push r13
- push r14
- push r15
- push rsi
- mov rbp,0FFFFFFFFFFFFFh
-
- ;; c=a.n[0] * a.n[0]
- mov r14,[rdi+0*8] ; r14=a.n[0]
- mov r10,rbp ; modulus
- mov rax,r14
- mul rax
- mov r15,[rdi+1*8] ; a.n[1]
- add r14,r14 ; r14=2*a.n[0]
- mov r8,rax
- and r10,rax ; only need lower qword
- shrd r8,rdx,52
- xor r9,r9
-
- ;; c+=2*a.n[0] * a.n[1]
- mov rax,r14 ; r14=2*a.n[0]
- mul r15
- mov rbx,[rdi+2*8] ; rbx=a.n[2]
- mov r11,rbp ; modulus
- add r8,rax
- adc r9,rdx
- and r11,r8
- shrd r8,r9,52
- xor r9,r9
-
- ;; c+=2*a.n[0]*a.n[2]+a.n[1]*a.n[1]
- mov rax,r14
- mul rbx
- add r8,rax
- adc r9,rdx
-
- mov rax,r15
- mov r12,rbp ; modulus
- mul rax
- mov rcx,[rdi+3*8] ; rcx=a.n[3]
- add r15,r15 ; r15=a.n[1]*2
- add r8,rax
- adc r9,rdx
- and r12,r8 ; only need lower dword
- shrd r8,r9,52
- xor r9,r9
-
- ;; c+=2*a.n[0]*a.n[3]+2*a.n[1]*a.n[2]
- mov rax,r14
- mul rcx
- add r8,rax
- adc r9,rdx
-
- mov rax,r15 ; rax=2*a.n[1]
- mov r13,rbp ; modulus
- mul rbx
- mov rsi,[rdi+4*8] ; rsi=a.n[4]
- add r8,rax
- adc r9,rdx
- and r13,r8
- shrd r8,r9,52
- xor r9,r9
-
- ;; c+=2*a.n[0]*a.n[4]+2*a.n[1]*a.n[3]+a.n[2]*a.n[2]
- mov rax,r14 ; last time we need 2*a.n[0]
- mul rsi
- add r8,rax
- adc r9,rdx
-
- mov rax,r15
- mul rcx
- mov r14,rbp ; modulus
- add r8,rax
- adc r9,rdx
-
- mov rax,rbx
- mul rax
- add rbx,rbx ; rcx=2*a.n[2]
- add r8,rax
- adc r9,rdx
- and r14,r8
- shrd r8,r9,52
- xor r9,r9
-
- ;; c+=2*a.n[1]*a.n[4]+2*a.n[2]*a.n[3]
- mov rax,r15 ; last time we need 2*a.n[1]
- mul rsi
- add r8,rax
- adc r9,rdx
-
- mov rax,rbx
- mul rcx
- mov r15,rbp ; modulus
- add r8,rax
- adc r9,rdx
- and r15,r8
- shrd r8,r9,52
- xor r9,r9
-
- ;; c+=2*a.n[2]*a.n[4]+a.n[3]*a.n[3]
- mov rax,rbx ; last time we need 2*a.n[2]
- mul rsi
- add r8,rax
- adc r9,rdx
-
- mov rax,rcx ; a.n[3]
- mul rax
- mov rbx,rbp ; modulus
- add r8,rax
- adc r9,rdx
- and rbx,r8 ; only need lower dword
- lea rax,[2*rcx]
- shrd r8,r9,52
- xor r9,r9
-
- ;; c+=2*a.n[3]*a.n[4]
- mul rsi
- mov rcx,rbp ; modulus
- add r8,rax
- adc r9,rdx
- and rcx,r8 ; only need lower dword
- shrd r8,r9,52
- xor r9,r9
-
- ;; c+=a.n[4]*a.n[4]
- mov rax,rsi
- mul rax
- ;; mov rbp,rbp ; modulus is already there!
- add r8,rax
- adc r9,rdx
- and rbp,r8
- shrd r8,r9,52
- xor r9,r9
-
- mov rsi,r8
-
- ;; *******************************************************
- jmp common_exit_norm
- end
-
-
/**********************************************************************
- * Copyright (c) 2013 Pieter Wuille *
+ * Copyright (c) 2013-2014 Diederik Huys, Pieter Wuille *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
+/**
+ * Changelog:
+ * - March 2013, Diederik Huys: original version
+ * - November 2014, Pieter Wuille: updated to use Peter Dettman's parallel multiplication algorithm
+ * - December 2014, Pieter Wuille: converted from YASM to GCC inline assembly
+ */
+
#ifndef _SECP256K1_FIELD_INNER5X52_IMPL_H_
#define _SECP256K1_FIELD_INNER5X52_IMPL_H_
-void __attribute__ ((sysv_abi)) secp256k1_fe_mul_inner(const uint64_t *a, const uint64_t *b, uint64_t *r);
-void __attribute__ ((sysv_abi)) secp256k1_fe_sqr_inner(const uint64_t *a, uint64_t *r);
+SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) {
+/**
+ * Registers: rdx:rax = multiplication accumulator
+ * r9:r8 = c
+ * r15:rcx = d
+ * r10-r14 = a0-a4
+ * rbx = b
+ * rdi = r
+ * rsi = a / t?
+ */
+ uint64_t tmp1, tmp2, tmp3;
+__asm__ __volatile__(
+ "movq 0(%%rsi),%%r10\n"
+ "movq 8(%%rsi),%%r11\n"
+ "movq 16(%%rsi),%%r12\n"
+ "movq 24(%%rsi),%%r13\n"
+ "movq 32(%%rsi),%%r14\n"
+
+ /* d += a3 * b0 */
+ "movq 0(%%rbx),%%rax\n"
+ "mulq %%r13\n"
+ "movq %%rax,%%rcx\n"
+ "movq %%rdx,%%r15\n"
+ /* d += a2 * b1 */
+ "movq 8(%%rbx),%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a1 * b2 */
+ "movq 16(%%rbx),%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d = a0 * b3 */
+ "movq 24(%%rbx),%%rax\n"
+ "mulq %%r10\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* c = a4 * b4 */
+ "movq 32(%%rbx),%%rax\n"
+ "mulq %%r14\n"
+ "movq %%rax,%%r8\n"
+ "movq %%rdx,%%r9\n"
+ /* d += (c & M) * R */
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* c >>= 52 (%%r8 only) */
+ "shrdq $52,%%r9,%%r8\n"
+ /* t3 (tmp1) = d & M */
+ "movq %%rcx,%%rsi\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rsi\n"
+ "movq %%rsi,%q1\n"
+ /* d >>= 52 */
+ "shrdq $52,%%r15,%%rcx\n"
+ "xorq %%r15,%%r15\n"
+ /* d += a4 * b0 */
+ "movq 0(%%rbx),%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a3 * b1 */
+ "movq 8(%%rbx),%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a2 * b2 */
+ "movq 16(%%rbx),%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a1 * b3 */
+ "movq 24(%%rbx),%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a0 * b4 */
+ "movq 32(%%rbx),%%rax\n"
+ "mulq %%r10\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += c * R */
+ "movq %%r8,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* t4 = d & M (%%rsi) */
+ "movq %%rcx,%%rsi\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rsi\n"
+ /* d >>= 52 */
+ "shrdq $52,%%r15,%%rcx\n"
+ "xorq %%r15,%%r15\n"
+ /* tx = t4 >> 48 (tmp3) */
+ "movq %%rsi,%%rax\n"
+ "shrq $48,%%rax\n"
+ "movq %%rax,%q3\n"
+ /* t4 &= (M >> 4) (tmp2) */
+ "movq $0xffffffffffff,%%rax\n"
+ "andq %%rax,%%rsi\n"
+ "movq %%rsi,%q2\n"
+ /* c = a0 * b0 */
+ "movq 0(%%rbx),%%rax\n"
+ "mulq %%r10\n"
+ "movq %%rax,%%r8\n"
+ "movq %%rdx,%%r9\n"
+ /* d += a4 * b1 */
+ "movq 8(%%rbx),%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a3 * b2 */
+ "movq 16(%%rbx),%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a2 * b3 */
+ "movq 24(%%rbx),%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a1 * b4 */
+ "movq 32(%%rbx),%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* u0 = d & M (%%rsi) */
+ "movq %%rcx,%%rsi\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rsi\n"
+ /* d >>= 52 */
+ "shrdq $52,%%r15,%%rcx\n"
+ "xorq %%r15,%%r15\n"
+ /* u0 = (u0 << 4) | tx (%%rsi) */
+ "shlq $4,%%rsi\n"
+ "movq %q3,%%rax\n"
+ "orq %%rax,%%rsi\n"
+ /* c += u0 * (R >> 4) */
+ "movq $0x1000003d1,%%rax\n"
+ "mulq %%rsi\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* r[0] = c & M */
+ "movq %%r8,%%rax\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq %%rax,0(%%rdi)\n"
+ /* c >>= 52 */
+ "shrdq $52,%%r9,%%r8\n"
+ "xorq %%r9,%%r9\n"
+ /* c += a1 * b0 */
+ "movq 0(%%rbx),%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* c += a0 * b1 */
+ "movq 8(%%rbx),%%rax\n"
+ "mulq %%r10\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d += a4 * b2 */
+ "movq 16(%%rbx),%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a3 * b3 */
+ "movq 24(%%rbx),%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a2 * b4 */
+ "movq 32(%%rbx),%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* c += (d & M) * R */
+ "movq %%rcx,%%rax\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d >>= 52 */
+ "shrdq $52,%%r15,%%rcx\n"
+ "xorq %%r15,%%r15\n"
+ /* r[1] = c & M */
+ "movq %%r8,%%rax\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq %%rax,8(%%rdi)\n"
+ /* c >>= 52 */
+ "shrdq $52,%%r9,%%r8\n"
+ "xorq %%r9,%%r9\n"
+ /* c += a2 * b0 */
+ "movq 0(%%rbx),%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* c += a1 * b1 */
+ "movq 8(%%rbx),%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* c += a0 * b2 (last use of %%r10 = a0) */
+ "movq 16(%%rbx),%%rax\n"
+ "mulq %%r10\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* fetch t3 (%%r10, overwrites a0), t4 (%%rsi) */
+ "movq %q2,%%rsi\n"
+ "movq %q1,%%r10\n"
+ /* d += a4 * b3 */
+ "movq 24(%%rbx),%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* d += a3 * b4 */
+ "movq 32(%%rbx),%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rcx\n"
+ "adcq %%rdx,%%r15\n"
+ /* c += (d & M) * R */
+ "movq %%rcx,%%rax\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d >>= 52 (%%rcx only) */
+ "shrdq $52,%%r15,%%rcx\n"
+ /* r[2] = c & M */
+ "movq %%r8,%%rax\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq %%rax,16(%%rdi)\n"
+ /* c >>= 52 */
+ "shrdq $52,%%r9,%%r8\n"
+ "xorq %%r9,%%r9\n"
+ /* c += t3 */
+ "addq %%r10,%%r8\n"
+ /* c += d * R */
+ "movq %%rcx,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* r[3] = c & M */
+ "movq %%r8,%%rax\n"
+ "movq $0xfffffffffffff,%%rdx\n"
+ "andq %%rdx,%%rax\n"
+ "movq %%rax,24(%%rdi)\n"
+ /* c >>= 52 (%%r8 only) */
+ "shrdq $52,%%r9,%%r8\n"
+ /* c += t4 (%%r8 only) */
+ "addq %%rsi,%%r8\n"
+ /* r[4] = c */
+ "movq %%r8,32(%%rdi)\n"
+: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3)
+: "b"(b), "D"(r)
+: "%rax", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"
+);
+}
+
+SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) {
+/**
+ * Registers: rdx:rax = multiplication accumulator
+ * r9:r8 = c
+ * rcx:rbx = d
+ * r10-r14 = a0-a4
+ * r15 = M (0xfffffffffffff)
+ * rdi = r
+ * rsi = a / t?
+ */
+ uint64_t tmp1, tmp2, tmp3;
+__asm__ __volatile__(
+ "movq 0(%%rsi),%%r10\n"
+ "movq 8(%%rsi),%%r11\n"
+ "movq 16(%%rsi),%%r12\n"
+ "movq 24(%%rsi),%%r13\n"
+ "movq 32(%%rsi),%%r14\n"
+ "movq $0xfffffffffffff,%%r15\n"
+
+ /* d = (a0*2) * a3 */
+ "leaq (%%r10,%%r10,1),%%rax\n"
+ "mulq %%r13\n"
+ "movq %%rax,%%rbx\n"
+ "movq %%rdx,%%rcx\n"
+ /* d += (a1*2) * a2 */
+ "leaq (%%r11,%%r11,1),%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* c = a4 * a4 */
+ "movq %%r14,%%rax\n"
+ "mulq %%r14\n"
+ "movq %%rax,%%r8\n"
+ "movq %%rdx,%%r9\n"
+ /* d += (c & M) * R */
+ "andq %%r15,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* c >>= 52 (%%r8 only) */
+ "shrdq $52,%%r9,%%r8\n"
+ /* t3 (tmp1) = d & M */
+ "movq %%rbx,%%rsi\n"
+ "andq %%r15,%%rsi\n"
+ "movq %%rsi,%q1\n"
+ /* d >>= 52 */
+ "shrdq $52,%%rcx,%%rbx\n"
+ "xorq %%rcx,%%rcx\n"
+ /* a4 *= 2 */
+ "addq %%r14,%%r14\n"
+ /* d += a0 * a4 */
+ "movq %%r10,%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* d+= (a1*2) * a3 */
+ "leaq (%%r11,%%r11,1),%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* d += a2 * a2 */
+ "movq %%r12,%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* d += c * R */
+ "movq %%r8,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* t4 = d & M (%%rsi) */
+ "movq %%rbx,%%rsi\n"
+ "andq %%r15,%%rsi\n"
+ /* d >>= 52 */
+ "shrdq $52,%%rcx,%%rbx\n"
+ "xorq %%rcx,%%rcx\n"
+ /* tx = t4 >> 48 (tmp3) */
+ "movq %%rsi,%%rax\n"
+ "shrq $48,%%rax\n"
+ "movq %%rax,%q3\n"
+ /* t4 &= (M >> 4) (tmp2) */
+ "movq $0xffffffffffff,%%rax\n"
+ "andq %%rax,%%rsi\n"
+ "movq %%rsi,%q2\n"
+ /* c = a0 * a0 */
+ "movq %%r10,%%rax\n"
+ "mulq %%r10\n"
+ "movq %%rax,%%r8\n"
+ "movq %%rdx,%%r9\n"
+ /* d += a1 * a4 */
+ "movq %%r11,%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* d += (a2*2) * a3 */
+ "leaq (%%r12,%%r12,1),%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* u0 = d & M (%%rsi) */
+ "movq %%rbx,%%rsi\n"
+ "andq %%r15,%%rsi\n"
+ /* d >>= 52 */
+ "shrdq $52,%%rcx,%%rbx\n"
+ "xorq %%rcx,%%rcx\n"
+ /* u0 = (u0 << 4) | tx (%%rsi) */
+ "shlq $4,%%rsi\n"
+ "movq %q3,%%rax\n"
+ "orq %%rax,%%rsi\n"
+ /* c += u0 * (R >> 4) */
+ "movq $0x1000003d1,%%rax\n"
+ "mulq %%rsi\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* r[0] = c & M */
+ "movq %%r8,%%rax\n"
+ "andq %%r15,%%rax\n"
+ "movq %%rax,0(%%rdi)\n"
+ /* c >>= 52 */
+ "shrdq $52,%%r9,%%r8\n"
+ "xorq %%r9,%%r9\n"
+ /* a0 *= 2 */
+ "addq %%r10,%%r10\n"
+ /* c += a0 * a1 */
+ "movq %%r10,%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d += a2 * a4 */
+ "movq %%r12,%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* d += a3 * a3 */
+ "movq %%r13,%%rax\n"
+ "mulq %%r13\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* c += (d & M) * R */
+ "movq %%rbx,%%rax\n"
+ "andq %%r15,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d >>= 52 */
+ "shrdq $52,%%rcx,%%rbx\n"
+ "xorq %%rcx,%%rcx\n"
+ /* r[1] = c & M */
+ "movq %%r8,%%rax\n"
+ "andq %%r15,%%rax\n"
+ "movq %%rax,8(%%rdi)\n"
+ /* c >>= 52 */
+ "shrdq $52,%%r9,%%r8\n"
+ "xorq %%r9,%%r9\n"
+ /* c += a0 * a2 (last use of %%r10) */
+ "movq %%r10,%%rax\n"
+ "mulq %%r12\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* fetch t3 (%%r10, overwrites a0),t4 (%%rsi) */
+ "movq %q2,%%rsi\n"
+ "movq %q1,%%r10\n"
+ /* c += a1 * a1 */
+ "movq %%r11,%%rax\n"
+ "mulq %%r11\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d += a3 * a4 */
+ "movq %%r13,%%rax\n"
+ "mulq %%r14\n"
+ "addq %%rax,%%rbx\n"
+ "adcq %%rdx,%%rcx\n"
+ /* c += (d & M) * R */
+ "movq %%rbx,%%rax\n"
+ "andq %%r15,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* d >>= 52 (%%rbx only) */
+ "shrdq $52,%%rcx,%%rbx\n"
+ /* r[2] = c & M */
+ "movq %%r8,%%rax\n"
+ "andq %%r15,%%rax\n"
+ "movq %%rax,16(%%rdi)\n"
+ /* c >>= 52 */
+ "shrdq $52,%%r9,%%r8\n"
+ "xorq %%r9,%%r9\n"
+ /* c += t3 */
+ "addq %%r10,%%r8\n"
+ /* c += d * R */
+ "movq %%rbx,%%rax\n"
+ "movq $0x1000003d10,%%rdx\n"
+ "mulq %%rdx\n"
+ "addq %%rax,%%r8\n"
+ "adcq %%rdx,%%r9\n"
+ /* r[3] = c & M */
+ "movq %%r8,%%rax\n"
+ "andq %%r15,%%rax\n"
+ "movq %%rax,24(%%rdi)\n"
+ /* c >>= 52 (%%r8 only) */
+ "shrdq $52,%%r9,%%r8\n"
+ /* c += t4 (%%r8 only) */
+ "addq %%rsi,%%r8\n"
+ /* r[4] = c */
+ "movq %%r8,32(%%rdi)\n"
+: "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3)
+: "D"(r)
+: "%rax", "%rbx", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"
+);
+}
#endif
#include "num.h"
#include "field.h"
-#if defined(USE_FIELD_5X52_ASM)
+#if defined(USE_ASM_X86_64)
#include "field_5x52_asm_impl.h"
-#elif defined(USE_FIELD_5X52_INT128)
-#include "field_5x52_int128_impl.h"
#else
-#error "Please select field_5x52 implementation"
+#include "field_5x52_int128_impl.h"
#endif
/** Implements arithmetic modulo FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F,
r &= (d[3] <= 0xFFFFFFFFFFFFFULL * m);
r &= (d[4] <= 0x0FFFFFFFFFFFFULL * m);
r &= (a->magnitude >= 0);
+ r &= (a->magnitude <= 2048);
if (a->normalized) {
r &= (a->magnitude <= 1);
if (r && (d[4] == 0x0FFFFFFFFFFFFULL) && ((d[3] & d[2] & d[1]) == 0xFFFFFFFFFFFFFULL)) {
#endif
}
+static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) {
+ uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
+
+ /* Reduce t4 at the start so there will be at most a single carry from the first pass */
+ uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x1000003D1ULL;
+ t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL;
+
+ /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t4 >> 49 == 0);
+
+ r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
+
+#ifdef VERIFY
+ r->magnitude = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) {
+ uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
+
+ /* Reduce t4 at the start so there will be at most a single carry from the first pass */
+ uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
+ uint64_t m;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x1000003D1ULL;
+ t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3;
+
+ /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t4 >> 49 == 0);
+
+ /* At most a single final reduction is needed; check if the value is >= the field characteristic */
+ x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL)
+ & (t0 >= 0xFFFFEFFFFFC2FULL));
+
+ if (x) {
+ t0 += 0x1000003D1ULL;
+ t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL;
+
+ /* If t4 didn't carry to bit 48 already, then it should have after any final reduction */
+ VERIFY_CHECK(t4 >> 48 == x);
+
+ /* Mask off the possible multiple of 2^256 from the final reduction */
+ t4 &= 0x0FFFFFFFFFFFFULL;
+ }
+
+ r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
+
+#ifdef VERIFY
+ r->magnitude = 1;
+ r->normalized = 1;
+ secp256k1_fe_verify(r);
+#endif
+}
+
+static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) {
+ uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
+
+ /* Reduce t4 at the start so there will be at most a single carry from the first pass */
+ uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
+
+ /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
+ uint64_t z0, z1;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x1000003D1ULL;
+ t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL; z0 = t0; z1 = t0 ^ 0x1000003D0ULL;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3;
+ z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL;
+
+ /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t4 >> 49 == 0);
+
+ return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL);
+}
+
+static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) {
+ uint64_t t0 = r->n[0], t4 = r->n[4];
+
+ /* Reduce t4 at the start so there will be at most a single carry from the first pass */
+ uint64_t x = t4 >> 48;
+
+ /* The first pass ensures the magnitude is 1, ... */
+ t0 += x * 0x1000003D1ULL;
+
+ /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */
+ uint64_t z0 = t0 & 0xFFFFFFFFFFFFFULL, z1 = z0 ^ 0x1000003D0ULL;
+
+ /* Fast return path should catch the majority of cases */
+ if ((z0 != 0ULL) & (z1 != 0xFFFFFFFFFFFFFULL))
+ return 0;
+
+ uint64_t t1 = r->n[1], t2 = r->n[2], t3 = r->n[3];
+ t4 &= 0x0FFFFFFFFFFFFULL;
+
+ t1 += (t0 >> 52); t0 = z0;
+ t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1;
+ t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2;
+ t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3;
+ z0 |= t4; z1 &= t4 ^ 0xF000000000000ULL;
+
+ /* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
+ VERIFY_CHECK(t4 >> 49 == 0);
+
+ return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL);
+}
+
SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
r->n[0] = a;
r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0;
}
}
-SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
+static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
#ifdef VERIFY
VERIFY_CHECK(a->normalized);
VERIFY_CHECK(b->normalized);
secp256k1_fe_verify(a);
secp256k1_fe_verify(b);
#endif
- const uint64_t *t = a->n, *u = b->n;
- return ((t[0]^u[0]) | (t[1]^u[1]) | (t[2]^u[2]) | (t[3]^u[3]) | (t[4]^u[4])) == 0;
+ for (int i = 4; i >= 0; i--) {
+ if (a->n[i] > b->n[i]) return 1;
+ if (a->n[i] < b->n[i]) return -1;
+ }
+ return 0;
}
-static void secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
+static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0;
for (int i=0; i<32; i++) {
for (int j=0; j<2; j++) {
r->n[limb] |= (uint64_t)((a[31-i] >> (4*j)) & 0xF) << shift;
}
}
+ if (r->n[4] == 0x0FFFFFFFFFFFFULL && (r->n[3] & r->n[2] & r->n[1]) == 0xFFFFFFFFFFFFFULL && r->n[0] >= 0xFFFFEFFFFFC2FULL) {
+ return 0;
+ }
#ifdef VERIFY
r->magnitude = 1;
r->normalized = 1;
secp256k1_fe_verify(r);
#endif
+ return 1;
}
/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */
#endif
}
-static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
+static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) {
#ifdef VERIFY
VERIFY_CHECK(a->magnitude <= 8);
VERIFY_CHECK(b->magnitude <= 8);
secp256k1_fe_verify(a);
secp256k1_fe_verify(b);
+ VERIFY_CHECK(r != b);
#endif
- secp256k1_fe_mul_inner(a->n, b->n, r->n);
+ secp256k1_fe_mul_inner(r->n, a->n, b->n);
#ifdef VERIFY
r->magnitude = 1;
r->normalized = 0;
VERIFY_CHECK(a->magnitude <= 8);
secp256k1_fe_verify(a);
#endif
- secp256k1_fe_sqr_inner(a->n, r->n);
+ secp256k1_fe_sqr_inner(r->n, a->n);
#ifdef VERIFY
r->magnitude = 1;
r->normalized = 0;
#endif
}
+static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) {
+ uint64_t mask0 = flag + ~((uint64_t)0), mask1 = ~mask0;
+ r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
+ r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
+ r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
+ r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
+ r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1);
+#ifdef VERIFY
+ if (flag) {
+ r->magnitude = a->magnitude;
+ r->normalized = a->normalized;
+ }
+#endif
+}
+
#endif
#define VERIFY_BITS(x, n) do { } while(0)
#endif
-SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint64_t *a, const uint64_t *b, uint64_t *r) {
+SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) {
VERIFY_BITS(a[0], 56);
VERIFY_BITS(a[1], 56);
VERIFY_BITS(a[2], 56);
VERIFY_BITS(b[2], 56);
VERIFY_BITS(b[3], 56);
VERIFY_BITS(b[4], 52);
+ VERIFY_CHECK(r != b);
const uint64_t M = 0xFFFFFFFFFFFFFULL, R = 0x1000003D10ULL;
/* [... a b c] is a shorthand for ... + a<<104 + b<<52 + c<<0 mod n.
* Note that [x 0 0 0 0 0] = [x*R].
*/
+ uint64_t a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4];
+
__int128 c, d;
- d = (__int128)a[0] * b[3]
- + (__int128)a[1] * b[2]
- + (__int128)a[2] * b[1]
- + (__int128)a[3] * b[0];
+ d = (__int128)a0 * b[3]
+ + (__int128)a1 * b[2]
+ + (__int128)a2 * b[1]
+ + (__int128)a3 * b[0];
VERIFY_BITS(d, 114);
/* [d 0 0 0] = [p3 0 0 0] */
- c = (__int128)a[4] * b[4];
+ c = (__int128)a4 * b[4];
VERIFY_BITS(c, 112);
/* [c 0 0 0 0 d 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */
d += (c & M) * R; c >>= 52;
VERIFY_BITS(d, 63);
/* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 0 p3 0 0 0] */
- d += (__int128)a[0] * b[4]
- + (__int128)a[1] * b[3]
- + (__int128)a[2] * b[2]
- + (__int128)a[3] * b[1]
- + (__int128)a[4] * b[0];
+ d += (__int128)a0 * b[4]
+ + (__int128)a1 * b[3]
+ + (__int128)a2 * b[2]
+ + (__int128)a3 * b[1]
+ + (__int128)a4 * b[0];
VERIFY_BITS(d, 115);
/* [c 0 0 0 0 d t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */
d += c * R;
VERIFY_BITS(t4, 48);
/* [d t4+(tx<<48) t3 0 0 0] = [p8 0 0 0 p4 p3 0 0 0] */
- c = (__int128)a[0] * b[0];
+ c = (__int128)a0 * b[0];
VERIFY_BITS(c, 112);
/* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 0 p4 p3 0 0 p0] */
- d += (__int128)a[1] * b[4]
- + (__int128)a[2] * b[3]
- + (__int128)a[3] * b[2]
- + (__int128)a[4] * b[1];
+ d += (__int128)a1 * b[4]
+ + (__int128)a2 * b[3]
+ + (__int128)a3 * b[2]
+ + (__int128)a4 * b[1];
VERIFY_BITS(d, 115);
/* [d t4+(tx<<48) t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
uint64_t u0 = d & M; d >>= 52;
c += (__int128)u0 * (R >> 4);
VERIFY_BITS(c, 115);
/* [d 0 t4 t3 0 0 c] = [p8 0 0 p5 p4 p3 0 0 p0] */
- uint64_t t0 = c & M; c >>= 52;
- VERIFY_BITS(t0, 52);
+ r[0] = c & M; c >>= 52;
+ VERIFY_BITS(r[0], 52);
VERIFY_BITS(c, 61);
- /* [d 0 t4 t3 0 c t0] = [p8 0 0 p5 p4 p3 0 0 p0] */
+ /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 0 p0] */
- c += (__int128)a[0] * b[1]
- + (__int128)a[1] * b[0];
+ c += (__int128)a0 * b[1]
+ + (__int128)a1 * b[0];
VERIFY_BITS(c, 114);
- /* [d 0 t4 t3 0 c t0] = [p8 0 0 p5 p4 p3 0 p1 p0] */
- d += (__int128)a[2] * b[4]
- + (__int128)a[3] * b[3]
- + (__int128)a[4] * b[2];
+ /* [d 0 t4 t3 0 c r0] = [p8 0 0 p5 p4 p3 0 p1 p0] */
+ d += (__int128)a2 * b[4]
+ + (__int128)a3 * b[3]
+ + (__int128)a4 * b[2];
VERIFY_BITS(d, 114);
- /* [d 0 t4 t3 0 c t0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
+ /* [d 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
c += (d & M) * R; d >>= 52;
VERIFY_BITS(c, 115);
VERIFY_BITS(d, 62);
- /* [d 0 0 t4 t3 0 c t0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
- uint64_t t1 = c & M; c >>= 52;
- VERIFY_BITS(t1, 52);
+ /* [d 0 0 t4 t3 0 c r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
+ r[1] = c & M; c >>= 52;
+ VERIFY_BITS(r[1], 52);
VERIFY_BITS(c, 63);
- /* [d 0 0 t4 t3 c t1 t0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
+ /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 0 p1 p0] */
- c += (__int128)a[0] * b[2]
- + (__int128)a[1] * b[1]
- + (__int128)a[2] * b[0];
+ c += (__int128)a0 * b[2]
+ + (__int128)a1 * b[1]
+ + (__int128)a2 * b[0];
VERIFY_BITS(c, 114);
- /* [d 0 0 t4 t3 c t1 t0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */
- d += (__int128)a[3] * b[4]
- + (__int128)a[4] * b[3];
+ /* [d 0 0 t4 t3 c r1 r0] = [p8 0 p6 p5 p4 p3 p2 p1 p0] */
+ d += (__int128)a3 * b[4]
+ + (__int128)a4 * b[3];
VERIFY_BITS(d, 114);
- /* [d 0 0 t4 t3 c t1 t0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ /* [d 0 0 t4 t3 c t1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
c += (d & M) * R; d >>= 52;
VERIFY_BITS(c, 115);
VERIFY_BITS(d, 62);
- /* [d 0 0 0 t4 t3 c t1 t0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
+ /* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
- r[0] = t0;
- VERIFY_BITS(r[0], 52);
- /* [d 0 0 0 t4 t3 c t1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
- r[1] = t1;
- VERIFY_BITS(r[1], 52);
/* [d 0 0 0 t4 t3 c r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
r[2] = c & M; c >>= 52;
VERIFY_BITS(r[2], 52);
/* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */
}
-SECP256K1_INLINE static void secp256k1_fe_sqr_inner(const uint64_t *a, uint64_t *r) {
+SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) {
VERIFY_BITS(a[0], 56);
VERIFY_BITS(a[1], 56);
VERIFY_BITS(a[2], 56);
+++ /dev/null
-/**********************************************************************
- * Copyright (c) 2013, 2014 Pieter Wuille *
- * Distributed under the MIT software license, see the accompanying *
- * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
- **********************************************************************/
-
-#ifndef _SECP256K1_FIELD_REPR_
-#define _SECP256K1_FIELD_REPR_
-
-#include <gmp.h>
-
-#define FIELD_LIMBS ((256 + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)
-
-typedef struct {
- mp_limb_t n[FIELD_LIMBS+1];
-} secp256k1_fe_t;
-
-#endif
+++ /dev/null
-/**********************************************************************
- * Copyright (c) 2013, 2014 Pieter Wuille *
- * Distributed under the MIT software license, see the accompanying *
- * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
- **********************************************************************/
-
-#ifndef _SECP256K1_FIELD_REPR_IMPL_H_
-#define _SECP256K1_FIELD_REPR_IMPL_H_
-
-#include <stdio.h>
-#include <string.h>
-#include "num.h"
-#include "field.h"
-
-static mp_limb_t secp256k1_field_p[FIELD_LIMBS];
-static mp_limb_t secp256k1_field_pc[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS];
-
-static void secp256k1_fe_inner_start(void) {
- for (int i=0; i<(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; i++)
- secp256k1_field_pc[i] = 0;
- secp256k1_field_pc[0] += 0x3D1UL;
- secp256k1_field_pc[32/GMP_NUMB_BITS] += (((mp_limb_t)1) << (32 % GMP_NUMB_BITS));
- for (int i=0; i<FIELD_LIMBS; i++) {
- secp256k1_field_p[i] = 0;
- }
- mpn_sub(secp256k1_field_p, secp256k1_field_p, FIELD_LIMBS, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS);
-}
-
-static void secp256k1_fe_inner_stop(void) {
-}
-
-static void secp256k1_fe_normalize(secp256k1_fe_t *r) {
- if (r->n[FIELD_LIMBS] != 0) {
-#if (GMP_NUMB_BITS >= 40)
- mp_limb_t carry = mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x1000003D1ULL * r->n[FIELD_LIMBS]);
- mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x1000003D1ULL * carry);
-#else
- mp_limb_t carry = mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x3D1UL * r->n[FIELD_LIMBS]) +
- mpn_add_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), r->n[FIELD_LIMBS] << (32 % GMP_NUMB_BITS));
- mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x3D1UL * carry);
- mpn_add_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), carry << (32%GMP_NUMB_BITS));
-#endif
- r->n[FIELD_LIMBS] = 0;
- }
- if (mpn_cmp(r->n, secp256k1_field_p, FIELD_LIMBS) >= 0)
- mpn_sub(r->n, r->n, FIELD_LIMBS, secp256k1_field_p, FIELD_LIMBS);
-}
-
-SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
- r->n[0] = a;
- for (int i=1; i<FIELD_LIMBS+1; i++)
- r->n[i] = 0;
-}
-
-SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *r) {
- for (int i=0; i<FIELD_LIMBS+1; i++)
- r->n[i] = 0;
-}
-
-SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) {
- int ret = 1;
- for (int i=0; i<FIELD_LIMBS+1; i++)
- ret &= (a->n[i] == 0);
- return ret;
-}
-
-SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) {
- return a->n[0] & 1;
-}
-
-SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
- int ret = 1;
- for (int i=0; i<FIELD_LIMBS+1; i++)
- ret &= (a->n[i] == b->n[i]);
- return ret;
-}
-
-static void secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
- for (int i=0; i<FIELD_LIMBS+1; i++)
- r->n[i] = 0;
- for (int i=0; i<256; i++) {
- int limb = i/GMP_NUMB_BITS;
- int shift = i%GMP_NUMB_BITS;
- r->n[limb] |= (mp_limb_t)((a[31-i/8] >> (i%8)) & 0x1) << shift;
- }
-}
-
-/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */
-static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) {
- for (int i=0; i<32; i++) {
- int c = 0;
- for (int j=0; j<8; j++) {
- int limb = (8*i+j)/GMP_NUMB_BITS;
- int shift = (8*i+j)%GMP_NUMB_BITS;
- c |= ((a->n[limb] >> shift) & 0x1) << j;
- }
- r[31-i] = c;
- }
-}
-
-SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) {
- (void)m;
- *r = *a;
- secp256k1_fe_normalize(r);
- for (int i=0; i<FIELD_LIMBS; i++)
- r->n[i] = ~(r->n[i]);
-#if (GMP_NUMB_BITS >= 33)
- mpn_sub_1(r->n, r->n, FIELD_LIMBS, 0x1000003D0ULL);
-#else
- mpn_sub_1(r->n, r->n, FIELD_LIMBS, 0x3D0UL);
- mpn_sub_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), 0x1UL << (32%GMP_NUMB_BITS));
-#endif
-}
-
-SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) {
- mpn_mul_1(r->n, r->n, FIELD_LIMBS+1, a);
-}
-
-SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
- mpn_add(r->n, r->n, FIELD_LIMBS+1, a->n, FIELD_LIMBS+1);
-}
-
-static void secp256k1_fe_reduce(secp256k1_fe_t *r, mp_limb_t *tmp) {
- /** <A1 A2 A3 A4> <B1 B2 B3 B4>
- * B1 B2 B3 B4
- * + C * A1 A2 A3 A4
- * + A1 A2 A3 A4
- */
-
-#if (GMP_NUMB_BITS >= 33)
- mp_limb_t o = mpn_addmul_1(tmp, tmp+FIELD_LIMBS, FIELD_LIMBS, 0x1000003D1ULL);
-#else
- mp_limb_t o = mpn_addmul_1(tmp, tmp+FIELD_LIMBS, FIELD_LIMBS, 0x3D1UL) +
- mpn_addmul_1(tmp+(32/GMP_NUMB_BITS), tmp+FIELD_LIMBS, FIELD_LIMBS-(32/GMP_NUMB_BITS), 0x1UL << (32%GMP_NUMB_BITS));
-#endif
- mp_limb_t q[1+(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS];
- q[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS] = mpn_mul_1(q, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS, o);
-#if (GMP_NUMB_BITS <= 32)
- mp_limb_t o2 = tmp[2*FIELD_LIMBS-(32/GMP_NUMB_BITS)] << (32%GMP_NUMB_BITS);
- q[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS] += mpn_addmul_1(q, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS, o2);
-#endif
- r->n[FIELD_LIMBS] = mpn_add(r->n, tmp, FIELD_LIMBS, q, 1+(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS);
-}
-
-static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
- secp256k1_fe_t ac = *a;
- secp256k1_fe_t bc = *b;
- secp256k1_fe_normalize(&ac);
- secp256k1_fe_normalize(&bc);
- mp_limb_t tmp[2*FIELD_LIMBS];
- mpn_mul_n(tmp, ac.n, bc.n, FIELD_LIMBS);
- secp256k1_fe_reduce(r, tmp);
-}
-
-static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
- secp256k1_fe_t ac = *a;
- secp256k1_fe_normalize(&ac);
- mp_limb_t tmp[2*FIELD_LIMBS];
- mpn_sqr(tmp, ac.n, FIELD_LIMBS);
- secp256k1_fe_reduce(r, tmp);
-}
-
-#endif
#include "util.h"
-#if defined(USE_FIELD_GMP)
-#include "field_gmp_impl.h"
-#elif defined(USE_FIELD_10X26)
+#if defined(USE_FIELD_10X26)
#include "field_10x26_impl.h"
#elif defined(USE_FIELD_5X52)
#include "field_5x52_impl.h"
r[64] = 0x00;
}
-static void secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen) {
+static int secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen) {
unsigned char tmp[32] = {};
static const int cvt[256] = {0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
if (alen > i*2)
tmp[32 - alen/2 + i] = (cvt[(unsigned char)a[2*i]] << 4) + cvt[(unsigned char)a[2*i+1]];
}
- secp256k1_fe_set_b32(r, tmp);
+ return secp256k1_fe_set_b32(r, tmp);
}
-static int secp256k1_fe_sqrt(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
+SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
+ secp256k1_fe_t na;
+ secp256k1_fe_negate(&na, a, 1);
+ secp256k1_fe_add(&na, b);
+ return secp256k1_fe_normalizes_to_zero_var(&na);
+}
+
+static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
/** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in
* { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block:
/* Check that a square root was actually calculated */
secp256k1_fe_sqr(&t1, r);
- secp256k1_fe_negate(&t1, &t1, 1);
- secp256k1_fe_add(&t1, a);
- secp256k1_fe_normalize(&t1);
- return secp256k1_fe_is_zero(&t1);
+ return secp256k1_fe_equal_var(&t1, a);
}
static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
for (int j=0; j<3; j++) secp256k1_fe_sqr(&t1, &t1);
secp256k1_fe_mul(&t1, &t1, &x2);
for (int j=0; j<2; j++) secp256k1_fe_sqr(&t1, &t1);
- secp256k1_fe_mul(r, &t1, a);
+ secp256k1_fe_mul(r, a, &t1);
}
static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
#elif defined(USE_FIELD_INV_NUM)
unsigned char b[32];
secp256k1_fe_t c = *a;
- secp256k1_fe_normalize(&c);
+ secp256k1_fe_normalize_var(&c);
secp256k1_fe_get_b32(b, &c);
secp256k1_num_t n;
secp256k1_num_set_bin(&n, b, 32);
secp256k1_num_mod_inverse(&n, &n, &secp256k1_fe_consts->p);
secp256k1_num_get_bin(b, 32, &n);
- secp256k1_fe_set_b32(r, b);
+ VERIFY_CHECK(secp256k1_fe_set_b32(r, b));
#else
#error "Please select field inverse implementation"
#endif
}
-static void secp256k1_fe_inv_all(size_t len, secp256k1_fe_t r[len], const secp256k1_fe_t a[len]) {
- if (len < 1)
- return;
-
- VERIFY_CHECK((r + len <= a) || (a + len <= r));
-
- r[0] = a[0];
-
- size_t i = 0;
- while (++i < len) {
- secp256k1_fe_mul(&r[i], &r[i - 1], &a[i]);
- }
-
- secp256k1_fe_t u; secp256k1_fe_inv(&u, &r[--i]);
-
- while (i > 0) {
- int j = i--;
- secp256k1_fe_mul(&r[j], &r[i], &u);
- secp256k1_fe_mul(&u, &u, &a[j]);
- }
-
- r[0] = u;
-}
-
static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t r[len], const secp256k1_fe_t a[len]) {
if (len < 1)
return;
}
static void secp256k1_fe_start(void) {
+#ifndef USE_NUM_NONE
static const unsigned char secp256k1_fe_consts_p[] = {
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F
};
+#endif
if (secp256k1_fe_consts == NULL) {
secp256k1_fe_inner_start();
- secp256k1_fe_consts_t *ret = (secp256k1_fe_consts_t*)malloc(sizeof(secp256k1_fe_consts_t));
+ secp256k1_fe_consts_t *ret = (secp256k1_fe_consts_t*)checked_malloc(sizeof(secp256k1_fe_consts_t));
+#ifndef USE_NUM_NONE
secp256k1_num_set_bin(&ret->p, secp256k1_fe_consts_p, sizeof(secp256k1_fe_consts_p));
+#endif
secp256k1_fe_consts = ret;
}
}
/** Global constants related to the group */
typedef struct {
- secp256k1_num_t order; /* the order of the curve (= order of its generator) */
- secp256k1_num_t half_order; /* half the order of the curve (= order of its generator) */
secp256k1_ge_t g; /* the generator point */
#ifdef USE_ENDOMORPHISM
/* constants related to secp256k1's efficiently computable endomorphism */
secp256k1_fe_t beta;
- secp256k1_num_t lambda, a1b2, b1, a2;
#endif
} secp256k1_ge_consts_t;
/** Set a group element (affine) equal to the point with the given X coordinate, and given oddness
* for Y. Return value indicates whether the result is valid. */
-static int secp256k1_ge_set_xo(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd);
+static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd);
/** Check whether a group element is the point at infinity. */
static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a);
/** Check whether a group element is valid (i.e., on the curve). */
-static int secp256k1_ge_is_valid(const secp256k1_ge_t *a);
+static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a);
static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a);
/** Set a group element (jacobian) equal to another which is given in affine coordinates. */
static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a);
-/** Get the X coordinate of a group element (jacobian). */
-static void secp256k1_gej_get_x_var(secp256k1_fe_t *r, const secp256k1_gej_t *a);
+/** Compare the X coordinate of a group element (jacobian). */
+static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a);
/** Set r equal to the inverse of a (i.e., mirrored around the X axis) */
static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a);
#ifdef USE_ENDOMORPHISM
/** Set r to be equal to lambda times a, where lambda is chosen in a way such that this is very fast. */
static void secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a);
-
-/** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (given that a is
- not more than 256 bits). */
-static void secp256k1_gej_split_exp_var(secp256k1_num_t *r1, secp256k1_num_t *r2, const secp256k1_num_t *a);
#endif
/** Clear a secp256k1_gej_t to prevent leaking sensitive information. */
/** Clear a secp256k1_ge_t to prevent leaking sensitive information. */
static void secp256k1_ge_clear(secp256k1_ge_t *r);
-
#endif
}
static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a) {
- r->infinity = a->infinity;
- r->x = a->x;
- r->y = a->y;
- secp256k1_fe_normalize(&r->y);
+ *r = *a;
+ secp256k1_fe_normalize_weak(&r->y);
secp256k1_fe_negate(&r->y, &r->y, 1);
}
static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t r[len], const secp256k1_gej_t a[len]) {
size_t count = 0;
- secp256k1_fe_t az[len];
+ secp256k1_fe_t *az = checked_malloc(sizeof(secp256k1_fe_t) * len);
for (size_t i=0; i<len; i++) {
if (!a[i].infinity) {
az[count++] = a[i].z;
}
}
- secp256k1_fe_t azi[count];
+ secp256k1_fe_t *azi = checked_malloc(sizeof(secp256k1_fe_t) * count);
secp256k1_fe_inv_all_var(count, azi, az);
+ free(az);
count = 0;
for (size_t i=0; i<len; i++) {
secp256k1_fe_mul(&r[i].y, &a[i].y, &zi3);
}
}
+ free(azi);
}
static void secp256k1_gej_set_infinity(secp256k1_gej_t *r) {
secp256k1_fe_clear(&r->y);
}
-static int secp256k1_ge_set_xo(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd) {
+static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd) {
r->x = *x;
secp256k1_fe_t x2; secp256k1_fe_sqr(&x2, x);
secp256k1_fe_t x3; secp256k1_fe_mul(&x3, x, &x2);
r->infinity = 0;
secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7);
secp256k1_fe_add(&c, &x3);
- if (!secp256k1_fe_sqrt(&r->y, &c))
+ if (!secp256k1_fe_sqrt_var(&r->y, &c))
return 0;
- secp256k1_fe_normalize(&r->y);
+ secp256k1_fe_normalize_var(&r->y);
if (secp256k1_fe_is_odd(&r->y) != odd)
secp256k1_fe_negate(&r->y, &r->y, 1);
return 1;
secp256k1_fe_set_int(&r->z, 1);
}
-static void secp256k1_gej_get_x_var(secp256k1_fe_t *r, const secp256k1_gej_t *a) {
- secp256k1_fe_t zi2; secp256k1_fe_inv_var(&zi2, &a->z); secp256k1_fe_sqr(&zi2, &zi2);
- secp256k1_fe_mul(r, &a->x, &zi2);
+static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a) {
+ VERIFY_CHECK(!a->infinity);
+ secp256k1_fe_t r; secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x);
+ secp256k1_fe_t r2 = a->x; secp256k1_fe_normalize_weak(&r2);
+ return secp256k1_fe_equal_var(&r, &r2);
}
static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
r->x = a->x;
r->y = a->y;
r->z = a->z;
- secp256k1_fe_normalize(&r->y);
+ secp256k1_fe_normalize_weak(&r->y);
secp256k1_fe_negate(&r->y, &r->y, 1);
}
return a->infinity;
}
-static int secp256k1_gej_is_valid(const secp256k1_gej_t *a) {
+static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) {
if (a->infinity)
return 0;
/** y^2 = x^3 + 7
secp256k1_fe_t z6; secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2);
secp256k1_fe_mul_int(&z6, 7);
secp256k1_fe_add(&x3, &z6);
- secp256k1_fe_normalize(&y2);
- secp256k1_fe_normalize(&x3);
- return secp256k1_fe_equal(&y2, &x3);
+ secp256k1_fe_normalize_weak(&x3);
+ return secp256k1_fe_equal_var(&y2, &x3);
}
-static int secp256k1_ge_is_valid(const secp256k1_ge_t *a) {
+static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) {
if (a->infinity)
return 0;
/* y^2 = x^3 + 7 */
secp256k1_fe_t x3; secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x);
secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7);
secp256k1_fe_add(&x3, &c);
- secp256k1_fe_normalize(&y2);
- secp256k1_fe_normalize(&x3);
- return secp256k1_fe_equal(&y2, &x3);
+ secp256k1_fe_normalize_weak(&x3);
+ return secp256k1_fe_equal_var(&y2, &x3);
}
static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
- if (a->infinity) {
- r->infinity = 1;
- return;
- }
-
- secp256k1_fe_t t5 = a->y;
- secp256k1_fe_normalize(&t5);
- if (secp256k1_fe_is_zero(&t5)) {
- r->infinity = 1;
+ // For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity,
+ // Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have
+ // y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p.
+ r->infinity = a->infinity;
+ if (r->infinity) {
return;
}
secp256k1_fe_t t1,t2,t3,t4;
- secp256k1_fe_mul(&r->z, &t5, &a->z);
+ secp256k1_fe_mul(&r->z, &a->z, &a->y);
secp256k1_fe_mul_int(&r->z, 2); /* Z' = 2*Y*Z (2) */
secp256k1_fe_sqr(&t1, &a->x);
secp256k1_fe_mul_int(&t1, 3); /* T1 = 3*X^2 (3) */
secp256k1_fe_sqr(&t2, &t1); /* T2 = 9*X^4 (1) */
- secp256k1_fe_sqr(&t3, &t5);
+ secp256k1_fe_sqr(&t3, &a->y);
secp256k1_fe_mul_int(&t3, 2); /* T3 = 2*Y^2 (2) */
secp256k1_fe_sqr(&t4, &t3);
secp256k1_fe_mul_int(&t4, 2); /* T4 = 8*Y^4 (2) */
- secp256k1_fe_mul(&t3, &a->x, &t3); /* T3 = 2*X*Y^2 (1) */
+ secp256k1_fe_mul(&t3, &t3, &a->x); /* T3 = 2*X*Y^2 (1) */
r->x = t3;
secp256k1_fe_mul_int(&r->x, 4); /* X' = 8*X*Y^2 (4) */
secp256k1_fe_negate(&r->x, &r->x, 4); /* X' = -8*X*Y^2 (5) */
secp256k1_fe_mul(&r->y, &t1, &t3); /* Y' = 36*X^3*Y^2 - 27*X^6 (1) */
secp256k1_fe_negate(&t2, &t4, 2); /* T2 = -8*Y^4 (3) */
secp256k1_fe_add(&r->y, &t2); /* Y' = 36*X^3*Y^2 - 27*X^6 - 8*Y^4 (4) */
- r->infinity = 0;
}
static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_t *b) {
secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12);
secp256k1_fe_t s1; secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z);
secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
- secp256k1_fe_normalize(&u1);
- secp256k1_fe_normalize(&u2);
- if (secp256k1_fe_equal(&u1, &u2)) {
- secp256k1_fe_normalize(&s1);
- secp256k1_fe_normalize(&s2);
- if (secp256k1_fe_equal(&s1, &s2)) {
+ secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
+ secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
+ if (secp256k1_fe_normalizes_to_zero_var(&h)) {
+ if (secp256k1_fe_normalizes_to_zero_var(&i)) {
secp256k1_gej_double_var(r, a);
} else {
r->infinity = 1;
}
return;
}
- secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
- secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
secp256k1_fe_t i2; secp256k1_fe_sqr(&i2, &i);
secp256k1_fe_t h2; secp256k1_fe_sqr(&h2, &h);
secp256k1_fe_t h3; secp256k1_fe_mul(&h3, &h, &h2);
}
r->infinity = 0;
secp256k1_fe_t z12; secp256k1_fe_sqr(&z12, &a->z);
- secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize(&u1);
+ secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize_weak(&u1);
secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12);
- secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize(&s1);
+ secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_weak(&s1);
secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
- secp256k1_fe_normalize(&u1);
- secp256k1_fe_normalize(&u2);
- if (secp256k1_fe_equal(&u1, &u2)) {
- secp256k1_fe_normalize(&s1);
- secp256k1_fe_normalize(&s2);
- if (secp256k1_fe_equal(&s1, &s2)) {
+ secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
+ secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
+ if (secp256k1_fe_normalizes_to_zero_var(&h)) {
+ if (secp256k1_fe_normalizes_to_zero_var(&i)) {
secp256k1_gej_double_var(r, a);
} else {
r->infinity = 1;
}
return;
}
- secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
- secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
secp256k1_fe_t i2; secp256k1_fe_sqr(&i2, &i);
secp256k1_fe_t h2; secp256k1_fe_sqr(&h2, &h);
secp256k1_fe_t h3; secp256k1_fe_mul(&h3, &h, &h2);
*
* Substituting x_i = Xi / Zi^2 and yi = Yi / Zi^3, for i=1,2,3, gives:
* U1 = X1*Z2^2, U2 = X2*Z1^2
- * S1 = X1*Z2^3, S2 = X2*Z2^3
+ * S1 = Y1*Z2^3, S2 = Y2*Z1^3
* Z = Z1*Z2
* T = U1+U2
* M = S1+S2
*/
secp256k1_fe_t zz; secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */
- secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize(&u1); /* u1 = U1 = X1*Z2^2 (1) */
+ secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize_weak(&u1); /* u1 = U1 = X1*Z2^2 (1) */
secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */
- secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize(&s1); /* s1 = S1 = Y1*Z2^3 (1) */
+ secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */
secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z2^2 (1) */
secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */
secp256k1_fe_t z = a->z; /* z = Z = Z1*Z2 (8) */
secp256k1_fe_add(&rr, &t); /* rr = R = T^2-U1*U2 (3) */
secp256k1_fe_sqr(&t, &rr); /* t = R^2 (1) */
secp256k1_fe_mul(&r->z, &m, &z); /* r->z = M*Z (1) */
- secp256k1_fe_normalize(&r->z);
- int infinity = secp256k1_fe_is_zero(&r->z) * (1 - a->infinity);
+ int infinity = secp256k1_fe_normalizes_to_zero(&r->z) * (1 - a->infinity);
secp256k1_fe_mul_int(&r->z, 2 * (1 - a->infinity)); /* r->z = Z3 = 2*M*Z (2) */
r->x = t; /* r->x = R^2 (1) */
secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */
secp256k1_fe_mul(&t, &t, &rr); /* t = R*(2*R^2-3*Q) (1) */
secp256k1_fe_add(&t, &n); /* t = R*(2*R^2-3*Q)+M^4 (2) */
secp256k1_fe_negate(&r->y, &t, 2); /* r->y = R*(3*Q-2*R^2)-M^4 (3) */
- secp256k1_fe_normalize(&r->y);
+ secp256k1_fe_normalize_weak(&r->y);
secp256k1_fe_mul_int(&r->x, 4 * (1 - a->infinity)); /* r->x = X3 = 4*(R^2-Q) */
secp256k1_fe_mul_int(&r->y, 4 * (1 - a->infinity)); /* r->y = Y3 = 4*R*(3*Q-2*R^2)-4*M^4 (4) */
*r = *a;
secp256k1_fe_mul(&r->x, &r->x, beta);
}
-
-static void secp256k1_gej_split_exp_var(secp256k1_num_t *r1, secp256k1_num_t *r2, const secp256k1_num_t *a) {
- const secp256k1_ge_consts_t *c = secp256k1_ge_consts;
- secp256k1_num_t bnc1, bnc2, bnt1, bnt2, bnn2;
-
- secp256k1_num_copy(&bnn2, &c->order);
- secp256k1_num_shift(&bnn2, 1);
-
- secp256k1_num_mul(&bnc1, a, &c->a1b2);
- secp256k1_num_add(&bnc1, &bnc1, &bnn2);
- secp256k1_num_div(&bnc1, &bnc1, &c->order);
-
- secp256k1_num_mul(&bnc2, a, &c->b1);
- secp256k1_num_add(&bnc2, &bnc2, &bnn2);
- secp256k1_num_div(&bnc2, &bnc2, &c->order);
-
- secp256k1_num_mul(&bnt1, &bnc1, &c->a1b2);
- secp256k1_num_mul(&bnt2, &bnc2, &c->a2);
- secp256k1_num_add(&bnt1, &bnt1, &bnt2);
- secp256k1_num_sub(r1, a, &bnt1);
- secp256k1_num_mul(&bnt1, &bnc1, &c->b1);
- secp256k1_num_mul(&bnt2, &bnc2, &c->a1b2);
- secp256k1_num_sub(r2, &bnt1, &bnt2);
-}
#endif
-
static void secp256k1_ge_start(void) {
- static const unsigned char secp256k1_ge_consts_order[] = {
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
- 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
- 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41
- };
static const unsigned char secp256k1_ge_consts_g_x[] = {
0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,
0x55,0xA0,0x62,0x95,0xCE,0x87,0x0B,0x07,
};
#ifdef USE_ENDOMORPHISM
/* properties of secp256k1's efficiently computable endomorphism */
- static const unsigned char secp256k1_ge_consts_lambda[] = {
- 0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,
- 0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a,
- 0x12,0x2e,0x22,0xea,0x20,0x81,0x66,0x78,
- 0xdf,0x02,0x96,0x7c,0x1b,0x23,0xbd,0x72
- };
static const unsigned char secp256k1_ge_consts_beta[] = {
0x7a,0xe9,0x6a,0x2b,0x65,0x7c,0x07,0x10,
0x6e,0x64,0x47,0x9e,0xac,0x34,0x34,0xe9,
0x9c,0xf0,0x49,0x75,0x12,0xf5,0x89,0x95,
0xc1,0x39,0x6c,0x28,0x71,0x95,0x01,0xee
};
- static const unsigned char secp256k1_ge_consts_a1b2[] = {
- 0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,
- 0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15
- };
- static const unsigned char secp256k1_ge_consts_b1[] = {
- 0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,
- 0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3
- };
- static const unsigned char secp256k1_ge_consts_a2[] = {
- 0x01,
- 0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,
- 0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8
- };
#endif
if (secp256k1_ge_consts == NULL) {
- secp256k1_ge_consts_t *ret = (secp256k1_ge_consts_t*)malloc(sizeof(secp256k1_ge_consts_t));
- secp256k1_num_set_bin(&ret->order, secp256k1_ge_consts_order, sizeof(secp256k1_ge_consts_order));
- secp256k1_num_copy(&ret->half_order, &ret->order);
- secp256k1_num_shift(&ret->half_order, 1);
+ secp256k1_ge_consts_t *ret = (secp256k1_ge_consts_t*)checked_malloc(sizeof(secp256k1_ge_consts_t));
#ifdef USE_ENDOMORPHISM
- secp256k1_num_set_bin(&ret->lambda, secp256k1_ge_consts_lambda, sizeof(secp256k1_ge_consts_lambda));
- secp256k1_num_set_bin(&ret->a1b2, secp256k1_ge_consts_a1b2, sizeof(secp256k1_ge_consts_a1b2));
- secp256k1_num_set_bin(&ret->a2, secp256k1_ge_consts_a2, sizeof(secp256k1_ge_consts_a2));
- secp256k1_num_set_bin(&ret->b1, secp256k1_ge_consts_b1, sizeof(secp256k1_ge_consts_b1));
- secp256k1_fe_set_b32(&ret->beta, secp256k1_ge_consts_beta);
+ VERIFY_CHECK(secp256k1_fe_set_b32(&ret->beta, secp256k1_ge_consts_beta));
#endif
secp256k1_fe_t g_x, g_y;
- secp256k1_fe_set_b32(&g_x, secp256k1_ge_consts_g_x);
- secp256k1_fe_set_b32(&g_y, secp256k1_ge_consts_g_y);
+ VERIFY_CHECK(secp256k1_fe_set_b32(&g_x, secp256k1_ge_consts_g_x));
+ VERIFY_CHECK(secp256k1_fe_set_b32(&g_y, secp256k1_ge_consts_g_y));
secp256k1_ge_set_xy(&ret->g, &g_x, &g_y);
secp256k1_ge_consts = ret;
}
--- /dev/null
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_HASH_
+#define _SECP256K1_HASH_
+
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef struct {
+ uint32_t s[32];
+ unsigned char buf[64];
+ size_t bytes;
+} secp256k1_sha256_t;
+
+static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash);
+static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t size);
+static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32);
+
+typedef struct {
+ secp256k1_sha256_t inner, outer;
+} secp256k1_hmac_sha256_t;
+
+static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t size);
+static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size);
+static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32);
+
+typedef struct {
+ unsigned char v[32];
+ unsigned char k[32];
+ int retry;
+} secp256k1_rfc6979_hmac_sha256_t;
+
+static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen);
+static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen);
+static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng);
+
+#endif
--- /dev/null
+/**********************************************************************
+ * Copyright (c) 2014 Pieter Wuille *
+ * Distributed under the MIT software license, see the accompanying *
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
+ **********************************************************************/
+
+#ifndef _SECP256K1_HASH_IMPL_H_
+#define _SECP256K1_HASH_IMPL_H_
+
+#include "hash.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
+#define Maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
+#define Sigma0(x) (((x) >> 2 | (x) << 30) ^ ((x) >> 13 | (x) << 19) ^ ((x) >> 22 | (x) << 10))
+#define Sigma1(x) (((x) >> 6 | (x) << 26) ^ ((x) >> 11 | (x) << 21) ^ ((x) >> 25 | (x) << 7))
+#define sigma0(x) (((x) >> 7 | (x) << 25) ^ ((x) >> 18 | (x) << 14) ^ ((x) >> 3))
+#define sigma1(x) (((x) >> 17 | (x) << 15) ^ ((x) >> 19 | (x) << 13) ^ ((x) >> 10))
+
+#define Round(a,b,c,d,e,f,g,h,k,w) do { \
+ uint32_t t1 = (h) + Sigma1(e) + Ch((e), (f), (g)) + (k) + (w); \
+ uint32_t t2 = Sigma0(a) + Maj((a), (b), (c)); \
+ (d) += t1; \
+ (h) = t1 + t2; \
+} while(0)
+
+#define ReadBE32(p) (((uint32_t)((p)[0])) << 24 | ((uint32_t)((p)[1])) << 16 | ((uint32_t)((p)[2])) << 8 | ((uint32_t)((p)[3])))
+#define WriteBE32(p, v) do { (p)[0] = (v) >> 24; (p)[1] = (v) >> 16; (p)[2] = (v) >> 8; (p)[3] = (v); } while(0)
+
+static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash) {
+ hash->s[0] = 0x6a09e667ul;
+ hash->s[1] = 0xbb67ae85ul;
+ hash->s[2] = 0x3c6ef372ul;
+ hash->s[3] = 0xa54ff53aul;
+ hash->s[4] = 0x510e527ful;
+ hash->s[5] = 0x9b05688cul;
+ hash->s[6] = 0x1f83d9abul;
+ hash->s[7] = 0x5be0cd19ul;
+ hash->bytes = 0;
+}
+
+/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
+static void secp256k1_sha256_transform(uint32_t* s, const unsigned char* chunk) {
+ uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
+ uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
+
+ Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0));
+ Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4));
+ Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8));
+ Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12));
+ Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16));
+ Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20));
+ Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24));
+ Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28));
+ Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32));
+ Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36));
+ Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40));
+ Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44));
+ Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48));
+ Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52));
+ Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56));
+ Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60));
+
+ Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));
+
+ s[0] += a;
+ s[1] += b;
+ s[2] += c;
+ s[3] += d;
+ s[4] += e;
+ s[5] += f;
+ s[6] += g;
+ s[7] += h;
+}
+
+static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t len) {
+ const unsigned char* end = data + len;
+ size_t bufsize = hash->bytes % 64;
+ if (bufsize && bufsize + len >= 64) {
+ // Fill the buffer, and process it.
+ memcpy(hash->buf + bufsize, data, 64 - bufsize);
+ hash->bytes += 64 - bufsize;
+ data += 64 - bufsize;
+ secp256k1_sha256_transform(hash->s, hash->buf);
+ bufsize = 0;
+ }
+ while (end >= data + 64) {
+ // Process full chunks directly from the source.
+ secp256k1_sha256_transform(hash->s, data);
+ hash->bytes += 64;
+ data += 64;
+ }
+ if (end > data) {
+ // Fill the buffer with what remains.
+ memcpy(hash->buf + bufsize, data, end - data);
+ hash->bytes += end - data;
+ }
+}
+
+static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32) {
+ static const unsigned char pad[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ unsigned char sizedesc[8];
+ WriteBE32(sizedesc, hash->bytes >> 29);
+ WriteBE32(sizedesc + 4, hash->bytes << 3);
+ secp256k1_sha256_write(hash, pad, 1 + ((119 - (hash->bytes % 64)) % 64));
+ secp256k1_sha256_write(hash, sizedesc, 8);
+ WriteBE32(out32, hash->s[0]);
+ hash->s[0] = 0;
+ WriteBE32(out32 + 4, hash->s[1]);
+ hash->s[1] = 0;
+ WriteBE32(out32 + 8, hash->s[2]);
+ hash->s[2] = 0;
+ WriteBE32(out32 + 12, hash->s[3]);
+ hash->s[3] = 0;
+ WriteBE32(out32 + 16, hash->s[4]);
+ hash->s[4] = 0;
+ WriteBE32(out32 + 20, hash->s[5]);
+ hash->s[5] = 0;
+ WriteBE32(out32 + 24, hash->s[6]);
+ hash->s[6] = 0;
+ WriteBE32(out32 + 28, hash->s[7]);
+ hash->s[7] = 0;
+}
+
+static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t keylen) {
+ unsigned char rkey[64];
+ if (keylen <= 64) {
+ memcpy(rkey, key, keylen);
+ memset(rkey + keylen, 0, 64 - keylen);
+ } else {
+ secp256k1_sha256_t sha256;
+ secp256k1_sha256_initialize(&sha256);
+ secp256k1_sha256_write(&sha256, key, keylen);
+ secp256k1_sha256_finalize(&sha256, rkey);
+ memset(rkey + 32, 0, 32);
+ }
+
+ secp256k1_sha256_initialize(&hash->outer);
+ for (int n = 0; n < 64; n++)
+ rkey[n] ^= 0x5c;
+ secp256k1_sha256_write(&hash->outer, rkey, 64);
+
+ secp256k1_sha256_initialize(&hash->inner);
+ for (int n = 0; n < 64; n++)
+ rkey[n] ^= 0x5c ^ 0x36;
+ secp256k1_sha256_write(&hash->inner, rkey, 64);
+ memset(rkey, 0, 64);
+}
+
+static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size) {
+ secp256k1_sha256_write(&hash->inner, data, size);
+}
+
+static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32) {
+ unsigned char temp[32];
+ secp256k1_sha256_finalize(&hash->inner, temp);
+ secp256k1_sha256_write(&hash->outer, temp, 32);
+ memset(temp, 0, 32);
+ secp256k1_sha256_finalize(&hash->outer, out32);
+}
+
+
+static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen) {
+ static const unsigned char zero[1] = {0x00};
+ static const unsigned char one[1] = {0x01};
+
+ memset(rng->v, 0x01, 32);
+ memset(rng->k, 0x00, 32);
+
+ secp256k1_hmac_sha256_t hmac;
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_write(&hmac, zero, 1);
+ secp256k1_hmac_sha256_write(&hmac, key, keylen);
+ secp256k1_hmac_sha256_write(&hmac, msg, msglen);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->k);
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->v);
+
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_write(&hmac, one, 1);
+ secp256k1_hmac_sha256_write(&hmac, key, keylen);
+ secp256k1_hmac_sha256_write(&hmac, msg, msglen);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->k);
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->v);
+ rng->retry = 0;
+}
+
+static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen) {
+ static const unsigned char zero[1] = {0x00};
+ if (rng->retry) {
+ secp256k1_hmac_sha256_t hmac;
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_write(&hmac, zero, 1);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->k);
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->v);
+ }
+
+ while (outlen > 0) {
+ secp256k1_hmac_sha256_t hmac;
+ secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
+ secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
+ secp256k1_hmac_sha256_finalize(&hmac, rng->v);
+ int now = outlen;
+ if (now > 32) {
+ now = 32;
+ }
+ memcpy(out, rng->v, now);
+ out += now;
+ outlen -= now;
+ }
+
+ rng->retry = 1;
+}
+
+static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng) {
+ memset(rng->k, 0, 32);
+ memset(rng->v, 0, 32);
+ rng->retry = 0;
+}
+
+
+#undef Round
+#undef sigma0
+#undef sigma1
+#undef Sigma0
+#undef Sigma1
+#undef Ch
+#undef Maj
+#undef ReadBE32
+#undef WriteBE32
+
+#endif
#ifndef _SECP256K1_NUM_
#define _SECP256K1_NUM_
+#ifndef USE_NUM_NONE
+
#if defined HAVE_CONFIG_H
#include "libsecp256k1-config.h"
#endif
#error "Please select num implementation"
#endif
-/** Clear a number to prevent the leak of sensitive data. */
-static void secp256k1_num_clear(secp256k1_num_t *r);
-
/** Copy a number. */
static void secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a);
/** Set a number to the value of a binary big-endian string. */
static void secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen);
-/** Set a number equal to a (signed) integer. */
-static void secp256k1_num_set_int(secp256k1_num_t *r, int a);
-
/** Compute a modular inverse. The input must be less than the modulus. */
static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m);
-/** Multiply two numbers modulo another. */
-static void secp256k1_num_mod_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b, const secp256k1_num_t *m);
-
/** Compare the absolute value of two numbers. */
static int secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b);
/** Multiply two (signed) numbers. */
static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b);
-/** Divide two (signed) numbers. */
-static void secp256k1_num_div(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b);
-
/** Replace a number by its remainder modulo m. M's sign is ignored. The result is a number between 0 and m-1,
even if r was negative. */
static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m);
-/** Calculate the number of bits in (the absolute value of) a number. */
-static int secp256k1_num_bits(const secp256k1_num_t *a);
-
-/** Right-shift the passed number by bits bits, and return those bits. */
-static int secp256k1_num_shift(secp256k1_num_t *r, int bits);
+/** Right-shift the passed number by bits bits. */
+static void secp256k1_num_shift(secp256k1_num_t *r, int bits);
/** Check whether a number is zero. */
static int secp256k1_num_is_zero(const secp256k1_num_t *a);
-/** Check whether a number is odd. */
-static int secp256k1_num_is_odd(const secp256k1_num_t *a);
-
/** Check whether a number is strictly negative. */
static int secp256k1_num_is_neg(const secp256k1_num_t *a);
-/** Check whether a particular bit is set in a number. */
-static int secp256k1_num_get_bit(const secp256k1_num_t *a, int pos);
-
-/** Increase a number by 1. */
-static void secp256k1_num_inc(secp256k1_num_t *r);
-
-/** Set a number equal to the value of a hex string (unsigned). */
-static void secp256k1_num_set_hex(secp256k1_num_t *r, const char *a, int alen);
-
-/** Convert (the absolute value of) a number to a hexadecimal string. */
-static void secp256k1_num_get_hex(char *r, int rlen, const secp256k1_num_t *a);
-
-/** Split a number into a low and high part. */
-static void secp256k1_num_split(secp256k1_num_t *rl, secp256k1_num_t *rh, const secp256k1_num_t *a, int bits);
-
/** Change a number's sign. */
static void secp256k1_num_negate(secp256k1_num_t *r);
-/** Get a bunch of bits from a number. */
-static int secp256k1_num_get_bits(const secp256k1_num_t *a, int offset, int count);
+#endif
#endif
#define secp256k1_num_sanity(a) do { } while(0)
#endif
-static void secp256k1_num_init(secp256k1_num_t *r) {
- r->neg = 0;
- r->limbs = 1;
- r->data[0] = 0;
-}
-
-static void secp256k1_num_clear(secp256k1_num_t *r) {
- memset(r, 0, sizeof(*r));
-}
-
-static void secp256k1_num_free(secp256k1_num_t *r) {
- (void)r;
-}
-
static void secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a) {
*r = *a;
}
-static int secp256k1_num_bits(const secp256k1_num_t *a) {
- int ret=(a->limbs-1)*GMP_NUMB_BITS;
- mp_limb_t x=a->data[a->limbs-1];
- while (x) {
- x >>= 1;
- ret++;
- }
- return ret;
-}
-
-
static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a) {
unsigned char tmp[65];
int len = 0;
VERIFY_CHECK(alen > 0);
VERIFY_CHECK(alen <= 64);
int len = mpn_set_str(r->data, a, alen, 256);
+ if (len == 0) {
+ r->data[0] = 0;
+ len = 1;
+ }
VERIFY_CHECK(len <= NUM_LIMBS*2);
r->limbs = len;
r->neg = 0;
while (r->limbs > 1 && r->data[r->limbs-1]==0) r->limbs--;
}
-static void secp256k1_num_set_int(secp256k1_num_t *r, int a) {
- r->limbs = 1;
- r->neg = (a < 0);
- r->data[0] = (a < 0) ? -a : a;
-}
-
static void secp256k1_num_add_abs(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) {
mp_limb_t c = mpn_add(r->data, a->data, a->limbs, b->data, b->limbs);
r->limbs = a->limbs;
return (a->limbs == 1 && a->data[0] == 0);
}
-static int secp256k1_num_is_odd(const secp256k1_num_t *a) {
- return a->data[0] & 1;
-}
-
static int secp256k1_num_is_neg(const secp256k1_num_t *a) {
return (a->limbs > 1 || a->data[0] != 0) && a->neg;
}
memset(tmp, 0, sizeof(tmp));
}
-static void secp256k1_num_div(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) {
- secp256k1_num_sanity(a);
- secp256k1_num_sanity(b);
- if (b->limbs > a->limbs) {
- r->limbs = 1;
- r->data[0] = 0;
- r->neg = 0;
- return;
- }
-
- mp_limb_t quo[2*NUM_LIMBS+1];
- mp_limb_t rem[2*NUM_LIMBS+1];
- mpn_tdiv_qr(quo, rem, 0, a->data, a->limbs, b->data, b->limbs);
- mpn_copyi(r->data, quo, a->limbs - b->limbs + 1);
- r->limbs = a->limbs - b->limbs + 1;
- while (r->limbs > 1 && r->data[r->limbs - 1]==0) r->limbs--;
- r->neg = a->neg ^ b->neg;
-}
-
-static void secp256k1_num_mod_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b, const secp256k1_num_t *m) {
- secp256k1_num_mul(r, a, b);
- secp256k1_num_mod(r, m);
-}
-
-
-static int secp256k1_num_shift(secp256k1_num_t *r, int bits) {
- VERIFY_CHECK(bits <= GMP_NUMB_BITS);
- mp_limb_t ret = mpn_rshift(r->data, r->data, r->limbs, bits);
- if (r->limbs>1 && r->data[r->limbs-1]==0) r->limbs--;
- ret >>= (GMP_NUMB_BITS - bits);
- return ret;
-}
-
-static int secp256k1_num_get_bit(const secp256k1_num_t *a, int pos) {
- return (a->limbs*GMP_NUMB_BITS > pos) && ((a->data[pos/GMP_NUMB_BITS] >> (pos % GMP_NUMB_BITS)) & 1);
-}
-
-static void secp256k1_num_inc(secp256k1_num_t *r) {
- mp_limb_t ret = mpn_add_1(r->data, r->data, r->limbs, (mp_limb_t)1);
- if (ret) {
- VERIFY_CHECK(r->limbs < 2*NUM_LIMBS);
- r->data[r->limbs++] = ret;
- }
-}
-
-static void secp256k1_num_set_hex(secp256k1_num_t *r, const char *a, int alen) {
- static const unsigned char cvt[256] = {
- 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
- 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
- 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
- 0, 1, 2, 3, 4, 5, 6,7,8,9,0,0,0,0,0,0,
- 0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,
- 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
- 0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,
- 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
- 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
- 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
- 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
- 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
- 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
- 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
- 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
- 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0
- };
- unsigned char num[257] = {};
- for (int i=0; i<alen; i++) {
- num[i] = cvt[(unsigned char)a[i]];
- }
- r->limbs = mpn_set_str(r->data, num, alen, 16);
- r->neg = 0;
- while (r->limbs > 1 && r->data[r->limbs-1] == 0) r->limbs--;
-}
-
-static void secp256k1_num_get_hex(char *r, int rlen, const secp256k1_num_t *a) {
- static const unsigned char cvt[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
- unsigned char *tmp = malloc(257);
- mp_size_t len = mpn_get_str(tmp, 16, (mp_limb_t*)a->data, a->limbs);
- VERIFY_CHECK(len <= rlen);
- for (int i=0; i<len; i++) {
- VERIFY_CHECK(rlen-len+i >= 0);
- VERIFY_CHECK(rlen-len+i < rlen);
- VERIFY_CHECK(tmp[i] < 16);
- r[rlen-len+i] = cvt[tmp[i]];
- }
- for (int i=0; i<rlen-len; i++) {
- VERIFY_CHECK(i >= 0);
- VERIFY_CHECK(i < rlen);
- r[i] = cvt[0];
- }
- free(tmp);
-}
-
-static void secp256k1_num_split(secp256k1_num_t *rl, secp256k1_num_t *rh, const secp256k1_num_t *a, int bits) {
- VERIFY_CHECK(bits > 0);
- rh->neg = a->neg;
- if (bits >= a->limbs * GMP_NUMB_BITS) {
- *rl = *a;
- rh->limbs = 1;
- rh->data[0] = 0;
- return;
- }
- rl->limbs = 0;
- rl->neg = a->neg;
- int left = bits;
- while (left >= GMP_NUMB_BITS) {
- rl->data[rl->limbs] = a->data[rl->limbs];
- rl->limbs++;
- left -= GMP_NUMB_BITS;
- }
- if (left == 0) {
- mpn_copyi(rh->data, a->data + rl->limbs, a->limbs - rl->limbs);
- rh->limbs = a->limbs - rl->limbs;
- } else {
- mpn_rshift(rh->data, a->data + rl->limbs, a->limbs - rl->limbs, left);
- rh->limbs = a->limbs - rl->limbs;
- while (rh->limbs>1 && rh->data[rh->limbs-1]==0) rh->limbs--;
- }
- if (left > 0) {
- rl->data[rl->limbs] = a->data[rl->limbs] & ((((mp_limb_t)1) << left) - 1);
- rl->limbs++;
+static void secp256k1_num_shift(secp256k1_num_t *r, int bits) {
+ if (bits % GMP_NUMB_BITS) {
+ // Shift within limbs.
+ mpn_rshift(r->data, r->data, r->limbs, bits % GMP_NUMB_BITS);
+ }
+ if (bits >= GMP_NUMB_BITS) {
+ // Shift full limbs.
+ for (int i = 0; i < r->limbs; i++) {
+ int index = i + (bits / GMP_NUMB_BITS);
+ if (index < r->limbs && index < 2*NUM_LIMBS) {
+ r->data[i] = r->data[index];
+ } else {
+ r->data[i] = 0;
+ }
+ }
}
- while (rl->limbs>1 && rl->data[rl->limbs-1]==0) rl->limbs--;
+ while (r->limbs>1 && r->data[r->limbs-1]==0) r->limbs--;
}
static void secp256k1_num_negate(secp256k1_num_t *r) {
r->neg ^= 1;
}
-static int secp256k1_num_get_bits(const secp256k1_num_t *a, int offset, int count) {
- int ret = 0;
- for (int i = 0; i < count; i++) {
- ret |= ((a->data[(offset + i) / GMP_NUMB_BITS] >> ((offset + i) % GMP_NUMB_BITS)) & 1) << i;
- }
- return ret;
-}
-
#endif
#if defined(USE_NUM_GMP)
#include "num_gmp_impl.h"
+#elif defined(USE_NUM_NONE)
+/* Nothing. */
#else
#error "Please select num implementation"
#endif
#error "Please select scalar implementation"
#endif
+static void secp256k1_scalar_start(void);
+static void secp256k1_scalar_stop(void);
+
/** Clear a scalar to prevent the leak of sensitive data. */
static void secp256k1_scalar_clear(secp256k1_scalar_t *r);
-/** Access bits from a scalar. */
-static int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, int offset, int count);
+/** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */
+static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count);
+
+/** Access bits from a scalar. Not constant time. */
+static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count);
/** Set a scalar from a big endian byte array. */
static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *bin, int *overflow);
+/** Set a scalar to an unsigned integer. */
+static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, unsigned int v);
+
/** Convert a scalar to a byte array. */
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_t* a);
-/** Add two scalars together (modulo the group order). */
-static void secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b);
+/** Add two scalars together (modulo the group order). Returns whether it overflowed. */
+static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b);
+
+/** Add a power of two to a scalar. The result is not allowed to overflow. */
+static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit);
/** Multiply two scalars (modulo the group order). */
static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b);
/** Compute the inverse of a scalar (modulo the group order). */
static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scalar_t *a);
+/** Compute the inverse of a scalar (modulo the group order), without constant-time guarantee. */
+static void secp256k1_scalar_inverse_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a);
+
/** Compute the complement of a scalar (modulo the group order). */
static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scalar_t *a);
/** Check whether a scalar is higher than the group order divided by 2. */
static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a);
+#ifndef USE_NUM_NONE
/** Convert a scalar to a number. */
static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a);
+/** Get the order of the group as a number. */
+static void secp256k1_scalar_order_get_num(secp256k1_num_t *r);
+#endif
+
+/** Compare two scalars. */
+static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b);
+
+static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a);
+
+#ifdef USE_ENDOMORPHISM
+/** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (see secp256k1_gej_mul_lambda). */
+static void secp256k1_scalar_split_lambda_var(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a);
+#endif
+
+/** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */
+static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift);
+
#endif
r->d[3] = 0;
}
-SECP256K1_INLINE static int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, int offset, int count) {
- VERIFY_CHECK((offset + count - 1) / 64 == offset / 64);
- return (a->d[offset / 64] >> (offset % 64)) & ((((uint64_t)1) << count) - 1);
+SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, unsigned int v) {
+ r->d[0] = v;
+ r->d[1] = 0;
+ r->d[2] = 0;
+ r->d[3] = 0;
+}
+
+SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) {
+ VERIFY_CHECK((offset + count - 1) >> 6 == offset >> 6);
+ return (a->d[offset >> 6] >> (offset & 0x3F)) & ((((uint64_t)1) << count) - 1);
+}
+
+SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) {
+ VERIFY_CHECK(count < 32);
+ VERIFY_CHECK(offset + count <= 256);
+ if ((offset + count - 1) >> 6 == offset >> 6) {
+ return secp256k1_scalar_get_bits(a, offset, count);
+ } else {
+ VERIFY_CHECK((offset >> 6) + 1 < 4);
+ return ((a->d[offset >> 6] >> (offset & 0x3F)) | (a->d[(offset >> 6) + 1] << (64 - (offset & 0x3F)))) & ((((uint64_t)1) << count) - 1);
+ }
}
SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar_t *a) {
return overflow;
}
-static void secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
uint128_t t = (uint128_t)a->d[0] + b->d[0];
r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
t += (uint128_t)a->d[1] + b->d[1];
r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
t += (uint128_t)a->d[3] + b->d[3];
r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
- secp256k1_scalar_reduce(r, t + secp256k1_scalar_check_overflow(r));
+ int overflow = t + secp256k1_scalar_check_overflow(r);
+ VERIFY_CHECK(overflow == 0 || overflow == 1);
+ secp256k1_scalar_reduce(r, overflow);
+ return overflow;
+}
+
+static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) {
+ VERIFY_CHECK(bit < 256);
+ uint128_t t = (uint128_t)r->d[0] + (((uint64_t)((bit >> 6) == 0)) << (bit & 0x3F));
+ r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
+ t += (uint128_t)r->d[1] + (((uint64_t)((bit >> 6) == 1)) << (bit & 0x3F));
+ r->d[1] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
+ t += (uint128_t)r->d[2] + (((uint64_t)((bit >> 6) == 2)) << (bit & 0x3F));
+ r->d[2] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64;
+ t += (uint128_t)r->d[3] + (((uint64_t)((bit >> 6) == 3)) << (bit & 0x3F));
+ r->d[3] = t & 0xFFFFFFFFFFFFFFFFULL;
+#ifdef VERIFY
+ VERIFY_CHECK((t >> 64) == 0);
+ VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0);
+#endif
}
static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *b32, int *overflow) {
secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r));
}
-static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
/* 160 bit accumulator. */
uint64_t c0 = 0, c1 = 0;
uint32_t c2 = 0;
- uint64_t l[8];
-
/* l[0..7] = a[0..3] * b[0..3]. */
muladd_fast(a->d[0], b->d[0]);
extract_fast(l[0]);
extract_fast(l[6]);
VERIFY_CHECK(c1 <= 0);
l[7] = c0;
-
- secp256k1_scalar_reduce_512(r, l);
}
-static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) {
+static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar_t *a) {
/* 160 bit accumulator. */
uint64_t c0 = 0, c1 = 0;
uint32_t c2 = 0;
- uint64_t l[8];
-
/* l[0..7] = a[0..3] * b[0..3]. */
muladd_fast(a->d[0], a->d[0]);
extract_fast(l[0]);
extract_fast(l[6]);
VERIFY_CHECK(c1 == 0);
l[7] = c0;
-
- secp256k1_scalar_reduce_512(r, l);
}
#undef sumadd
#undef extract
#undef extract_fast
+static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+ uint64_t l[8];
+ secp256k1_scalar_mul_512(l, a, b);
+ secp256k1_scalar_reduce_512(r, l);
+}
+
+static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) {
+ uint64_t l[8];
+ secp256k1_scalar_sqr_512(l, a);
+ secp256k1_scalar_reduce_512(r, l);
+}
+
+static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) {
+ r1->d[0] = a->d[0];
+ r1->d[1] = a->d[1];
+ r1->d[2] = 0;
+ r1->d[3] = 0;
+ r2->d[0] = a->d[2];
+ r2->d[1] = a->d[3];
+ r2->d[2] = 0;
+ r2->d[3] = 0;
+}
+
+SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+ return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3])) == 0;
+}
+
+SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift) {
+ VERIFY_CHECK(shift >= 256);
+ uint64_t l[8];
+ secp256k1_scalar_mul_512(l, a, b);
+ unsigned int shiftlimbs = shift >> 6;
+ unsigned int shiftlow = shift & 0x3F;
+ unsigned int shifthigh = 64 - shiftlow;
+ r->d[0] = shift < 512 ? (l[0 + shiftlimbs] >> shiftlow | (shift < 448 && shiftlow ? (l[1 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[1] = shift < 448 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 384 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[2] = shift < 384 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[3] = shift < 320 ? (l[3 + shiftlimbs] >> shiftlow) : 0;
+ if ((l[(shift - 1) >> 6] >> ((shift - 1) & 0x3f)) & 1) {
+ secp256k1_scalar_add_bit(r, 0);
+ }
+}
+
#endif
r->d[7] = 0;
}
-SECP256K1_INLINE static int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, int offset, int count) {
- VERIFY_CHECK((offset + count - 1) / 32 == offset / 32);
- return (a->d[offset / 32] >> (offset % 32)) & ((1 << count) - 1);
+SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, unsigned int v) {
+ r->d[0] = v;
+ r->d[1] = 0;
+ r->d[2] = 0;
+ r->d[3] = 0;
+ r->d[4] = 0;
+ r->d[5] = 0;
+ r->d[6] = 0;
+ r->d[7] = 0;
+}
+
+SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) {
+ VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5);
+ return (a->d[offset >> 5] >> (offset & 0x1F)) & ((1 << count) - 1);
+}
+
+SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) {
+ VERIFY_CHECK(count < 32);
+ VERIFY_CHECK(offset + count <= 256);
+ if ((offset + count - 1) >> 5 == offset >> 5) {
+ return secp256k1_scalar_get_bits(a, offset, count);
+ } else {
+ VERIFY_CHECK((offset >> 5) + 1 < 8);
+ return ((a->d[offset >> 5] >> (offset & 0x1F)) | (a->d[(offset >> 5) + 1] << (32 - (offset & 0x1F)))) & ((((uint32_t)1) << count) - 1);
+ }
}
SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar_t *a) {
return overflow;
}
-static void secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
uint64_t t = (uint64_t)a->d[0] + b->d[0];
r->d[0] = t & 0xFFFFFFFFULL; t >>= 32;
t += (uint64_t)a->d[1] + b->d[1];
r->d[6] = t & 0xFFFFFFFFULL; t >>= 32;
t += (uint64_t)a->d[7] + b->d[7];
r->d[7] = t & 0xFFFFFFFFULL; t >>= 32;
- secp256k1_scalar_reduce(r, t + secp256k1_scalar_check_overflow(r));
+ int overflow = t + secp256k1_scalar_check_overflow(r);
+ VERIFY_CHECK(overflow == 0 || overflow == 1);
+ secp256k1_scalar_reduce(r, overflow);
+ return overflow;
+}
+
+static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) {
+ VERIFY_CHECK(bit < 256);
+ uint64_t t = (uint64_t)r->d[0] + (((uint32_t)((bit >> 5) == 0)) << (bit & 0x1F));
+ r->d[0] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[1] + (((uint32_t)((bit >> 5) == 1)) << (bit & 0x1F));
+ r->d[1] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[2] + (((uint32_t)((bit >> 5) == 2)) << (bit & 0x1F));
+ r->d[2] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[3] + (((uint32_t)((bit >> 5) == 3)) << (bit & 0x1F));
+ r->d[3] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[4] + (((uint32_t)((bit >> 5) == 4)) << (bit & 0x1F));
+ r->d[4] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[5] + (((uint32_t)((bit >> 5) == 5)) << (bit & 0x1F));
+ r->d[5] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[6] + (((uint32_t)((bit >> 5) == 6)) << (bit & 0x1F));
+ r->d[6] = t & 0xFFFFFFFFULL; t >>= 32;
+ t += (uint64_t)r->d[7] + (((uint32_t)((bit >> 5) == 7)) << (bit & 0x1F));
+ r->d[7] = t & 0xFFFFFFFFULL;
+#ifdef VERIFY
+ VERIFY_CHECK((t >> 32) == 0);
+ VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0);
+#endif
}
static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *b32, int *overflow) {
secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r));
}
-static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+static void secp256k1_scalar_mul_512(uint32_t l[16], const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
/* 96 bit accumulator. */
uint32_t c0 = 0, c1 = 0, c2 = 0;
- uint32_t l[16];
-
/* l[0..15] = a[0..7] * b[0..7]. */
muladd_fast(a->d[0], b->d[0]);
extract_fast(l[0]);
extract_fast(l[14]);
VERIFY_CHECK(c1 == 0);
l[15] = c0;
-
- secp256k1_scalar_reduce_512(r, l);
}
-static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) {
+static void secp256k1_scalar_sqr_512(uint32_t l[16], const secp256k1_scalar_t *a) {
/* 96 bit accumulator. */
uint32_t c0 = 0, c1 = 0, c2 = 0;
- uint32_t l[16];
-
/* l[0..15] = a[0..7]^2. */
muladd_fast(a->d[0], a->d[0]);
extract_fast(l[0]);
extract_fast(l[14]);
VERIFY_CHECK(c1 == 0);
l[15] = c0;
-
- secp256k1_scalar_reduce_512(r, l);
}
#undef sumadd
#undef extract
#undef extract_fast
+static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+ uint32_t l[16];
+ secp256k1_scalar_mul_512(l, a, b);
+ secp256k1_scalar_reduce_512(r, l);
+}
+
+static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) {
+ uint32_t l[16];
+ secp256k1_scalar_sqr_512(l, a);
+ secp256k1_scalar_reduce_512(r, l);
+}
+
+static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) {
+ r1->d[0] = a->d[0];
+ r1->d[1] = a->d[1];
+ r1->d[2] = a->d[2];
+ r1->d[3] = a->d[3];
+ r1->d[4] = 0;
+ r1->d[5] = 0;
+ r1->d[6] = 0;
+ r1->d[7] = 0;
+ r2->d[0] = a->d[4];
+ r2->d[1] = a->d[5];
+ r2->d[2] = a->d[6];
+ r2->d[3] = a->d[7];
+ r2->d[4] = 0;
+ r2->d[5] = 0;
+ r2->d[6] = 0;
+ r2->d[7] = 0;
+}
+
+SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
+ return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3]) | (a->d[4] ^ b->d[4]) | (a->d[5] ^ b->d[5]) | (a->d[6] ^ b->d[6]) | (a->d[7] ^ b->d[7])) == 0;
+}
+
+SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift) {
+ VERIFY_CHECK(shift >= 256);
+ uint32_t l[16];
+ secp256k1_scalar_mul_512(l, a, b);
+ unsigned int shiftlimbs = shift >> 5;
+ unsigned int shiftlow = shift & 0x1F;
+ unsigned int shifthigh = 32 - shiftlow;
+ r->d[0] = shift < 512 ? (l[0 + shiftlimbs] >> shiftlow | (shift < 480 && shiftlow ? (l[1 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[1] = shift < 480 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 448 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[2] = shift < 448 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 416 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[3] = shift < 416 ? (l[3 + shiftlimbs] >> shiftlow | (shift < 384 && shiftlow ? (l[4 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[4] = shift < 384 ? (l[4 + shiftlimbs] >> shiftlow | (shift < 352 && shiftlow ? (l[5 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[5] = shift < 352 ? (l[5 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[6 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[6] = shift < 320 ? (l[6 + shiftlimbs] >> shiftlow | (shift < 288 && shiftlow ? (l[7 + shiftlimbs] << shifthigh) : 0)) : 0;
+ r->d[7] = shift < 288 ? (l[7 + shiftlimbs] >> shiftlow) : 0;
+ if ((l[(shift - 1) >> 5] >> ((shift - 1) & 0x1f)) & 1) {
+ secp256k1_scalar_add_bit(r, 0);
+ }
+}
+
#endif
#include <string.h>
+#include "group.h"
#include "scalar.h"
#if defined HAVE_CONFIG_H
#error "Please select scalar implementation"
#endif
+typedef struct {
+#ifndef USE_NUM_NONE
+ secp256k1_num_t order;
+#endif
+#ifdef USE_ENDOMORPHISM
+ secp256k1_scalar_t minus_lambda, minus_b1, minus_b2, g1, g2;
+#endif
+} secp256k1_scalar_consts_t;
+
+static const secp256k1_scalar_consts_t *secp256k1_scalar_consts = NULL;
+
+static void secp256k1_scalar_start(void) {
+ if (secp256k1_scalar_consts != NULL)
+ return;
+
+ /* Allocate. */
+ secp256k1_scalar_consts_t *ret = (secp256k1_scalar_consts_t*)checked_malloc(sizeof(secp256k1_scalar_consts_t));
+
+#ifndef USE_NUM_NONE
+ static const unsigned char secp256k1_scalar_consts_order[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+ 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
+ 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41
+ };
+ secp256k1_num_set_bin(&ret->order, secp256k1_scalar_consts_order, sizeof(secp256k1_scalar_consts_order));
+#endif
+#ifdef USE_ENDOMORPHISM
+ /**
+ * Lambda is a scalar which has the property for secp256k1 that point multiplication by
+ * it is efficiently computable (see secp256k1_gej_mul_lambda). */
+ static const unsigned char secp256k1_scalar_consts_lambda[32] = {
+ 0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,
+ 0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a,
+ 0x12,0x2e,0x22,0xea,0x20,0x81,0x66,0x78,
+ 0xdf,0x02,0x96,0x7c,0x1b,0x23,0xbd,0x72
+ };
+ /**
+ * "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm
+ * (algorithm 3.74) to find k1 and k2 given k, such that k1 + k2 * lambda == k mod n, and k1
+ * and k2 have a small size.
+ * It relies on constants a1, b1, a2, b2. These constants for the value of lambda above are:
+ *
+ * - a1 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15}
+ * - b1 = -{0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3}
+ * - a2 = {0x01,0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8}
+ * - b2 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15}
+ *
+ * The algorithm then computes c1 = round(b1 * k / n) and c2 = round(b2 * k / n), and gives
+ * k1 = k - (c1*a1 + c2*a2) and k2 = -(c1*b1 + c2*b2). Instead, we use modular arithmetic, and
+ * compute k1 as k - k2 * lambda, avoiding the need for constants a1 and a2.
+ *
+ * g1, g2 are precomputed constants used to replace division with a rounded multiplication
+ * when decomposing the scalar for an endomorphism-based point multiplication.
+ *
+ * The possibility of using precomputed estimates is mentioned in "Guide to Elliptic Curve
+ * Cryptography" (Hankerson, Menezes, Vanstone) in section 3.5.
+ *
+ * The derivation is described in the paper "Efficient Software Implementation of Public-Key
+ * Cryptography on Sensor Networks Using the MSP430X Microcontroller" (Gouvea, Oliveira, Lopez),
+ * Section 4.3 (here we use a somewhat higher-precision estimate):
+ * d = a1*b2 - b1*a2
+ * g1 = round((2^272)*b2/d)
+ * g2 = round((2^272)*b1/d)
+ *
+ * (Note that 'd' is also equal to the curve order here because [a1,b1] and [a2,b2] are found
+ * as outputs of the Extended Euclidean Algorithm on inputs 'order' and 'lambda').
+ */
+ static const unsigned char secp256k1_scalar_consts_minus_b1[32] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,
+ 0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3
+ };
+ static const unsigned char secp256k1_scalar_consts_b2[32] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,
+ 0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15
+ };
+ static const unsigned char secp256k1_scalar_consts_g1[32] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x86,
+ 0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,
+ 0x90,0xe4,0x92,0x84,0xeb,0x15,0x3d,0xab
+ };
+ static const unsigned char secp256k1_scalar_consts_g2[32] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x43,
+ 0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54,
+ 0x7f,0xa9,0x0a,0xbf,0xe4,0xc4,0x22,0x12
+ };
+
+ secp256k1_scalar_set_b32(&ret->minus_lambda, secp256k1_scalar_consts_lambda, NULL);
+ secp256k1_scalar_negate(&ret->minus_lambda, &ret->minus_lambda);
+ secp256k1_scalar_set_b32(&ret->minus_b1, secp256k1_scalar_consts_minus_b1, NULL);
+ secp256k1_scalar_set_b32(&ret->minus_b2, secp256k1_scalar_consts_b2, NULL);
+ secp256k1_scalar_negate(&ret->minus_b2, &ret->minus_b2);
+ secp256k1_scalar_set_b32(&ret->g1, secp256k1_scalar_consts_g1, NULL);
+ secp256k1_scalar_set_b32(&ret->g2, secp256k1_scalar_consts_g2, NULL);
+#endif
+
+ /* Set the global pointer. */
+ secp256k1_scalar_consts = ret;
+}
+
+static void secp256k1_scalar_stop(void) {
+ if (secp256k1_scalar_consts == NULL)
+ return;
+
+ secp256k1_scalar_consts_t *c = (secp256k1_scalar_consts_t*)secp256k1_scalar_consts;
+ secp256k1_scalar_consts = NULL;
+ free(c);
+}
+
+#ifndef USE_NUM_NONE
static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a) {
unsigned char c[32];
secp256k1_scalar_get_b32(c, a);
secp256k1_num_set_bin(r, c, 32);
}
+static void secp256k1_scalar_order_get_num(secp256k1_num_t *r) {
+ *r = secp256k1_scalar_consts->order;
+}
+#endif
static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scalar_t *x) {
/* First compute x ^ (2^N - 1) for some values of N. */
secp256k1_scalar_mul(r, t, &x6); /* 111111 */
}
+static void secp256k1_scalar_inverse_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *x) {
+#if defined(USE_SCALAR_INV_BUILTIN)
+ secp256k1_scalar_inverse(r, x);
+#elif defined(USE_SCALAR_INV_NUM)
+ unsigned char b[32];
+ secp256k1_scalar_get_b32(b, x);
+ secp256k1_num_t n;
+ secp256k1_num_set_bin(&n, b, 32);
+ secp256k1_num_mod_inverse(&n, &n, &secp256k1_scalar_consts->order);
+ secp256k1_num_get_bin(b, 32, &n);
+ secp256k1_scalar_set_b32(r, b, NULL);
+#else
+#error "Please select scalar inverse implementation"
+#endif
+}
+
+#ifdef USE_ENDOMORPHISM
+static void secp256k1_scalar_split_lambda_var(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) {
+ VERIFY_CHECK(r1 != a);
+ VERIFY_CHECK(r2 != a);
+ secp256k1_scalar_t c1, c2;
+ secp256k1_scalar_mul_shift_var(&c1, a, &secp256k1_scalar_consts->g1, 272);
+ secp256k1_scalar_mul_shift_var(&c2, a, &secp256k1_scalar_consts->g2, 272);
+ secp256k1_scalar_mul(&c1, &c1, &secp256k1_scalar_consts->minus_b1);
+ secp256k1_scalar_mul(&c2, &c2, &secp256k1_scalar_consts->minus_b2);
+ secp256k1_scalar_add(r2, &c1, &c2);
+ secp256k1_scalar_mul(r1, r2, &secp256k1_scalar_consts->minus_lambda);
+ secp256k1_scalar_add(r1, r1, a);
+}
+#endif
+
#endif
#include "ecmult_gen_impl.h"
#include "ecdsa_impl.h"
#include "eckey_impl.h"
+#include "hash_impl.h"
void secp256k1_start(unsigned int flags) {
secp256k1_fe_start();
secp256k1_ge_start();
+ secp256k1_scalar_start();
+ secp256k1_ecdsa_start();
if (flags & SECP256K1_START_SIGN) {
secp256k1_ecmult_gen_start();
}
void secp256k1_stop(void) {
secp256k1_ecmult_stop();
secp256k1_ecmult_gen_stop();
+ secp256k1_ecdsa_stop();
+ secp256k1_scalar_stop();
secp256k1_ge_stop();
secp256k1_fe_stop();
}
-int secp256k1_ecdsa_verify(const unsigned char *msg, int msglen, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) {
+int secp256k1_ecdsa_verify(const unsigned char *msg32, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) {
DEBUG_CHECK(secp256k1_ecmult_consts != NULL);
- DEBUG_CHECK(msg != NULL);
- DEBUG_CHECK(msglen <= 32);
+ DEBUG_CHECK(msg32 != NULL);
DEBUG_CHECK(sig != NULL);
DEBUG_CHECK(pubkey != NULL);
int ret = -3;
- secp256k1_num_t m;
+ secp256k1_scalar_t m;
secp256k1_ecdsa_sig_t s;
secp256k1_ge_t q;
- secp256k1_num_set_bin(&m, msg, msglen);
+ secp256k1_scalar_set_b32(&m, msg32, NULL);
if (!secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen)) {
ret = -1;
return ret;
}
-int secp256k1_ecdsa_sign(const unsigned char *message, int messagelen, unsigned char *signature, int *signaturelen, const unsigned char *seckey, const unsigned char *nonce) {
+static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) {
+ (void)data;
+ secp256k1_rfc6979_hmac_sha256_t rng;
+ secp256k1_rfc6979_hmac_sha256_initialize(&rng, key32, 32, msg32, 32);
+ for (unsigned int i = 0; i <= counter; i++) {
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32);
+ }
+ secp256k1_rfc6979_hmac_sha256_finalize(&rng);
+ return 1;
+}
+
+const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979;
+const secp256k1_nonce_function_t secp256k1_nonce_function_default = nonce_function_rfc6979;
+
+int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) {
DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL);
- DEBUG_CHECK(message != NULL);
- DEBUG_CHECK(messagelen <= 32);
+ DEBUG_CHECK(msg32 != NULL);
DEBUG_CHECK(signature != NULL);
DEBUG_CHECK(signaturelen != NULL);
DEBUG_CHECK(seckey != NULL);
- DEBUG_CHECK(nonce != NULL);
+ if (noncefp == NULL) {
+ noncefp = secp256k1_nonce_function_default;
+ }
secp256k1_scalar_t sec, non, msg;
secp256k1_scalar_set_b32(&sec, seckey, NULL);
+ secp256k1_scalar_set_b32(&msg, msg32, NULL);
int overflow = 0;
- secp256k1_scalar_set_b32(&non, nonce, &overflow);
- {
- unsigned char c[32] = {0};
- memcpy(c + 32 - messagelen, message, messagelen);
- secp256k1_scalar_set_b32(&msg, c, NULL);
- memset(c, 0, 32);
- }
- int ret = !secp256k1_scalar_is_zero(&non) && !overflow;
+ int ret = 0;
+ unsigned int count = 0;
secp256k1_ecdsa_sig_t sig;
- if (ret) {
- ret = secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, NULL);
+ while (1) {
+ unsigned char nonce32[32];
+ ret = noncefp(nonce32, msg32, seckey, count, noncedata);
+ if (!ret) {
+ break;
+ }
+ secp256k1_scalar_set_b32(&non, nonce32, &overflow);
+ memset(nonce32, 0, 32);
+ if (!secp256k1_scalar_is_zero(&non) && !overflow) {
+ if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, NULL)) {
+ break;
+ }
+ }
+ count++;
}
if (ret) {
- secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig);
+ ret = secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig);
}
secp256k1_scalar_clear(&msg);
secp256k1_scalar_clear(&non);
return ret;
}
-int secp256k1_ecdsa_sign_compact(const unsigned char *message, int messagelen, unsigned char *sig64, const unsigned char *seckey, const unsigned char *nonce, int *recid) {
+int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata, int *recid) {
DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL);
- DEBUG_CHECK(message != NULL);
- DEBUG_CHECK(messagelen <= 32);
+ DEBUG_CHECK(msg32 != NULL);
DEBUG_CHECK(sig64 != NULL);
DEBUG_CHECK(seckey != NULL);
- DEBUG_CHECK(nonce != NULL);
+ if (noncefp == NULL) {
+ noncefp = secp256k1_nonce_function_default;
+ }
secp256k1_scalar_t sec, non, msg;
secp256k1_scalar_set_b32(&sec, seckey, NULL);
+ secp256k1_scalar_set_b32(&msg, msg32, NULL);
int overflow = 0;
- secp256k1_scalar_set_b32(&non, nonce, &overflow);
- {
- unsigned char c[32] = {0};
- memcpy(c + 32 - messagelen, message, messagelen);
- secp256k1_scalar_set_b32(&msg, c, NULL);
- memset(c, 0, 32);
- }
- int ret = !secp256k1_scalar_is_zero(&non) && !overflow;
+ int ret = 0;
+ unsigned int count = 0;
secp256k1_ecdsa_sig_t sig;
- if (ret) {
- ret = secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid);
+ while (1) {
+ unsigned char nonce32[32];
+ ret = noncefp(nonce32, msg32, seckey, count, noncedata);
+ if (!ret) {
+ break;
+ }
+ secp256k1_scalar_set_b32(&non, nonce32, &overflow);
+ memset(nonce32, 0, 32);
+ if (!secp256k1_scalar_is_zero(&non) && !overflow) {
+ if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid)) {
+ break;
+ }
+ }
+ count++;
}
if (ret) {
- secp256k1_num_get_bin(sig64, 32, &sig.r);
- secp256k1_num_get_bin(sig64 + 32, 32, &sig.s);
+ secp256k1_scalar_get_b32(sig64, &sig.r);
+ secp256k1_scalar_get_b32(sig64 + 32, &sig.s);
}
secp256k1_scalar_clear(&msg);
secp256k1_scalar_clear(&non);
return ret;
}
-int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) {
+int secp256k1_ecdsa_recover_compact(const unsigned char *msg32, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) {
DEBUG_CHECK(secp256k1_ecmult_consts != NULL);
- DEBUG_CHECK(msg != NULL);
- DEBUG_CHECK(msglen <= 32);
+ DEBUG_CHECK(msg32 != NULL);
DEBUG_CHECK(sig64 != NULL);
DEBUG_CHECK(pubkey != NULL);
DEBUG_CHECK(pubkeylen != NULL);
DEBUG_CHECK(recid >= 0 && recid <= 3);
int ret = 0;
- secp256k1_num_t m;
+ secp256k1_scalar_t m;
secp256k1_ecdsa_sig_t sig;
- secp256k1_num_set_bin(&sig.r, sig64, 32);
- secp256k1_num_set_bin(&sig.s, sig64 + 32, 32);
- secp256k1_num_set_bin(&m, msg, msglen);
+ int overflow = 0;
+ secp256k1_scalar_set_b32(&sig.r, sig64, &overflow);
+ if (overflow) {
+ return 0;
+ }
+ secp256k1_scalar_set_b32(&sig.s, sig64 + 32, &overflow);
+ if (overflow) {
+ return 0;
+ }
+ secp256k1_scalar_set_b32(&m, msg32, NULL);
secp256k1_ge_t q;
if (secp256k1_ecdsa_sig_recover(&sig, &q, &m, recid)) {
DEBUG_CHECK(pubkey != NULL);
DEBUG_CHECK(tweak != NULL);
- secp256k1_num_t term;
- secp256k1_num_set_bin(&term, tweak, 32);
+ secp256k1_scalar_t term;
+ int overflow = 0;
+ secp256k1_scalar_set_b32(&term, tweak, &overflow);
+ if (overflow) {
+ return 0;
+ }
secp256k1_ge_t p;
int ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen);
if (ret) {
DEBUG_CHECK(pubkey != NULL);
DEBUG_CHECK(tweak != NULL);
- secp256k1_num_t factor;
- secp256k1_num_set_bin(&factor, tweak, 32);
+ secp256k1_scalar_t factor;
+ int overflow = 0;
+ secp256k1_scalar_set_b32(&factor, tweak, &overflow);
+ if (overflow) {
+ return 0;
+ }
secp256k1_ge_t p;
int ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen);
if (ret) {
#include <stdio.h>
#include <stdlib.h>
+#include <time.h>
+
#include "secp256k1.c"
#include "testrand_impl.h"
static int count = 64;
-/***** NUM TESTS *****/
-
-void random_num_negate(secp256k1_num_t *num) {
- if (secp256k1_rand32() & 1)
- secp256k1_num_negate(num);
-}
-
void random_field_element_test(secp256k1_fe_t *fe) {
do {
unsigned char b32[32];
secp256k1_rand256_test(b32);
- secp256k1_num_t num;
- secp256k1_num_set_bin(&num, b32, 32);
- if (secp256k1_num_cmp(&num, &secp256k1_fe_consts->p) >= 0)
- continue;
- secp256k1_fe_set_b32(fe, b32);
- break;
+ if (secp256k1_fe_set_b32(fe, b32)) {
+ break;
+ }
} while(1);
}
void random_field_element_magnitude(secp256k1_fe_t *fe) {
+ int n = secp256k1_rand32() % 9;
secp256k1_fe_normalize(fe);
- int n = secp256k1_rand32() % 4;
- for (int i = 0; i < n; i++) {
- secp256k1_fe_negate(fe, fe, 1 + 2*i);
- secp256k1_fe_negate(fe, fe, 2 + 2*i);
+ if (n == 0) {
+ return;
}
+ secp256k1_fe_t zero;
+ secp256k1_fe_clear(&zero);
+ secp256k1_fe_negate(&zero, &zero, 0);
+ secp256k1_fe_mul_int(&zero, n - 1);
+ secp256k1_fe_add(fe, &zero);
+#ifdef VERIFY
+ CHECK(fe->magnitude == n);
+#endif
}
void random_group_element_test(secp256k1_ge_t *ge) {
secp256k1_fe_t fe;
do {
random_field_element_test(&fe);
- if (secp256k1_ge_set_xo(ge, &fe, secp256k1_rand32() & 1))
+ if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_rand32() & 1))
break;
} while(1);
}
gej->infinity = ge->infinity;
}
-void random_num_order_test(secp256k1_num_t *num) {
- do {
- unsigned char b32[32];
- secp256k1_rand256_test(b32);
- secp256k1_num_set_bin(num, b32, 32);
- if (secp256k1_num_is_zero(num))
- continue;
- if (secp256k1_num_cmp(num, &secp256k1_ge_consts->order) >= 0)
- continue;
- break;
- } while(1);
-}
-
void random_scalar_order_test(secp256k1_scalar_t *num) {
do {
unsigned char b32[32];
} while(1);
}
-void random_num_order(secp256k1_num_t *num) {
+void random_scalar_order(secp256k1_scalar_t *num) {
do {
unsigned char b32[32];
secp256k1_rand256(b32);
- secp256k1_num_set_bin(num, b32, 32);
- if (secp256k1_num_is_zero(num))
- continue;
- if (secp256k1_num_cmp(num, &secp256k1_ge_consts->order) >= 0)
+ int overflow = 0;
+ secp256k1_scalar_set_b32(num, b32, &overflow);
+ if (overflow || secp256k1_scalar_is_zero(num))
continue;
break;
} while(1);
}
-void test_num_copy_inc_cmp(void) {
- secp256k1_num_t n1,n2;
- random_num_order(&n1);
- secp256k1_num_copy(&n2, &n1);
- CHECK(secp256k1_num_eq(&n1, &n2));
- CHECK(secp256k1_num_eq(&n2, &n1));
- secp256k1_num_inc(&n2);
- CHECK(!secp256k1_num_eq(&n1, &n2));
- CHECK(!secp256k1_num_eq(&n2, &n1));
-}
-
+/***** HASH TESTS *****/
-void test_num_get_set_hex(void) {
- secp256k1_num_t n1,n2;
- random_num_order_test(&n1);
- char c[64];
- secp256k1_num_get_hex(c, 64, &n1);
- secp256k1_num_set_hex(&n2, c, 64);
- CHECK(secp256k1_num_eq(&n1, &n2));
- for (int i=0; i<64; i++) {
- /* check whether the lower 4 bits correspond to the last hex character */
- int low1 = secp256k1_num_shift(&n1, 4);
- int lowh = c[63];
- int low2 = ((lowh>>6)*9+(lowh-'0'))&15;
- CHECK(low1 == low2);
- /* shift bits off the hex representation, and compare */
- memmove(c+1, c, 63);
- c[0] = '0';
- secp256k1_num_set_hex(&n2, c, 64);
- CHECK(secp256k1_num_eq(&n1, &n2));
+void run_sha256_tests(void) {
+ static const char *inputs[8] = {
+ "", "abc", "message digest", "secure hash algorithm", "SHA256 is considered to be safe",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "For this sample, this 63-byte string will be used as input data",
+ "This is exactly 64 bytes long, not counting the terminating byte"
+ };
+ static const unsigned char outputs[8][32] = {
+ {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55},
+ {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad},
+ {0xf7, 0x84, 0x6f, 0x55, 0xcf, 0x23, 0xe1, 0x4e, 0xeb, 0xea, 0xb5, 0xb4, 0xe1, 0x55, 0x0c, 0xad, 0x5b, 0x50, 0x9e, 0x33, 0x48, 0xfb, 0xc4, 0xef, 0xa3, 0xa1, 0x41, 0x3d, 0x39, 0x3c, 0xb6, 0x50},
+ {0xf3, 0x0c, 0xeb, 0x2b, 0xb2, 0x82, 0x9e, 0x79, 0xe4, 0xca, 0x97, 0x53, 0xd3, 0x5a, 0x8e, 0xcc, 0x00, 0x26, 0x2d, 0x16, 0x4c, 0xc0, 0x77, 0x08, 0x02, 0x95, 0x38, 0x1c, 0xbd, 0x64, 0x3f, 0x0d},
+ {0x68, 0x19, 0xd9, 0x15, 0xc7, 0x3f, 0x4d, 0x1e, 0x77, 0xe4, 0xe1, 0xb5, 0x2d, 0x1f, 0xa0, 0xf9, 0xcf, 0x9b, 0xea, 0xea, 0xd3, 0x93, 0x9f, 0x15, 0x87, 0x4b, 0xd9, 0x88, 0xe2, 0xa2, 0x36, 0x30},
+ {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1},
+ {0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42},
+ {0xab, 0x64, 0xef, 0xf7, 0xe8, 0x8e, 0x2e, 0x46, 0x16, 0x5e, 0x29, 0xf2, 0xbc, 0xe4, 0x18, 0x26, 0xbd, 0x4c, 0x7b, 0x35, 0x52, 0xf6, 0xb3, 0x82, 0xa9, 0xe7, 0xd3, 0xaf, 0x47, 0xc2, 0x45, 0xf8}
+ };
+ for (int i = 0; i < 8; i++) {
+ secp256k1_sha256_t hasher;
+ secp256k1_sha256_initialize(&hasher);
+ secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i]));
+ unsigned char out[32];
+ secp256k1_sha256_finalize(&hasher, out);
+ CHECK(memcmp(out, outputs[i], 32) == 0);
+ if (strlen(inputs[i]) > 0) {
+ secp256k1_sha256_initialize(&hasher);
+ int split = secp256k1_rand32() % strlen(inputs[i]);
+ secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split);
+ secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split);
+ secp256k1_sha256_finalize(&hasher, out);
+ CHECK(memcmp(out, outputs[i], 32) == 0);
+ }
}
}
-void test_num_get_set_bin(void) {
- secp256k1_num_t n1,n2;
- random_num_order_test(&n1);
- unsigned char c[32];
- secp256k1_num_get_bin(c, 32, &n1);
- secp256k1_num_set_bin(&n2, c, 32);
- CHECK(secp256k1_num_eq(&n1, &n2));
- for (int i=0; i<32; i++) {
- /* check whether the lower 8 bits correspond to the last byte */
- int low1 = secp256k1_num_shift(&n1, 8);
- int low2 = c[31];
- CHECK(low1 == low2);
- /* shift bits off the byte representation, and compare */
- memmove(c+1, c, 31);
- c[0] = 0;
- secp256k1_num_set_bin(&n2, c, 32);
- CHECK(secp256k1_num_eq(&n1, &n2));
+void run_hmac_sha256_tests(void) {
+ static const char *keys[6] = {
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ "\x4a\x65\x66\x65",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ };
+ static const char *inputs[6] = {
+ "\x48\x69\x20\x54\x68\x65\x72\x65",
+ "\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+ "\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74",
+ "\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e"
+ };
+ static const unsigned char outputs[6][32] = {
+ {0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7},
+ {0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43},
+ {0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7, 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22, 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe},
+ {0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e, 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a, 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07, 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b},
+ {0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54},
+ {0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2}
+ };
+ for (int i = 0; i < 6; i++) {
+ secp256k1_hmac_sha256_t hasher;
+ secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i]));
+ secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i]));
+ unsigned char out[32];
+ secp256k1_hmac_sha256_finalize(&hasher, out);
+ CHECK(memcmp(out, outputs[i], 32) == 0);
+ if (strlen(inputs[i]) > 0) {
+ secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i]));
+ int split = secp256k1_rand32() % strlen(inputs[i]);
+ secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split);
+ secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split);
+ secp256k1_hmac_sha256_finalize(&hasher, out);
+ CHECK(memcmp(out, outputs[i], 32) == 0);
+ }
}
}
-void run_num_int(void) {
- secp256k1_num_t n1;
- for (int i=-255; i<256; i++) {
- unsigned char c1[3] = {};
- c1[2] = abs(i);
- unsigned char c2[3] = {0x11,0x22,0x33};
- secp256k1_num_set_int(&n1, i);
- secp256k1_num_get_bin(c2, 3, &n1);
- CHECK(memcmp(c1, c2, 3) == 0);
+void run_rfc6979_hmac_sha256_tests(void) {
+ static const unsigned char key1[32] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00};
+ static const unsigned char msg1[32] = {0x4b, 0xf5, 0x12, 0x2f, 0x34, 0x45, 0x54, 0xc5, 0x3b, 0xde, 0x2e, 0xbb, 0x8c, 0xd2, 0xb7, 0xe3, 0xd1, 0x60, 0x0a, 0xd6, 0x31, 0xc3, 0x85, 0xa5, 0xd7, 0xcc, 0xe2, 0x3c, 0x77, 0x85, 0x45, 0x9a};
+ static const unsigned char out1[3][32] = {
+ {0x4f, 0xe2, 0x95, 0x25, 0xb2, 0x08, 0x68, 0x09, 0x15, 0x9a, 0xcd, 0xf0, 0x50, 0x6e, 0xfb, 0x86, 0xb0, 0xec, 0x93, 0x2c, 0x7b, 0xa4, 0x42, 0x56, 0xab, 0x32, 0x1e, 0x42, 0x1e, 0x67, 0xe9, 0xfb},
+ {0x2b, 0xf0, 0xff, 0xf1, 0xd3, 0xc3, 0x78, 0xa2, 0x2d, 0xc5, 0xde, 0x1d, 0x85, 0x65, 0x22, 0x32, 0x5c, 0x65, 0xb5, 0x04, 0x49, 0x1a, 0x0c, 0xbd, 0x01, 0xcb, 0x8f, 0x3a, 0xa6, 0x7f, 0xfd, 0x4a},
+ {0xf5, 0x28, 0xb4, 0x10, 0xcb, 0x54, 0x1f, 0x77, 0x00, 0x0d, 0x7a, 0xfb, 0x6c, 0x5b, 0x53, 0xc5, 0xc4, 0x71, 0xea, 0xb4, 0x3e, 0x46, 0x6d, 0x9a, 0xc5, 0x19, 0x0c, 0x39, 0xc8, 0x2f, 0xd8, 0x2e}
+ };
+
+ static const unsigned char key2[32] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ static const unsigned char msg2[32] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55};
+ static const unsigned char out2[3][32] = {
+ {0x9c, 0x23, 0x6c, 0x16, 0x5b, 0x82, 0xae, 0x0c, 0xd5, 0x90, 0x65, 0x9e, 0x10, 0x0b, 0x6b, 0xab, 0x30, 0x36, 0xe7, 0xba, 0x8b, 0x06, 0x74, 0x9b, 0xaf, 0x69, 0x81, 0xe1, 0x6f, 0x1a, 0x2b, 0x95},
+ {0xdf, 0x47, 0x10, 0x61, 0x62, 0x5b, 0xc0, 0xea, 0x14, 0xb6, 0x82, 0xfe, 0xee, 0x2c, 0x9c, 0x02, 0xf2, 0x35, 0xda, 0x04, 0x20, 0x4c, 0x1d, 0x62, 0xa1, 0x53, 0x6c, 0x6e, 0x17, 0xae, 0xd7, 0xa9},
+ {0x75, 0x97, 0x88, 0x7c, 0xbd, 0x76, 0x32, 0x1f, 0x32, 0xe3, 0x04, 0x40, 0x67, 0x9a, 0x22, 0xcf, 0x7f, 0x8d, 0x9d, 0x2e, 0xac, 0x39, 0x0e, 0x58, 0x1f, 0xea, 0x09, 0x1c, 0xe2, 0x02, 0xba, 0x94}
+ };
+
+ secp256k1_rfc6979_hmac_sha256_t rng;
+ unsigned char out[32];
+
+ secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 32, msg1, 32);
+ for (int i = 0; i < 3; i++) {
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32);
+ CHECK(memcmp(out, out1[i], 32) == 0);
}
+ secp256k1_rfc6979_hmac_sha256_finalize(&rng);
+
+ secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 32, msg2, 32);
+ for (int i = 0; i < 3; i++) {
+ secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32);
+ CHECK(memcmp(out, out2[i], 32) == 0);
+ }
+ secp256k1_rfc6979_hmac_sha256_finalize(&rng);
+}
+
+/***** NUM TESTS *****/
+
+#ifndef USE_NUM_NONE
+void random_num_negate(secp256k1_num_t *num) {
+ if (secp256k1_rand32() & 1)
+ secp256k1_num_negate(num);
+}
+
+void random_num_order_test(secp256k1_num_t *num) {
+ secp256k1_scalar_t sc;
+ random_scalar_order_test(&sc);
+ secp256k1_scalar_get_num(num, &sc);
+}
+
+void random_num_order(secp256k1_num_t *num) {
+ secp256k1_scalar_t sc;
+ random_scalar_order(&sc);
+ secp256k1_scalar_get_num(num, &sc);
}
void test_num_negate(void) {
void run_num_smalltests(void) {
for (int i=0; i<100*count; i++) {
- test_num_copy_inc_cmp();
- test_num_get_set_hex();
- test_num_get_set_bin();
test_num_negate();
test_num_add_sub();
}
- run_num_int();
}
+#endif
/***** SCALAR TESTS *****/
-int secp256k1_scalar_eq(const secp256k1_scalar_t *s1, const secp256k1_scalar_t *s2) {
- secp256k1_scalar_t t;
- secp256k1_scalar_negate(&t, s2);
- secp256k1_scalar_add(&t, &t, s1);
- int ret = secp256k1_scalar_is_zero(&t);
- return ret;
-}
-
void scalar_test(void) {
unsigned char c[32];
/* Set 's' to a random scalar, with value 'snum'. */
- secp256k1_rand256_test(c);
secp256k1_scalar_t s;
- secp256k1_scalar_set_b32(&s, c, NULL);
- secp256k1_num_t snum;
- secp256k1_num_set_bin(&snum, c, 32);
- secp256k1_num_mod(&snum, &secp256k1_ge_consts->order);
+ random_scalar_order_test(&s);
/* Set 's1' to a random scalar, with value 's1num'. */
- secp256k1_rand256_test(c);
secp256k1_scalar_t s1;
- secp256k1_scalar_set_b32(&s1, c, NULL);
- secp256k1_num_t s1num;
- secp256k1_num_set_bin(&s1num, c, 32);
- secp256k1_num_mod(&s1num, &secp256k1_ge_consts->order);
+ random_scalar_order_test(&s1);
/* Set 's2' to a random scalar, with value 'snum2', and byte array representation 'c'. */
- secp256k1_rand256_test(c);
secp256k1_scalar_t s2;
- int overflow = 0;
- secp256k1_scalar_set_b32(&s2, c, &overflow);
- secp256k1_num_t s2num;
- secp256k1_num_set_bin(&s2num, c, 32);
- secp256k1_num_mod(&s2num, &secp256k1_ge_consts->order);
+ random_scalar_order_test(&s2);
+ secp256k1_scalar_get_b32(c, &s2);
+
+#ifndef USE_NUM_NONE
+ secp256k1_num_t snum, s1num, s2num;
+ secp256k1_scalar_get_num(&snum, &s);
+ secp256k1_scalar_get_num(&s1num, &s1);
+ secp256k1_scalar_get_num(&s2num, &s2);
+
+ secp256k1_num_t order;
+ secp256k1_scalar_order_get_num(&order);
+ secp256k1_num_t half_order = order;
+ secp256k1_num_shift(&half_order, 1);
+#endif
{
/* Test that fetching groups of 4 bits from a scalar and recursing n(i)=16*n(i-1)+p(i) reconstructs it. */
- secp256k1_num_t n, t, m;
- secp256k1_num_set_int(&n, 0);
- secp256k1_num_set_int(&m, 16);
+ secp256k1_scalar_t n;
+ secp256k1_scalar_set_int(&n, 0);
for (int i = 0; i < 256; i += 4) {
- secp256k1_num_set_int(&t, secp256k1_scalar_get_bits(&s, 256 - 4 - i, 4));
- secp256k1_num_mul(&n, &n, &m);
- secp256k1_num_add(&n, &n, &t);
+ secp256k1_scalar_t t;
+ secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits(&s, 256 - 4 - i, 4));
+ for (int j = 0; j < 4; j++) {
+ secp256k1_scalar_add(&n, &n, &n);
+ }
+ secp256k1_scalar_add(&n, &n, &t);
}
- CHECK(secp256k1_num_eq(&n, &snum));
+ CHECK(secp256k1_scalar_eq(&n, &s));
}
{
- /* Test that get_b32 returns the same as get_bin on the number. */
- unsigned char r1[32];
- secp256k1_scalar_get_b32(r1, &s2);
- unsigned char r2[32];
- secp256k1_num_get_bin(r2, 32, &s2num);
- CHECK(memcmp(r1, r2, 32) == 0);
- /* If no overflow occurred when assigning, it should also be equal to the original byte array. */
- CHECK((memcmp(r1, c, 32) == 0) == (overflow == 0));
+ /* Test that fetching groups of randomly-sized bits from a scalar and recursing n(i)=b*n(i-1)+p(i) reconstructs it. */
+ secp256k1_scalar_t n;
+ secp256k1_scalar_set_int(&n, 0);
+ int i = 0;
+ while (i < 256) {
+ int now = (secp256k1_rand32() % 15) + 1;
+ if (now + i > 256) {
+ now = 256 - i;
+ }
+ secp256k1_scalar_t t;
+ secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits_var(&s, 256 - now - i, now));
+ for (int j = 0; j < now; j++) {
+ secp256k1_scalar_add(&n, &n, &n);
+ }
+ secp256k1_scalar_add(&n, &n, &t);
+ i += now;
+ }
+ CHECK(secp256k1_scalar_eq(&n, &s));
}
+#ifndef USE_NUM_NONE
{
/* Test that adding the scalars together is equal to adding their numbers together modulo the order. */
secp256k1_num_t rnum;
secp256k1_num_add(&rnum, &snum, &s2num);
- secp256k1_num_mod(&rnum, &secp256k1_ge_consts->order);
+ secp256k1_num_mod(&rnum, &order);
secp256k1_scalar_t r;
secp256k1_scalar_add(&r, &s, &s2);
secp256k1_num_t r2num;
/* Test that multipying the scalars is equal to multiplying their numbers modulo the order. */
secp256k1_num_t rnum;
secp256k1_num_mul(&rnum, &snum, &s2num);
- secp256k1_num_mod(&rnum, &secp256k1_ge_consts->order);
+ secp256k1_num_mod(&rnum, &order);
secp256k1_scalar_t r;
secp256k1_scalar_mul(&r, &s, &s2);
secp256k1_num_t r2num;
/* Check that comparison with zero matches comparison with zero on the number. */
CHECK(secp256k1_num_is_zero(&snum) == secp256k1_scalar_is_zero(&s));
/* Check that comparison with the half order is equal to testing for high scalar. */
- CHECK(secp256k1_scalar_is_high(&s) == (secp256k1_num_cmp(&snum, &secp256k1_ge_consts->half_order) > 0));
+ CHECK(secp256k1_scalar_is_high(&s) == (secp256k1_num_cmp(&snum, &half_order) > 0));
secp256k1_scalar_t neg;
secp256k1_scalar_negate(&neg, &s);
secp256k1_num_t negnum;
- secp256k1_num_sub(&negnum, &secp256k1_ge_consts->order, &snum);
- secp256k1_num_mod(&negnum, &secp256k1_ge_consts->order);
+ secp256k1_num_sub(&negnum, &order, &snum);
+ secp256k1_num_mod(&negnum, &order);
/* Check that comparison with the half order is equal to testing for high scalar after negation. */
- CHECK(secp256k1_scalar_is_high(&neg) == (secp256k1_num_cmp(&negnum, &secp256k1_ge_consts->half_order) > 0));
+ CHECK(secp256k1_scalar_is_high(&neg) == (secp256k1_num_cmp(&negnum, &half_order) > 0));
/* Negating should change the high property, unless the value was already zero. */
CHECK((secp256k1_scalar_is_high(&s) == secp256k1_scalar_is_high(&neg)) == secp256k1_scalar_is_zero(&s));
secp256k1_num_t negnum2;
CHECK(secp256k1_scalar_is_zero(&neg));
}
+ {
+ /* Test secp256k1_scalar_mul_shift_var. */
+ secp256k1_scalar_t r;
+ unsigned int shift = 256 + (secp256k1_rand32() % 257);
+ secp256k1_scalar_mul_shift_var(&r, &s1, &s2, shift);
+ secp256k1_num_t rnum;
+ secp256k1_num_mul(&rnum, &s1num, &s2num);
+ secp256k1_num_shift(&rnum, shift - 1);
+ secp256k1_num_t one;
+ unsigned char cone[1] = {0x01};
+ secp256k1_num_set_bin(&one, cone, 1);
+ secp256k1_num_add(&rnum, &rnum, &one);
+ secp256k1_num_shift(&rnum, 1);
+ secp256k1_num_t rnum2;
+ secp256k1_scalar_get_num(&rnum2, &r);
+ CHECK(secp256k1_num_eq(&rnum, &rnum2));
+ }
+#endif
+
{
/* Test that scalar inverses are equal to the inverse of their number modulo the order. */
if (!secp256k1_scalar_is_zero(&s)) {
secp256k1_scalar_t inv;
secp256k1_scalar_inverse(&inv, &s);
+#ifndef USE_NUM_NONE
secp256k1_num_t invnum;
- secp256k1_num_mod_inverse(&invnum, &snum, &secp256k1_ge_consts->order);
+ secp256k1_num_mod_inverse(&invnum, &snum, &order);
secp256k1_num_t invnum2;
secp256k1_scalar_get_num(&invnum2, &inv);
CHECK(secp256k1_num_eq(&invnum, &invnum2));
+#endif
secp256k1_scalar_mul(&inv, &inv, &s);
/* Multiplying a scalar with its inverse must result in one. */
CHECK(secp256k1_scalar_is_one(&inv));
CHECK(secp256k1_scalar_eq(&r1, &r2));
}
+ {
+ /* Test add_bit. */
+ int bit = secp256k1_rand32() % 256;
+ secp256k1_scalar_t b;
+ secp256k1_scalar_set_int(&b, 1);
+ CHECK(secp256k1_scalar_is_one(&b));
+ for (int i = 0; i < bit; i++) {
+ secp256k1_scalar_add(&b, &b, &b);
+ }
+ secp256k1_scalar_t r1 = s1, r2 = s1;
+ if (!secp256k1_scalar_add(&r1, &r1, &b)) {
+ /* No overflow happened. */
+ secp256k1_scalar_add_bit(&r2, bit);
+ CHECK(secp256k1_scalar_eq(&r1, &r2));
+ }
+ }
+
{
/* Test commutativity of mul. */
secp256k1_scalar_t r1, r2;
secp256k1_scalar_mul(&r2, &s1, &s1);
CHECK(secp256k1_scalar_eq(&r1, &r2));
}
+
+ {
+ /* Test multiplicative identity. */
+ secp256k1_scalar_t r1, v1;
+ secp256k1_scalar_set_int(&v1,1);
+ secp256k1_scalar_mul(&r1, &s1, &v1);
+ CHECK(secp256k1_scalar_eq(&r1, &s1));
+ }
+
+ {
+ /* Test additive identity. */
+ secp256k1_scalar_t r1, v0;
+ secp256k1_scalar_set_int(&v0,0);
+ secp256k1_scalar_add(&r1, &s1, &v0);
+ CHECK(secp256k1_scalar_eq(&r1, &s1));
+ }
+
+ {
+ /* Test zero product property. */
+ secp256k1_scalar_t r1, v0;
+ secp256k1_scalar_set_int(&v0,0);
+ secp256k1_scalar_mul(&r1, &s1, &v0);
+ CHECK(secp256k1_scalar_eq(&r1, &v0));
+ }
+
}
void run_scalar_tests(void) {
for (int i = 0; i < 128 * count; i++) {
scalar_test();
}
+
+ {
+ /* (-1)+1 should be zero. */
+ secp256k1_scalar_t s, o;
+ secp256k1_scalar_set_int(&s, 1);
+ CHECK(secp256k1_scalar_is_one(&s));
+ secp256k1_scalar_negate(&o, &s);
+ secp256k1_scalar_add(&o, &o, &s);
+ CHECK(secp256k1_scalar_is_zero(&o));
+ secp256k1_scalar_negate(&o, &o);
+ CHECK(secp256k1_scalar_is_zero(&o));
+ }
+
+#ifndef USE_NUM_NONE
+ {
+ /* A scalar with value of the curve order should be 0. */
+ secp256k1_num_t order;
+ secp256k1_scalar_order_get_num(&order);
+ unsigned char bin[32];
+ secp256k1_num_get_bin(bin, 32, &order);
+ secp256k1_scalar_t zero;
+ int overflow = 0;
+ secp256k1_scalar_set_b32(&zero, bin, &overflow);
+ CHECK(overflow == 1);
+ CHECK(secp256k1_scalar_is_zero(&zero));
+ }
+#endif
}
/***** FIELD TESTS *****/
void random_fe(secp256k1_fe_t *x) {
unsigned char bin[32];
- secp256k1_rand256(bin);
- secp256k1_fe_set_b32(x, bin);
+ do {
+ secp256k1_rand256(bin);
+ if (secp256k1_fe_set_b32(x, bin)) {
+ return;
+ }
+ } while(1);
}
void random_fe_non_zero(secp256k1_fe_t *nz) {
void random_fe_non_square(secp256k1_fe_t *ns) {
random_fe_non_zero(ns);
secp256k1_fe_t r;
- if (secp256k1_fe_sqrt(&r, ns)) {
+ if (secp256k1_fe_sqrt_var(&r, ns)) {
secp256k1_fe_negate(ns, ns, 1);
}
}
int check_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
- secp256k1_fe_t an = *a; secp256k1_fe_normalize(&an);
- secp256k1_fe_t bn = *b; secp256k1_fe_normalize(&bn);
- return secp256k1_fe_equal(&an, &bn);
+ secp256k1_fe_t an = *a; secp256k1_fe_normalize_weak(&an);
+ secp256k1_fe_t bn = *b; secp256k1_fe_normalize_var(&bn);
+ return secp256k1_fe_equal_var(&an, &bn);
}
int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) {
return check_fe_equal(&x, &one);
}
+void run_field_misc(void) {
+ const unsigned char f32_5[32] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ };
+ secp256k1_fe_t x;
+ secp256k1_fe_t y;
+ secp256k1_fe_t z;
+ secp256k1_fe_t q;
+ secp256k1_fe_t fe5;
+ CHECK(secp256k1_fe_set_b32(&fe5, f32_5));
+ for (int i=0; i<5*count; i++) {
+ random_fe(&x);
+ random_fe_non_zero(&y);
+ /* Test the fe equality and comparison operations. */
+ CHECK(secp256k1_fe_cmp_var(&x, &x) == 0);
+ CHECK(secp256k1_fe_equal_var(&x, &x));
+ z = x;
+ secp256k1_fe_add(&z,&y);
+ secp256k1_fe_normalize(&z);
+ /* Test the conditional move. */
+ secp256k1_fe_cmov(&z, &x, 0);
+ CHECK(secp256k1_fe_equal_var(&x, &z) == 0);
+ CHECK(secp256k1_fe_cmp_var(&x, &z) != 0);
+ secp256k1_fe_cmov(&y, &x, 1);
+ CHECK(secp256k1_fe_equal_var(&x, &y));
+ /* Test that mul_int, mul, and add agree. */
+ secp256k1_fe_add(&y, &x);
+ secp256k1_fe_add(&y, &x);
+ z = x;
+ secp256k1_fe_mul_int(&z, 3);
+ CHECK(check_fe_equal(&y, &z));
+ secp256k1_fe_add(&y, &x);
+ secp256k1_fe_add(&z, &x);
+ CHECK(check_fe_equal(&z, &y));
+ z = x;
+ secp256k1_fe_mul_int(&z, 5);
+ secp256k1_fe_mul(&q, &x, &fe5);
+ CHECK(check_fe_equal(&z, &q));
+ secp256k1_fe_negate(&x, &x, 1);
+ secp256k1_fe_add(&z, &x);
+ secp256k1_fe_add(&q, &x);
+ CHECK(check_fe_equal(&y, &z));
+ CHECK(check_fe_equal(&q, &y));
+ }
+}
+
void run_field_inv(void) {
secp256k1_fe_t x, xi, xii;
for (int i=0; i<10*count; i++) {
}
}
-void run_field_inv_all(void) {
- secp256k1_fe_t x[16], xi[16], xii[16];
- /* Check it's safe to call for 0 elements */
- secp256k1_fe_inv_all(0, xi, x);
- for (int i=0; i<count; i++) {
- size_t len = (secp256k1_rand32() & 15) + 1;
- for (size_t j=0; j<len; j++)
- random_fe_non_zero(&x[j]);
- secp256k1_fe_inv_all(len, xi, x);
- for (size_t j=0; j<len; j++)
- CHECK(check_fe_inverse(&x[j], &xi[j]));
- secp256k1_fe_inv_all(len, xii, xi);
- for (size_t j=0; j<len; j++)
- CHECK(check_fe_equal(&x[j], &xii[j]));
- }
-}
-
void run_field_inv_all_var(void) {
secp256k1_fe_t x[16], xi[16], xii[16];
/* Check it's safe to call for 0 elements */
void test_sqrt(const secp256k1_fe_t *a, const secp256k1_fe_t *k) {
secp256k1_fe_t r1, r2;
- int v = secp256k1_fe_sqrt(&r1, a);
+ int v = secp256k1_fe_sqrt_var(&r1, a);
CHECK((v == 0) == (k == NULL));
if (k != NULL) {
/***** GROUP TESTS *****/
-int ge_equals_ge(const secp256k1_ge_t *a, const secp256k1_ge_t *b) {
- if (a->infinity && b->infinity)
- return 1;
- return check_fe_equal(&a->x, &b->x) && check_fe_equal(&a->y, &b->y);
+void ge_equals_ge(const secp256k1_ge_t *a, const secp256k1_ge_t *b) {
+ CHECK(a->infinity == b->infinity);
+ if (a->infinity)
+ return;
+ CHECK(secp256k1_fe_equal_var(&a->x, &b->x));
+ CHECK(secp256k1_fe_equal_var(&b->y, &b->y));
}
void ge_equals_gej(const secp256k1_ge_t *a, const secp256k1_gej_t *b) {
- secp256k1_ge_t bb;
- secp256k1_gej_t bj = *b;
- secp256k1_ge_set_gej_var(&bb, &bj);
- CHECK(ge_equals_ge(a, &bb));
-}
-
-void gej_equals_gej(const secp256k1_gej_t *a, const secp256k1_gej_t *b) {
- secp256k1_ge_t aa, bb;
- secp256k1_gej_t aj = *a, bj = *b;
- secp256k1_ge_set_gej_var(&aa, &aj);
- secp256k1_ge_set_gej_var(&bb, &bj);
- CHECK(ge_equals_ge(&aa, &bb));
+ CHECK(a->infinity == b->infinity);
+ if (a->infinity)
+ return;
+ /* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */
+ secp256k1_fe_t z2s;
+ secp256k1_fe_sqr(&z2s, &b->z);
+ secp256k1_fe_t u1, u2, s1, s2;
+ secp256k1_fe_mul(&u1, &a->x, &z2s);
+ u2 = b->x; secp256k1_fe_normalize_weak(&u2);
+ secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z);
+ s2 = b->y; secp256k1_fe_normalize_weak(&s2);
+ CHECK(secp256k1_fe_equal_var(&u1, &u2));
+ CHECK(secp256k1_fe_equal_var(&s1, &s2));
}
void test_ge(void) {
- secp256k1_ge_t a, b, i, n;
- random_group_element_test(&a);
- random_group_element_test(&b);
- n = a;
- secp256k1_fe_normalize(&a.y);
- secp256k1_fe_negate(&n.y, &a.y, 1);
- secp256k1_ge_set_infinity(&i);
- random_field_element_magnitude(&a.x);
- random_field_element_magnitude(&a.y);
- random_field_element_magnitude(&b.x);
- random_field_element_magnitude(&b.y);
- random_field_element_magnitude(&n.x);
- random_field_element_magnitude(&n.y);
-
- secp256k1_gej_t aj, bj, ij, nj;
- random_group_element_jacobian_test(&aj, &a);
- random_group_element_jacobian_test(&bj, &b);
- secp256k1_gej_set_infinity(&ij);
- random_group_element_jacobian_test(&nj, &n);
- random_field_element_magnitude(&aj.x);
- random_field_element_magnitude(&aj.y);
- random_field_element_magnitude(&aj.z);
- random_field_element_magnitude(&bj.x);
- random_field_element_magnitude(&bj.y);
- random_field_element_magnitude(&bj.z);
- random_field_element_magnitude(&nj.x);
- random_field_element_magnitude(&nj.y);
- random_field_element_magnitude(&nj.z);
-
- /* gej + gej adds */
- secp256k1_gej_t aaj; secp256k1_gej_add_var(&aaj, &aj, &aj);
- secp256k1_gej_t abj; secp256k1_gej_add_var(&abj, &aj, &bj);
- secp256k1_gej_t aij; secp256k1_gej_add_var(&aij, &aj, &ij);
- secp256k1_gej_t anj; secp256k1_gej_add_var(&anj, &aj, &nj);
- secp256k1_gej_t iaj; secp256k1_gej_add_var(&iaj, &ij, &aj);
- secp256k1_gej_t iij; secp256k1_gej_add_var(&iij, &ij, &ij);
-
- /* gej + ge adds */
- secp256k1_gej_t aa; secp256k1_gej_add_ge_var(&aa, &aj, &a);
- secp256k1_gej_t ab; secp256k1_gej_add_ge_var(&ab, &aj, &b);
- secp256k1_gej_t ai; secp256k1_gej_add_ge_var(&ai, &aj, &i);
- secp256k1_gej_t an; secp256k1_gej_add_ge_var(&an, &aj, &n);
- secp256k1_gej_t ia; secp256k1_gej_add_ge_var(&ia, &ij, &a);
- secp256k1_gej_t ii; secp256k1_gej_add_ge_var(&ii, &ij, &i);
-
- /* const gej + ge adds */
- secp256k1_gej_t aac; secp256k1_gej_add_ge(&aac, &aj, &a);
- secp256k1_gej_t abc; secp256k1_gej_add_ge(&abc, &aj, &b);
- secp256k1_gej_t anc; secp256k1_gej_add_ge(&anc, &aj, &n);
- secp256k1_gej_t iac; secp256k1_gej_add_ge(&iac, &ij, &a);
-
- CHECK(secp256k1_gej_is_infinity(&an));
- CHECK(secp256k1_gej_is_infinity(&anj));
- CHECK(secp256k1_gej_is_infinity(&anc));
- gej_equals_gej(&aa, &aaj);
- gej_equals_gej(&aa, &aac);
- gej_equals_gej(&ab, &abj);
- gej_equals_gej(&ab, &abc);
- gej_equals_gej(&an, &anj);
- gej_equals_gej(&an, &anc);
- gej_equals_gej(&ia, &iaj);
- gej_equals_gej(&ai, &aij);
- gej_equals_gej(&ii, &iij);
- ge_equals_gej(&a, &ai);
- ge_equals_gej(&a, &ai);
- ge_equals_gej(&a, &iaj);
- ge_equals_gej(&a, &iaj);
- ge_equals_gej(&a, &iac);
+ int runs = 4;
+ /* Points: (infinity, p1, p1, -p1, -p1, p2, p2, -p2, -p2, p3, p3, -p3, -p3, p4, p4, -p4, -p4).
+ * The second in each pair of identical points uses a random Z coordinate in the Jacobian form.
+ * All magnitudes are randomized.
+ * All 17*17 combinations of points are added to eachother, using all applicable methods.
+ */
+ secp256k1_ge_t *ge = malloc(sizeof(secp256k1_ge_t) * (1 + 4 * runs));
+ secp256k1_gej_t *gej = malloc(sizeof(secp256k1_gej_t) * (1 + 4 * runs));
+ secp256k1_gej_set_infinity(&gej[0]);
+ secp256k1_ge_clear(&ge[0]);
+ secp256k1_ge_set_gej_var(&ge[0], &gej[0]);
+ for (int i = 0; i < runs; i++) {
+ secp256k1_ge_t g;
+ random_group_element_test(&g);
+ ge[1 + 4 * i] = g;
+ ge[2 + 4 * i] = g;
+ secp256k1_ge_neg(&ge[3 + 4 * i], &g);
+ secp256k1_ge_neg(&ge[4 + 4 * i], &g);
+ secp256k1_gej_set_ge(&gej[1 + 4 * i], &ge[1 + 4 * i]);
+ random_group_element_jacobian_test(&gej[2 + 4 * i], &ge[2 + 4 * i]);
+ secp256k1_gej_set_ge(&gej[3 + 4 * i], &ge[3 + 4 * i]);
+ random_group_element_jacobian_test(&gej[4 + 4 * i], &ge[4 + 4 * i]);
+ for (int j = 0; j < 4; j++) {
+ random_field_element_magnitude(&ge[1 + j + 4 * i].x);
+ random_field_element_magnitude(&ge[1 + j + 4 * i].y);
+ random_field_element_magnitude(&gej[1 + j + 4 * i].x);
+ random_field_element_magnitude(&gej[1 + j + 4 * i].y);
+ random_field_element_magnitude(&gej[1 + j + 4 * i].z);
+ }
+ }
+
+ for (int i1 = 0; i1 < 1 + 4 * runs; i1++) {
+ for (int i2 = 0; i2 < 1 + 4 * runs; i2++) {
+ /* Compute reference result using gej + gej (var). */
+ secp256k1_gej_t refj, resj;
+ secp256k1_ge_t ref;
+ secp256k1_gej_add_var(&refj, &gej[i1], &gej[i2]);
+ secp256k1_ge_set_gej_var(&ref, &refj);
+
+ /* Test gej + ge (var). */
+ secp256k1_gej_add_ge_var(&resj, &gej[i1], &ge[i2]);
+ ge_equals_gej(&ref, &resj);
+
+ /* Test gej + ge (const). */
+ if (i2 != 0) {
+ /* secp256k1_gej_add_ge does not support its second argument being infinity. */
+ secp256k1_gej_add_ge(&resj, &gej[i1], &ge[i2]);
+ ge_equals_gej(&ref, &resj);
+ }
+
+ /* Test doubling (var). */
+ if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 == ((i2 + 3)%4)/2)) {
+ /* Normal doubling. */
+ secp256k1_gej_double_var(&resj, &gej[i1]);
+ ge_equals_gej(&ref, &resj);
+ secp256k1_gej_double_var(&resj, &gej[i2]);
+ ge_equals_gej(&ref, &resj);
+ }
+
+ /* Test adding opposites. */
+ if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 != ((i2 + 3)%4)/2)) {
+ CHECK(secp256k1_ge_is_infinity(&ref));
+ }
+
+ /* Test adding infinity. */
+ if (i1 == 0) {
+ CHECK(secp256k1_ge_is_infinity(&ge[i1]));
+ CHECK(secp256k1_gej_is_infinity(&gej[i1]));
+ ge_equals_gej(&ref, &gej[i2]);
+ }
+ if (i2 == 0) {
+ CHECK(secp256k1_ge_is_infinity(&ge[i2]));
+ CHECK(secp256k1_gej_is_infinity(&gej[i2]));
+ ge_equals_gej(&ref, &gej[i1]);
+ }
+ }
+ }
+
+ /* Test adding all points together in random order equals infinity. */
+ {
+ secp256k1_gej_t *gej_shuffled = malloc((4 * runs + 1) * sizeof(secp256k1_gej_t));
+ for (int i = 0; i < 4 * runs + 1; i++) {
+ gej_shuffled[i] = gej[i];
+ }
+ for (int i = 0; i < 4 * runs + 1; i++) {
+ int swap = i + secp256k1_rand32() % (4 * runs + 1 - i);
+ if (swap != i) {
+ secp256k1_gej_t t = gej_shuffled[i];
+ gej_shuffled[i] = gej_shuffled[swap];
+ gej_shuffled[swap] = t;
+ }
+ }
+ secp256k1_gej_t sum;
+ secp256k1_gej_set_infinity(&sum);
+ for (int i = 0; i < 4 * runs + 1; i++) {
+ secp256k1_gej_add_var(&sum, &sum, &gej_shuffled[i]);
+ }
+ CHECK(secp256k1_gej_is_infinity(&sum));
+ free(gej_shuffled);
+ }
+
+ /* Test batch gej -> ge conversion. */
+ {
+ secp256k1_ge_t *ge_set_all = malloc((4 * runs + 1) * sizeof(secp256k1_ge_t));
+ secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej);
+ for (int i = 0; i < 4 * runs + 1; i++) {
+ ge_equals_gej(&ge_set_all[i], &gej[i]);
+ }
+ free(ge_set_all);
+ }
+
+ free(ge);
+ free(gej);
}
void run_ge(void) {
- for (int i = 0; i < 2000*count; i++) {
+ for (int i = 0; i < count * 32; i++) {
test_ge();
}
}
void run_ecmult_chain(void) {
/* random starting point A (on the curve) */
- secp256k1_fe_t ax; secp256k1_fe_set_hex(&ax, "8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004", 64);
- secp256k1_fe_t ay; secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64);
+ secp256k1_fe_t ax; VERIFY_CHECK(secp256k1_fe_set_hex(&ax, "8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004", 64));
+ secp256k1_fe_t ay; VERIFY_CHECK(secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64));
secp256k1_gej_t a; secp256k1_gej_set_xy(&a, &ax, &ay);
/* two random initial factors xn and gn */
- secp256k1_num_t xn;
- secp256k1_num_set_hex(&xn, "84cc5452f7fde1edb4d38a8ce9b1b84ccef31f146e569be9705d357a42985407", 64);
- secp256k1_num_t gn;
- secp256k1_num_set_hex(&gn, "a1e58d22553dcd42b23980625d4c57a96e9323d42b3152e5ca2c3990edc7c9de", 64);
+ static const unsigned char xni[32] = {
+ 0x84, 0xcc, 0x54, 0x52, 0xf7, 0xfd, 0xe1, 0xed,
+ 0xb4, 0xd3, 0x8a, 0x8c, 0xe9, 0xb1, 0xb8, 0x4c,
+ 0xce, 0xf3, 0x1f, 0x14, 0x6e, 0x56, 0x9b, 0xe9,
+ 0x70, 0x5d, 0x35, 0x7a, 0x42, 0x98, 0x54, 0x07
+ };
+ secp256k1_scalar_t xn;
+ secp256k1_scalar_set_b32(&xn, xni, NULL);
+ static const unsigned char gni[32] = {
+ 0xa1, 0xe5, 0x8d, 0x22, 0x55, 0x3d, 0xcd, 0x42,
+ 0xb2, 0x39, 0x80, 0x62, 0x5d, 0x4c, 0x57, 0xa9,
+ 0x6e, 0x93, 0x23, 0xd4, 0x2b, 0x31, 0x52, 0xe5,
+ 0xca, 0x2c, 0x39, 0x90, 0xed, 0xc7, 0xc9, 0xde
+ };
+ secp256k1_scalar_t gn;
+ secp256k1_scalar_set_b32(&gn, gni, NULL);
/* two small multipliers to be applied to xn and gn in every iteration: */
- secp256k1_num_t xf;
- secp256k1_num_set_hex(&xf, "1337", 4);
- secp256k1_num_t gf;
- secp256k1_num_set_hex(&gf, "7113", 4);
+ static const unsigned char xfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x13,0x37};
+ secp256k1_scalar_t xf;
+ secp256k1_scalar_set_b32(&xf, xfi, NULL);
+ static const unsigned char gfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x71,0x13};
+ secp256k1_scalar_t gf;
+ secp256k1_scalar_set_b32(&gf, gfi, NULL);
/* accumulators with the resulting coefficients to A and G */
- secp256k1_num_t ae;
- secp256k1_num_set_int(&ae, 1);
- secp256k1_num_t ge;
- secp256k1_num_set_int(&ge, 0);
+ secp256k1_scalar_t ae;
+ secp256k1_scalar_set_int(&ae, 1);
+ secp256k1_scalar_t ge;
+ secp256k1_scalar_set_int(&ge, 0);
/* the point being computed */
secp256k1_gej_t x = a;
- const secp256k1_num_t *order = &secp256k1_ge_consts->order;
for (int i=0; i<200*count; i++) {
/* in each iteration, compute X = xn*X + gn*G; */
secp256k1_ecmult(&x, &x, &xn, &gn);
/* also compute ae and ge: the actual accumulated factors for A and G */
/* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */
- secp256k1_num_mod_mul(&ae, &ae, &xn, order);
- secp256k1_num_mod_mul(&ge, &ge, &xn, order);
- secp256k1_num_add(&ge, &ge, &gn);
- secp256k1_num_mod(&ge, order);
+ secp256k1_scalar_mul(&ae, &ae, &xn);
+ secp256k1_scalar_mul(&ge, &ge, &xn);
+ secp256k1_scalar_add(&ge, &ge, &gn);
/* modify xn and gn */
- secp256k1_num_mod_mul(&xn, &xn, &xf, order);
- secp256k1_num_mod_mul(&gn, &gn, &gf, order);
+ secp256k1_scalar_mul(&xn, &xn, &xf);
+ secp256k1_scalar_mul(&gn, &gn, &gf);
/* verify */
if (i == 19999) {
}
void test_point_times_order(const secp256k1_gej_t *point) {
- /* multiplying a point by the order results in O */
- const secp256k1_num_t *order = &secp256k1_ge_consts->order;
- secp256k1_num_t zero;
- secp256k1_num_set_int(&zero, 0);
- secp256k1_gej_t res;
- secp256k1_ecmult(&res, point, order, order); /* calc res = order * point + order * G; */
- CHECK(secp256k1_gej_is_infinity(&res));
+ unsigned char pub[65];
+ /* X * (point + G) + (order-X) * (pointer + G) = 0 */
+ secp256k1_scalar_t x;
+ random_scalar_order_test(&x);
+ secp256k1_scalar_t nx;
+ secp256k1_scalar_negate(&nx, &x);
+ secp256k1_gej_t res1, res2;
+ secp256k1_ecmult(&res1, point, &x, &x); /* calc res1 = x * point + x * G; */
+ secp256k1_ecmult(&res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */
+ secp256k1_gej_add_var(&res1, &res1, &res2);
+ CHECK(secp256k1_gej_is_infinity(&res1));
+ CHECK(secp256k1_gej_is_valid_var(&res1) == 0);
+ secp256k1_ge_t res3;
+ secp256k1_ge_set_gej(&res3, &res1);
+ CHECK(secp256k1_ge_is_infinity(&res3));
+ CHECK(secp256k1_ge_is_valid_var(&res3) == 0);
+ int psize = 65;
+ CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 0) == 0);
+ psize = 65;
+ CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 1) == 0);
}
void run_point_times_order(void) {
- secp256k1_fe_t x; secp256k1_fe_set_hex(&x, "02", 2);
+ secp256k1_fe_t x; VERIFY_CHECK(secp256k1_fe_set_hex(&x, "02", 2));
for (int i=0; i<500; i++) {
secp256k1_ge_t p;
- if (secp256k1_ge_set_xo(&p, &x, 1)) {
- CHECK(secp256k1_ge_is_valid(&p));
+ if (secp256k1_ge_set_xo_var(&p, &x, 1)) {
+ CHECK(secp256k1_ge_is_valid_var(&p));
secp256k1_gej_t j;
secp256k1_gej_set_ge(&j, &p);
- CHECK(secp256k1_gej_is_valid(&j));
+ CHECK(secp256k1_gej_is_valid_var(&j));
test_point_times_order(&j);
}
secp256k1_fe_sqr(&x, &x);
}
- char c[65]; int cl=65;
+ char c[65];
+ int cl = 1;
+ c[1] = 123;
+ secp256k1_fe_get_hex(c, &cl, &x); /* Check that fe_get_hex handles a too short input. */
+ CHECK(c[1] == 123);
+ cl = 65;
secp256k1_fe_get_hex(c, &cl, &x);
CHECK(strcmp(c, "7603CB59B0EF6C63FE6084792A0C378CDB3233A80F8A9A09A877DEAD31B38C45") == 0);
}
-void test_wnaf(const secp256k1_num_t *number, int w) {
- secp256k1_num_t x, two, t;
- secp256k1_num_set_int(&x, 0);
- secp256k1_num_set_int(&two, 2);
- int wnaf[257];
+void test_wnaf(const secp256k1_scalar_t *number, int w) {
+ secp256k1_scalar_t x, two, t;
+ secp256k1_scalar_set_int(&x, 0);
+ secp256k1_scalar_set_int(&two, 2);
+ int wnaf[256];
int bits = secp256k1_ecmult_wnaf(wnaf, number, w);
+ CHECK(bits <= 256);
int zeroes = -1;
for (int i=bits-1; i>=0; i--) {
- secp256k1_num_mul(&x, &x, &two);
+ secp256k1_scalar_mul(&x, &x, &two);
int v = wnaf[i];
if (v) {
CHECK(zeroes == -1 || zeroes >= w-1); /* check that distance between non-zero elements is at least w-1 */
CHECK(zeroes != -1); /* check that no unnecessary zero padding exists */
zeroes++;
}
- secp256k1_num_set_int(&t, v);
- secp256k1_num_add(&x, &x, &t);
+ if (v >= 0) {
+ secp256k1_scalar_set_int(&t, v);
+ } else {
+ secp256k1_scalar_set_int(&t, -v);
+ secp256k1_scalar_negate(&t, &t);
+ }
+ secp256k1_scalar_add(&x, &x, &t);
}
- CHECK(secp256k1_num_eq(&x, number)); /* check that wnaf represents number */
+ CHECK(secp256k1_scalar_eq(&x, number)); /* check that wnaf represents number */
}
void run_wnaf(void) {
- secp256k1_num_t n;
+ secp256k1_scalar_t n;
for (int i=0; i<count; i++) {
- random_num_order(&n);
+ random_scalar_order(&n);
if (i % 1)
- secp256k1_num_negate(&n);
+ secp256k1_scalar_negate(&n, &n);
test_wnaf(&n, 4+(i%10));
}
}
}
void test_ecdsa_sign_verify(void) {
+ int recid;
+ int getrec;
secp256k1_scalar_t msg, key;
random_scalar_order_test(&msg);
random_scalar_order_test(&key);
secp256k1_gej_t pubj; secp256k1_ecmult_gen(&pubj, &key);
secp256k1_ge_t pub; secp256k1_ge_set_gej(&pub, &pubj);
secp256k1_ecdsa_sig_t sig;
- random_sign(&sig, &key, &msg, NULL);
- secp256k1_num_t msg_num;
- secp256k1_scalar_get_num(&msg_num, &msg);
- CHECK(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg_num));
- secp256k1_num_inc(&msg_num);
- CHECK(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg_num));
+ getrec = secp256k1_rand32()&1;
+ random_sign(&sig, &key, &msg, getrec?&recid:NULL);
+ if (getrec) CHECK(recid >= 0 && recid < 4);
+ CHECK(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg));
+ secp256k1_scalar_t one;
+ secp256k1_scalar_set_int(&one, 1);
+ secp256k1_scalar_add(&msg, &msg, &one);
+ CHECK(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg));
}
void run_ecdsa_sign_verify(void) {
}
}
+/** Dummy nonce generation function that just uses a precomputed nonce, and fails if it is not accepted. Use only for testing. */
+static int precomputed_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) {
+ (void)msg32;
+ (void)key32;
+ memcpy(nonce32, data, 32);
+ return (counter == 0);
+}
+
+static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) {
+ /* Dummy nonce generator that has a fatal error on the first counter value. */
+ if (counter == 0) return 0;
+ return nonce_function_rfc6979(nonce32, msg32, key32, counter - 1, data);
+}
+
+static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) {
+ /* Dummy nonce generator that produces unacceptable nonces for the first several counter values. */
+ if (counter < 3) {
+ memset(nonce32, counter==0 ? 0 : 255, 32);
+ if (counter == 2) nonce32[31]--;
+ return 1;
+ }
+ if (counter < 5) {
+ static const unsigned char order[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+ 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
+ 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41
+ };
+ memcpy(nonce32, order, 32);
+ if (counter == 4) nonce32[31]++;
+ return 1;
+ }
+ /* Retry rate of 6979 is negligible esp. as we only call this in determinstic tests. */
+ /* If someone does fine a case where it retries for secp256k1, we'd like to know. */
+ if (counter > 5) return 0;
+ return nonce_function_rfc6979(nonce32, msg32, key32, counter - 5, data);
+}
+
void test_ecdsa_end_to_end(void) {
unsigned char privkey[32];
unsigned char message[32];
/* Generate a random key and message. */
{
- secp256k1_num_t msg, key;
- random_num_order_test(&msg);
- random_num_order_test(&key);
- secp256k1_num_get_bin(privkey, 32, &key);
- secp256k1_num_get_bin(message, 32, &msg);
+ secp256k1_scalar_t msg, key;
+ random_scalar_order_test(&msg);
+ random_scalar_order_test(&key);
+ secp256k1_scalar_get_b32(privkey, &key);
+ secp256k1_scalar_get_b32(message, &msg);
}
/* Construct and verify corresponding public key. */
CHECK(secp256k1_ec_seckey_verify(privkey) == 1);
unsigned char pubkey[65]; int pubkeylen = 65;
- CHECK(secp256k1_ec_pubkey_create(pubkey, &pubkeylen, privkey, secp256k1_rand32() % 2) == 1);
+ CHECK(secp256k1_ec_pubkey_create(pubkey, &pubkeylen, privkey, (secp256k1_rand32() & 3) != 0) == 1);
+ if (secp256k1_rand32() & 1) {
+ CHECK(secp256k1_ec_pubkey_decompress(pubkey, &pubkeylen));
+ }
CHECK(secp256k1_ec_pubkey_verify(pubkey, pubkeylen));
/* Verify private key import and export. */
/* Sign. */
unsigned char signature[72]; int signaturelen = 72;
- while(1) {
- unsigned char rnd[32];
- secp256k1_rand256_test(rnd);
- if (secp256k1_ecdsa_sign(message, 32, signature, &signaturelen, privkey, rnd) == 1) {
- break;
- }
- }
+ CHECK(secp256k1_ecdsa_sign(message, signature, &signaturelen, privkey, NULL, NULL) == 1);
/* Verify. */
- CHECK(secp256k1_ecdsa_verify(message, 32, signature, signaturelen, pubkey, pubkeylen) == 1);
+ CHECK(secp256k1_ecdsa_verify(message, signature, signaturelen, pubkey, pubkeylen) == 1);
/* Destroy signature and verify again. */
signature[signaturelen - 1 - secp256k1_rand32() % 20] += 1 + (secp256k1_rand32() % 255);
- CHECK(secp256k1_ecdsa_verify(message, 32, signature, signaturelen, pubkey, pubkeylen) != 1);
+ CHECK(secp256k1_ecdsa_verify(message, signature, signaturelen, pubkey, pubkeylen) != 1);
/* Compact sign. */
unsigned char csignature[64]; int recid = 0;
- while(1) {
- unsigned char rnd[32];
- secp256k1_rand256_test(rnd);
- if (secp256k1_ecdsa_sign_compact(message, 32, csignature, privkey, rnd, &recid) == 1) {
- break;
- }
- }
+ CHECK(secp256k1_ecdsa_sign_compact(message, csignature, privkey, NULL, NULL, &recid) == 1);
/* Recover. */
unsigned char recpubkey[65]; int recpubkeylen = 0;
- CHECK(secp256k1_ecdsa_recover_compact(message, 32, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1);
+ CHECK(secp256k1_ecdsa_recover_compact(message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1);
CHECK(recpubkeylen == pubkeylen);
CHECK(memcmp(pubkey, recpubkey, pubkeylen) == 0);
/* Destroy signature and verify again. */
csignature[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255);
- CHECK(secp256k1_ecdsa_recover_compact(message, 32, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) != 1 ||
+ CHECK(secp256k1_ecdsa_recover_compact(message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) != 1 ||
memcmp(pubkey, recpubkey, pubkeylen) != 0);
CHECK(recpubkeylen == pubkeylen);
}
+void test_random_pubkeys(void) {
+ unsigned char in[65];
+ /* Generate some randomly sized pubkeys. */
+ uint32_t r = secp256k1_rand32();
+ int len = (r & 3) == 0 ? 65 : 33;
+ r>>=2;
+ if ((r & 3) == 0) len = (r & 252) >> 3;
+ r>>=8;
+ if (len == 65) {
+ in[0] = (r & 2) ? 4 : (r & 1? 6 : 7);
+ } else {
+ in[0] = (r & 1) ? 2 : 3;
+ }
+ r>>=2;
+ if ((r & 7) == 0) in[0] = (r & 2040) >> 3;
+ r>>=11;
+ if (len > 1) secp256k1_rand256(&in[1]);
+ if (len > 33) secp256k1_rand256(&in[33]);
+ secp256k1_ge_t elem;
+ secp256k1_ge_t elem2;
+ if (secp256k1_eckey_pubkey_parse(&elem, in, len)) {
+ unsigned char out[65];
+ unsigned char firstb;
+ int res;
+ int size = len;
+ firstb = in[0];
+ /* If the pubkey can be parsed, it should round-trip... */
+ CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, len == 33));
+ CHECK(size == len);
+ CHECK(memcmp(&in[1], &out[1], len-1) == 0);
+ /* ... except for the type of hybrid inputs. */
+ if ((in[0] != 6) && (in[0] != 7)) CHECK(in[0] == out[0]);
+ size = 65;
+ CHECK(secp256k1_eckey_pubkey_serialize(&elem, in, &size, 0));
+ CHECK(size == 65);
+ CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size));
+ ge_equals_ge(&elem,&elem2);
+ /* Check that the X9.62 hybrid type is checked. */
+ in[0] = (r & 1) ? 6 : 7;
+ res = secp256k1_eckey_pubkey_parse(&elem2, in, size);
+ if (firstb == 2 || firstb == 3) {
+ if (in[0] == firstb + 4) CHECK(res);
+ else CHECK(!res);
+ }
+ if (res) {
+ ge_equals_ge(&elem,&elem2);
+ CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, 0));
+ CHECK(memcmp(&in[1], &out[1], 64) == 0);
+ }
+ }
+}
+
+void run_random_pubkeys(void) {
+ for (int i=0; i<10*count; i++) {
+ test_random_pubkeys();
+ }
+}
+
void run_ecdsa_end_to_end(void) {
for (int i=0; i<64*count; i++) {
test_ecdsa_end_to_end();
}
}
-void test_ecdsa_infinity(void) {
+/* Tests several edge cases. */
+void test_ecdsa_edge_cases(void) {
const unsigned char msg32[32] = {
'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
'a', ' ', 'v', 'e', 'r', 'y', ' ', 's',
's', 's', 'a', 'g', 'e', '.', '.', '.'
};
const unsigned char sig64[64] = {
- // Generated by signing the above message with nonce 'This is the nonce we will use...'
- // and secret key 0 (which is not valid), resulting in recid 0.
+ /* Generated by signing the above message with nonce 'This is the nonce we will use...'
+ * and secret key 0 (which is not valid), resulting in recid 0. */
0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8,
0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96,
0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63,
};
unsigned char pubkey[65];
int pubkeylen = 65;
- CHECK(!secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 0));
- CHECK(secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 1));
- CHECK(!secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 2));
- CHECK(!secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 3));
+ CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 0));
+ CHECK(secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 1));
+ CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 2));
+ CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 3));
+
+ /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */
+ const unsigned char sigb64[64] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ };
+ unsigned char pubkeyb[33];
+ int pubkeyblen = 33;
+ for (int recid = 0; recid < 4; recid++) {
+ /* (4,4) encoded in DER. */
+ unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04};
+ unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01};
+ unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00};
+ unsigned char sigbderalt1[39] = {
+ 0x30, 0x25, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04,
+ };
+ unsigned char sigbderalt2[39] = {
+ 0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ };
+ unsigned char sigbderalt3[40] = {
+ 0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04,
+ };
+ unsigned char sigbderalt4[40] = {
+ 0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ };
+ /* (order + r,4) encoded in DER. */
+ unsigned char sigbderlong[40] = {
+ 0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC,
+ 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E,
+ 0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04
+ };
+ CHECK(secp256k1_ecdsa_recover_compact(msg32, sigb64, pubkeyb, &pubkeyblen, 1, recid));
+ CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 1);
+ for (int recid2 = 0; recid2 < 4; recid2++) {
+ unsigned char pubkey2b[33];
+ int pubkey2blen = 33;
+ CHECK(secp256k1_ecdsa_recover_compact(msg32, sigb64, pubkey2b, &pubkey2blen, 1, recid2));
+ /* Verifying with (order + r,4) should always fail. */
+ CHECK(secp256k1_ecdsa_verify(msg32, sigbderlong, sizeof(sigbderlong), pubkey2b, pubkey2blen) != 1);
+ }
+ /* DER parsing tests. */
+ /* Zero length r/s. */
+ CHECK(secp256k1_ecdsa_verify(msg32, sigcder_zr, sizeof(sigcder_zr), pubkeyb, pubkeyblen) == -2);
+ CHECK(secp256k1_ecdsa_verify(msg32, sigcder_zs, sizeof(sigcder_zs), pubkeyb, pubkeyblen) == -2);
+ /* Leading zeros. */
+ CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt1, sizeof(sigbderalt1), pubkeyb, pubkeyblen) == 1);
+ CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt2, sizeof(sigbderalt2), pubkeyb, pubkeyblen) == 1);
+ CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == 1);
+ CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == 1);
+ sigbderalt3[4] = 1;
+ CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == -2);
+ sigbderalt4[7] = 1;
+ CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == -2);
+ /* Damage signature. */
+ sigbder[7]++;
+ CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0);
+ sigbder[7]--;
+ CHECK(secp256k1_ecdsa_verify(msg32, sigbder, 6, pubkeyb, pubkeyblen) == -2);
+ CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder)-1, pubkeyb, pubkeyblen) == -2);
+ for(int i = 0; i<8; i++) {
+ unsigned char orig = sigbder[i];
+ /*Try every single-byte change.*/
+ for (int c=0; c<256; c++) {
+ if (c == orig ) continue;
+ sigbder[i] = c;
+ CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) ==
+ (i==4 || i==7) ? 0 : -2 );
+ }
+ sigbder[i] = orig;
+ }
+ }
+
+ /* Test the case where ECDSA recomputes a point that is infinity. */
+ {
+ secp256k1_ecdsa_sig_t sig;
+ secp256k1_scalar_set_int(&sig.s, 1);
+ secp256k1_scalar_negate(&sig.s, &sig.s);
+ secp256k1_scalar_inverse(&sig.s, &sig.s);
+ secp256k1_scalar_set_int(&sig.r, 1);
+ secp256k1_gej_t keyj;
+ secp256k1_ecmult_gen(&keyj, &sig.r);
+ secp256k1_ge_t key;
+ secp256k1_ge_set_gej(&key, &keyj);
+ secp256k1_scalar_t msg = sig.s;
+ CHECK(secp256k1_ecdsa_sig_verify(&sig, &key, &msg) == 0);
+ }
+
+ /* Test r/s equal to zero */
+ {
+ /* (1,1) encoded in DER. */
+ unsigned char sigcder[8] = {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01};
+ unsigned char sigc64[64] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ };
+ unsigned char pubkeyc[65];
+ int pubkeyclen = 65;
+ CHECK(secp256k1_ecdsa_recover_compact(msg32, sigc64, pubkeyc, &pubkeyclen, 0, 0) == 1);
+ CHECK(secp256k1_ecdsa_verify(msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 1);
+ sigcder[4] = 0;
+ sigc64[31] = 0;
+ CHECK(secp256k1_ecdsa_recover_compact(msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0);
+ CHECK(secp256k1_ecdsa_verify(msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0);
+ sigcder[4] = 1;
+ sigcder[7] = 0;
+ sigc64[31] = 1;
+ sigc64[63] = 0;
+ CHECK(secp256k1_ecdsa_recover_compact(msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0);
+ CHECK(secp256k1_ecdsa_verify(msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0);
+ }
+
+ /*Signature where s would be zero.*/
+ {
+ const unsigned char nonce[32] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ };
+ static const unsigned char nonce2[32] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
+ 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
+ 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40
+ };
+ const unsigned char key[32] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ };
+ unsigned char msg[32] = {
+ 0x86, 0x41, 0x99, 0x81, 0x06, 0x23, 0x44, 0x53,
+ 0xaa, 0x5f, 0x9d, 0x6a, 0x31, 0x78, 0xf4, 0xf7,
+ 0xb8, 0x12, 0xe0, 0x0b, 0x81, 0x7a, 0x77, 0x62,
+ 0x65, 0xdf, 0xdd, 0x31, 0xb9, 0x3e, 0x29, 0xa9,
+ };
+ unsigned char sig[72];
+ int siglen = 72;
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 0);
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 0);
+ msg[31] = 0xaa;
+ siglen = 72;
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 1);
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 1);
+ siglen = 10;
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) != 1);
+ }
+
+ /* Nonce function corner cases. */
+ {
+ unsigned char key[32];
+ unsigned char msg[32];
+ unsigned char sig[72];
+ memset(key, 0, 32);
+ memset(msg, 0, 32);
+ key[31] = 1;
+ msg[31] = 1;
+ int siglen = 72;
+ int recid;
+ /* Nonce function failure results in signature failure. */
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_fail, NULL) == 0);
+ CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_fail, NULL, &recid) == 0);
+ /* The retry loop successfully makes its way to the first good value. */
+ unsigned char sig2[72];
+ int siglen2 = 72;
+ siglen = 72;
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_retry, NULL) == 1);
+ CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, nonce_function_rfc6979, NULL) == 1);
+ CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0));
+ int recid2;
+ CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_retry, NULL, &recid) == 1);
+ CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, nonce_function_rfc6979, NULL, &recid2) == 1);
+ CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0));
+ /* The default nonce function is determinstic. */
+ siglen = 72;
+ siglen2 = 72;
+ CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, NULL, NULL) == 1);
+ CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, NULL) == 1);
+ CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0));
+ CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, NULL, NULL, &recid) == 1);
+ CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, NULL, NULL, &recid2) == 1);
+ CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0));
+ /* The default nonce function changes output with different messages. */
+ secp256k1_ecdsa_sig_t s[512];
+ for(int i=0; i<256; i++) {
+ siglen2 = 72;
+ msg[0] = i;
+ CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, NULL) == 1);
+ CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2));
+ for (int j=0; j<i; j++) {
+ CHECK(!secp256k1_scalar_eq(&s[i].r, &s[j].r));
+ }
+ }
+ msg[0] = 0;
+ msg[31] = 2;
+ /* The default nonce function changes output with different keys. */
+ for(int i=256; i<512; i++) {
+ siglen2 = 72;
+ key[0] = i - 256;
+ CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, NULL) == 1);
+ CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2));
+ for (int j=0; j<i; j++) {
+ CHECK(!secp256k1_scalar_eq(&s[i].r, &s[j].r));
+ }
+ }
+ key[0] = 0;
+ }
+
+ /* Privkey export where pubkey is the point at infinity. */
+ {
+ unsigned char privkey[300];
+ unsigned char seckey[32] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
+ 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
+ 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,
+ };
+ int outlen = 300;
+ CHECK(!secp256k1_ec_privkey_export(seckey, privkey, &outlen, 0));
+ CHECK(!secp256k1_ec_privkey_export(seckey, privkey, &outlen, 1));
+ }
}
-void run_ecdsa_infinity(void) {
- test_ecdsa_infinity();
+void run_ecdsa_edge_cases(void) {
+ test_ecdsa_edge_cases();
}
#ifdef ENABLE_OPENSSL_TESTS
CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key));
secp256k1_ecdsa_sig_t sig;
CHECK(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize));
- secp256k1_num_t msg_num;
- secp256k1_scalar_get_num(&msg_num, &msg);
- CHECK(secp256k1_ecdsa_sig_verify(&sig, &q, &msg_num));
- secp256k1_num_inc(&sig.r);
- CHECK(!secp256k1_ecdsa_sig_verify(&sig, &q, &msg_num));
+ CHECK(secp256k1_ecdsa_sig_verify(&sig, &q, &msg));
+ secp256k1_scalar_t one;
+ secp256k1_scalar_set_int(&one, 1);
+ secp256k1_scalar_t msg2;
+ secp256k1_scalar_add(&msg2, &msg, &one);
+ CHECK(!secp256k1_ecdsa_sig_verify(&sig, &q, &msg2));
random_sign(&sig, &key, &msg, NULL);
int secp_sigsize = 80;
/* initialize */
secp256k1_start(SECP256K1_START_SIGN | SECP256K1_START_VERIFY);
+ /* initializing a second time shouldn't cause any harm or memory leaks. */
+ secp256k1_start(SECP256K1_START_SIGN | SECP256K1_START_VERIFY);
+
+ /* Likewise, re-running the internal init functions should be harmless. */
+ secp256k1_fe_start();
+ secp256k1_ge_start();
+ secp256k1_scalar_start();
+ secp256k1_ecdsa_start();
+
+ run_sha256_tests();
+ run_hmac_sha256_tests();
+ run_rfc6979_hmac_sha256_tests();
+
+#ifndef USE_NUM_NONE
/* num tests */
run_num_smalltests();
+#endif
/* scalar tests */
run_scalar_tests();
/* field tests */
run_field_inv();
run_field_inv_var();
- run_field_inv_all();
run_field_inv_all_var();
+ run_field_misc();
run_sqr();
run_sqrt();
run_ecmult_chain();
/* ecdsa tests */
+ run_random_pubkeys();
run_ecdsa_sign_verify();
run_ecdsa_end_to_end();
- run_ecdsa_infinity();
+ run_ecdsa_edge_cases();
#ifdef ENABLE_OPENSSL_TESTS
run_ecdsa_openssl();
#endif
/* shutdown */
secp256k1_stop();
+
+ /* shutting down twice shouldn't cause any double frees. */
+ secp256k1_stop();
+
+ /* Same for the internal shutdown functions. */
+ secp256k1_fe_stop();
+ secp256k1_ge_stop();
+ secp256k1_scalar_stop();
+ secp256k1_ecdsa_stop();
return 0;
}
#define VERIFY_CHECK(cond) do { (void)(cond); } while(0)
#endif
+static inline void *checked_malloc(size_t size) {
+ void *ret = malloc(size);
+ CHECK(ret != NULL);
+ return ret;
+}
+
+/* Macro for restrict, when available and not in a VERIFY build. */
+#if defined(SECP256K1_BUILD) && defined(VERIFY)
+# define SECP256K1_RESTRICT
+#else
+# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
+# if SECP256K1_GNUC_PREREQ(3,0)
+# define SECP256K1_RESTRICT __restrict__
+# elif (defined(_MSC_VER) && _MSC_VER >= 1400)
+# define SECP256K1_RESTRICT __restrict
+# else
+# define SECP256K1_RESTRICT
+# endif
+# else
+# define SECP256K1_RESTRICT restrict
+# endif
+#endif
+
#endif
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <utility>
#include <vector>
+#include "compat/endian.h"
+
class CScript;
static const unsigned int MAX_SIZE = 0x02000000;
return v.empty() ? NULL : (&v[0] + v.size());
}
+/*
+ * Lowest-level serialization and conversion.
+ * @note Sizes of these types are verified in the tests
+ */
+template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
+{
+ s.write((char*)&obj, 1);
+}
+template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
+{
+ obj = htole16(obj);
+ s.write((char*)&obj, 2);
+}
+template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
+{
+ obj = htole32(obj);
+ s.write((char*)&obj, 4);
+}
+template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
+{
+ obj = htole64(obj);
+ s.write((char*)&obj, 8);
+}
+template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
+{
+ uint8_t obj;
+ s.read((char*)&obj, 1);
+ return obj;
+}
+template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
+{
+ uint16_t obj;
+ s.read((char*)&obj, 2);
+ return le16toh(obj);
+}
+template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
+{
+ uint32_t obj;
+ s.read((char*)&obj, 4);
+ return le32toh(obj);
+}
+template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
+{
+ uint64_t obj;
+ s.read((char*)&obj, 8);
+ return le64toh(obj);
+}
+inline uint64_t ser_double_to_uint64(double x)
+{
+ union { double x; uint64_t y; } tmp;
+ tmp.x = x;
+ return tmp.y;
+}
+inline uint32_t ser_float_to_uint32(float x)
+{
+ union { float x; uint32_t y; } tmp;
+ tmp.x = x;
+ return tmp.y;
+}
+inline double ser_uint64_to_double(uint64_t y)
+{
+ union { double x; uint64_t y; } tmp;
+ tmp.y = y;
+ return tmp.x;
+}
+inline float ser_uint32_to_float(uint32_t y)
+{
+ union { float x; uint32_t y; } tmp;
+ tmp.y = y;
+ return tmp.x;
+}
+
+
/////////////////////////////////////////////////////////////////
//
// Templates for serializing to anything that looks like a stream,
SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \
}
-
-
/*
* Basic Types
*/
-#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj))
-#define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj))
-
-inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed long long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned long long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); }
-
-template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed long long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned long long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); }
-
-template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed long long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned long long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); }
+inline unsigned int GetSerializeSize(char a, int, int=0) { return 1; }
+inline unsigned int GetSerializeSize(int8_t a, int, int=0) { return 1; }
+inline unsigned int GetSerializeSize(uint8_t a, int, int=0) { return 1; }
+inline unsigned int GetSerializeSize(int16_t a, int, int=0) { return 2; }
+inline unsigned int GetSerializeSize(uint16_t a, int, int=0) { return 2; }
+inline unsigned int GetSerializeSize(int32_t a, int, int=0) { return 4; }
+inline unsigned int GetSerializeSize(uint32_t a, int, int=0) { return 4; }
+inline unsigned int GetSerializeSize(int64_t a, int, int=0) { return 8; }
+inline unsigned int GetSerializeSize(uint64_t a, int, int=0) { return 8; }
+inline unsigned int GetSerializeSize(float a, int, int=0) { return 4; }
+inline unsigned int GetSerializeSize(double a, int, int=0) { return 8; }
+
+template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { ser_writedata8(s, a); } // TODO Get rid of bare char
+template<typename Stream> inline void Serialize(Stream& s, int8_t a, int, int=0) { ser_writedata8(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint8_t a, int, int=0) { ser_writedata8(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, int16_t a, int, int=0) { ser_writedata16(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint16_t a, int, int=0) { ser_writedata16(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, int32_t a, int, int=0) { ser_writedata32(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint32_t a, int, int=0) { ser_writedata32(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, int64_t a, int, int=0) { ser_writedata64(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint64_t a, int, int=0) { ser_writedata64(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { ser_writedata32(s, ser_float_to_uint32(a)); }
+template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { ser_writedata64(s, ser_double_to_uint64(a)); }
+
+template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { a = ser_readdata8(s); } // TODO Get rid of bare char
+template<typename Stream> inline void Unserialize(Stream& s, int8_t& a, int, int=0) { a = ser_readdata8(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a, int, int=0) { a = ser_readdata8(s); }
+template<typename Stream> inline void Unserialize(Stream& s, int16_t& a, int, int=0) { a = ser_readdata16(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a, int, int=0) { a = ser_readdata16(s); }
+template<typename Stream> inline void Unserialize(Stream& s, int32_t& a, int, int=0) { a = ser_readdata32(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a, int, int=0) { a = ser_readdata32(s); }
+template<typename Stream> inline void Unserialize(Stream& s, int64_t& a, int, int=0) { a = ser_readdata64(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a, int, int=0) { a = ser_readdata64(s); }
+template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { a = ser_uint32_to_float(ser_readdata32(s)); }
+template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { a = ser_uint64_to_double(ser_readdata64(s)); }
inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); }
-template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); }
-template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; }
+template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; ser_writedata8(s, f); }
+template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f=ser_readdata8(s); a=f; }
{
if (nSize < 253)
{
- unsigned char chSize = nSize;
- WRITEDATA(os, chSize);
+ ser_writedata8(os, nSize);
}
else if (nSize <= std::numeric_limits<unsigned short>::max())
{
- unsigned char chSize = 253;
- unsigned short xSize = nSize;
- WRITEDATA(os, chSize);
- WRITEDATA(os, xSize);
+ ser_writedata8(os, 253);
+ ser_writedata16(os, nSize);
}
else if (nSize <= std::numeric_limits<unsigned int>::max())
{
- unsigned char chSize = 254;
- unsigned int xSize = nSize;
- WRITEDATA(os, chSize);
- WRITEDATA(os, xSize);
+ ser_writedata8(os, 254);
+ ser_writedata32(os, nSize);
}
else
{
- unsigned char chSize = 255;
- uint64_t xSize = nSize;
- WRITEDATA(os, chSize);
- WRITEDATA(os, xSize);
+ ser_writedata8(os, 255);
+ ser_writedata64(os, nSize);
}
return;
}
template<typename Stream>
uint64_t ReadCompactSize(Stream& is)
{
- unsigned char chSize;
- READDATA(is, chSize);
+ uint8_t chSize = ser_readdata8(is);
uint64_t nSizeRet = 0;
if (chSize < 253)
{
}
else if (chSize == 253)
{
- unsigned short xSize;
- READDATA(is, xSize);
- nSizeRet = xSize;
+ nSizeRet = ser_readdata16(is);
if (nSizeRet < 253)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
else if (chSize == 254)
{
- unsigned int xSize;
- READDATA(is, xSize);
- nSizeRet = xSize;
+ nSizeRet = ser_readdata32(is);
if (nSizeRet < 0x10000u)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
else
{
- uint64_t xSize;
- READDATA(is, xSize);
- nSizeRet = xSize;
+ nSizeRet = ser_readdata64(is);
if (nSizeRet < 0x100000000ULL)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
if (nSizeRet > (uint64_t)MAX_SIZE)
- throw std::ios_base::failure("ReadCompactSize() : size too large");
+ throw std::ios_base::failure("ReadCompactSize(): size too large");
return nSizeRet;
}
len++;
}
do {
- WRITEDATA(os, tmp[len]);
+ ser_writedata8(os, tmp[len]);
} while(len--);
}
{
I n = 0;
while(true) {
- unsigned char chData;
- READDATA(is, chData);
+ unsigned char chData = ser_readdata8(is);
n = (n << 7) | (chData & 0x7F);
if (chData & 0x80)
n++;
// 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-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_STREAMS_H
#include <map>
#include <set>
#include <stdint.h>
+#include <stdio.h>
#include <string>
#include <string.h>
#include <utility>
{
if (nReadPosNext > vch.size())
{
- throw std::ios_base::failure("CDataStream::read() : end of data");
+ throw std::ios_base::failure("CDataStream::read(): end of data");
}
memcpy(pch, &vch[nReadPos], nSize);
nReadPos = 0;
if (nReadPosNext >= vch.size())
{
if (nReadPosNext > vch.size())
- throw std::ios_base::failure("CDataStream::ignore() : end of data");
+ throw std::ios_base::failure("CDataStream::ignore(): end of data");
nReadPos = 0;
vch.clear();
return (*this);
CAutoFile& read(char* pch, size_t nSize)
{
if (!file)
- throw std::ios_base::failure("CAutoFile::read : file handle is NULL");
+ throw std::ios_base::failure("CAutoFile::read: file handle is NULL");
if (fread(pch, 1, nSize, file) != nSize)
- throw std::ios_base::failure(feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed");
+ throw std::ios_base::failure(feof(file) ? "CAutoFile::read: end of file" : "CAutoFile::read: fread failed");
return (*this);
}
CAutoFile& write(const char* pch, size_t nSize)
{
if (!file)
- throw std::ios_base::failure("CAutoFile::write : file handle is NULL");
+ throw std::ios_base::failure("CAutoFile::write: file handle is NULL");
if (fwrite(pch, 1, nSize, file) != nSize)
- throw std::ios_base::failure("CAutoFile::write : write failed");
+ throw std::ios_base::failure("CAutoFile::write: write failed");
return (*this);
}
{
// Serialize to this stream
if (!file)
- throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL");
+ throw std::ios_base::failure("CAutoFile::operator<<: file handle is NULL");
::Serialize(*this, obj, nType, nVersion);
return (*this);
}
{
// Unserialize from this stream
if (!file)
- throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL");
+ throw std::ios_base::failure("CAutoFile::operator>>: file handle is NULL");
::Unserialize(*this, obj, nType, nVersion);
return (*this);
}
return false;
size_t read = fread((void*)&vchBuf[pos], 1, readNow, src);
if (read == 0) {
- throw std::ios_base::failure(feof(src) ? "CBufferedFile::Fill : end of file" : "CBufferedFile::Fill : fread failed");
+ throw std::ios_base::failure(feof(src) ? "CBufferedFile::Fill: end of file" : "CBufferedFile::Fill: fread failed");
} else {
nSrcPos += read;
return true;
--- /dev/null
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "cleanse.h"
+
+#include <openssl/crypto.h>
+
+void memory_cleanse(void *ptr, size_t len)
+{
+ OPENSSL_cleanse(ptr, len);
+}
--- /dev/null
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SUPPORT_CLEANSE_H
+#define BITCOIN_SUPPORT_CLEANSE_H
+
+#include <stdlib.h>
+
+void memory_cleanse(void *ptr, size_t len);
+
+#endif // BITCOIN_SUPPORT_CLEANSE_H
-// Copyright (c) 2011-2012 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2011-2012 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "sync.h"
// 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-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SYNC_H
Enter(pszName, pszFile, nLine);
}
+ CMutexLock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false)
+ {
+ if (!pmutexIn) return;
+
+ lock = boost::unique_lock<Mutex>(*pmutexIn, boost::defer_lock);
+ if (fTry)
+ TryEnter(pszName, pszFile, nLine);
+ else
+ Enter(pszName, pszFile, nLine);
+ }
+
~CMutexLock()
{
if (lock.owns_lock())
// Copyright (c) 2011-2013 The Bitcoin Core 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"
#include "uint256.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
using namespace std;
-BOOST_AUTO_TEST_SUITE(Checkpoints_tests)
+BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(sanity)
{
- uint256 p11111 = uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
- uint256 p134444 = uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe");
+ uint256 p11111 = uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d");
+ uint256 p134444 = uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe");
BOOST_CHECK(Checkpoints::CheckBlock(11111, p11111));
BOOST_CHECK(Checkpoints::CheckBlock(134444, p134444));
// Copyright (c) 2011-2014 The Bitcoin Core 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 "serialize.h"
#include "util.h"
+#include "test/test_bitcoin.h"
+
#include <stdint.h>
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
return CService(CNetAddr(s), Params().GetDefaultPort());
}
-BOOST_AUTO_TEST_SUITE(DoS_tests)
+BOOST_FIXTURE_TEST_SUITE(DoS_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(DoS_banning)
{
// Copyright (c) 2012-2014 The Bitcoin Core 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 "wallet.h"
#include "walletdb.h"
+#include "test/test_bitcoin.h"
+
#include <stdint.h>
#include <boost/foreach.hpp>
extern CWallet* pwalletMain;
-BOOST_AUTO_TEST_SUITE(accounting_tests)
+BOOST_FIXTURE_TEST_SUITE(accounting_tests, TestingSetup)
static void
GetResults(CWalletDB& walletdb, std::map<CAmount, CAccountingEntry>& results)
walletdb.WriteAccountingEntry(ae);
wtx.mapValue["comment"] = "z";
- pwalletMain->AddToWallet(wtx);
+ pwalletMain->AddToWallet(wtx, false, &walletdb);
vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]);
vpwtx[0]->nTimeReceived = (unsigned int)1333333335;
vpwtx[0]->nOrderPos = -1;
--tx.nLockTime; // Just to change the hash :)
*static_cast<CTransaction*>(&wtx) = CTransaction(tx);
}
- pwalletMain->AddToWallet(wtx);
+ pwalletMain->AddToWallet(wtx, false, &walletdb);
vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]);
vpwtx[1]->nTimeReceived = (unsigned int)1333333336;
--tx.nLockTime; // Just to change the hash :)
*static_cast<CTransaction*>(&wtx) = CTransaction(tx);
}
- pwalletMain->AddToWallet(wtx);
+ pwalletMain->AddToWallet(wtx, false, &walletdb);
vpwtx.push_back(&pwalletMain->mapWallet[wtx.GetHash()]);
vpwtx[2]->nTimeReceived = (unsigned int)1333333329;
vpwtx[2]->nOrderPos = -1;
// Copyright (c) 2013 The Bitcoin Core 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 "util.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
+
#include <fstream>
#include <boost/filesystem/operations.hpp>
}
#endif
-struct ReadAlerts
+struct ReadAlerts : public TestingSetup
{
ReadAlerts()
{
alerts.push_back(alert);
}
}
- catch (std::exception) { }
+ catch (const std::exception&) { }
}
~ReadAlerts() { }
// Copyright (c) 2012-2013 The Bitcoin Core 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 "util.h"
#include "allocators.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(allocator_tests)
+BOOST_FIXTURE_TEST_SUITE(allocator_tests, BasicTestingSetup)
// Dummy memory page locker for platform independent tests
static const void *last_lock_addr, *last_unlock_addr;
--- /dev/null
+// Copyright (c) 2011-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <boost/test/unit_test.hpp>
+#include <stdint.h>
+#include <sstream>
+#include <iomanip>
+#include <limits>
+#include <cmath>
+#include "uint256.h"
+#include "arith_uint256.h"
+#include <string>
+#include "version.h"
+#include "test/test_bitcoin.h"
+
+BOOST_FIXTURE_TEST_SUITE(arith_uint256_tests, BasicTestingSetup)
+
+/// Convert vector to arith_uint256, via uint256 blob
+inline arith_uint256 arith_uint256V(const std::vector<unsigned char>& vch)
+{
+ return UintToArith256(uint256(vch));
+}
+
+const unsigned char R1Array[] =
+ "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2"
+ "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d";
+const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c";
+const double R1Ldouble = 0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256
+const arith_uint256 R1L = arith_uint256V(std::vector<unsigned char>(R1Array,R1Array+32));
+const uint64_t R1LLow64 = 0x121156cfdb4a529cULL;
+
+const unsigned char R2Array[] =
+ "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf"
+ "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7";
+const arith_uint256 R2L = arith_uint256V(std::vector<unsigned char>(R2Array,R2Array+32));
+
+const char R1LplusR2L[] = "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C";
+
+const unsigned char ZeroArray[] =
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+const arith_uint256 ZeroL = arith_uint256V(std::vector<unsigned char>(ZeroArray,ZeroArray+32));
+
+const unsigned char OneArray[] =
+ "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+const arith_uint256 OneL = arith_uint256V(std::vector<unsigned char>(OneArray,OneArray+32));
+
+const unsigned char MaxArray[] =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
+const arith_uint256 MaxL = arith_uint256V(std::vector<unsigned char>(MaxArray,MaxArray+32));
+
+const arith_uint256 HalfL = (OneL << 255);
+std::string ArrayToString(const unsigned char A[], unsigned int width)
+{
+ std::stringstream Stream;
+ Stream << std::hex;
+ for (unsigned int i = 0; i < width; ++i)
+ {
+ Stream<<std::setw(2)<<std::setfill('0')<<(unsigned int)A[width-i-1];
+ }
+ return Stream.str();
+}
+
+BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
+{
+ BOOST_CHECK(1 == 0+1);
+ // constructor arith_uint256(vector<char>):
+ BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array,32));
+ BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array,32));
+ BOOST_CHECK(ZeroL.ToString() == ArrayToString(ZeroArray,32));
+ BOOST_CHECK(OneL.ToString() == ArrayToString(OneArray,32));
+ BOOST_CHECK(MaxL.ToString() == ArrayToString(MaxArray,32));
+ BOOST_CHECK(OneL.ToString() != ArrayToString(ZeroArray,32));
+
+ // == and !=
+ BOOST_CHECK(R1L != R2L);
+ BOOST_CHECK(ZeroL != OneL);
+ BOOST_CHECK(OneL != ZeroL);
+ BOOST_CHECK(MaxL != ZeroL);
+ BOOST_CHECK(~MaxL == ZeroL);
+ BOOST_CHECK( ((R1L ^ R2L) ^ R1L) == R2L);
+
+ uint64_t Tmp64 = 0xc4dab720d9c7acaaULL;
+ for (unsigned int i = 0; i < 256; ++i)
+ {
+ BOOST_CHECK(ZeroL != (OneL << i));
+ BOOST_CHECK((OneL << i) != ZeroL);
+ BOOST_CHECK(R1L != (R1L ^ (OneL << i)));
+ BOOST_CHECK(((arith_uint256(Tmp64) ^ (OneL << i) ) != Tmp64 ));
+ }
+ BOOST_CHECK(ZeroL == (OneL << 256));
+
+ // String Constructor and Copy Constructor
+ BOOST_CHECK(arith_uint256("0x"+R1L.ToString()) == R1L);
+ BOOST_CHECK(arith_uint256("0x"+R2L.ToString()) == R2L);
+ BOOST_CHECK(arith_uint256("0x"+ZeroL.ToString()) == ZeroL);
+ BOOST_CHECK(arith_uint256("0x"+OneL.ToString()) == OneL);
+ BOOST_CHECK(arith_uint256("0x"+MaxL.ToString()) == MaxL);
+ BOOST_CHECK(arith_uint256(R1L.ToString()) == R1L);
+ BOOST_CHECK(arith_uint256(" 0x"+R1L.ToString()+" ") == R1L);
+ BOOST_CHECK(arith_uint256("") == ZeroL);
+ BOOST_CHECK(R1L == arith_uint256(R1ArrayHex));
+ BOOST_CHECK(arith_uint256(R1L) == R1L);
+ BOOST_CHECK((arith_uint256(R1L^R2L)^R2L) == R1L);
+ BOOST_CHECK(arith_uint256(ZeroL) == ZeroL);
+ BOOST_CHECK(arith_uint256(OneL) == OneL);
+
+ // uint64_t constructor
+ BOOST_CHECK( (R1L & arith_uint256("0xffffffffffffffff")) == arith_uint256(R1LLow64));
+ BOOST_CHECK(ZeroL == arith_uint256(0));
+ BOOST_CHECK(OneL == arith_uint256(1));
+ BOOST_CHECK(arith_uint256("0xffffffffffffffff") = arith_uint256(0xffffffffffffffffULL));
+
+ // Assignment (from base_uint)
+ arith_uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL);
+ tmpL = ~OneL; BOOST_CHECK(tmpL == ~OneL);
+ tmpL = ~R1L; BOOST_CHECK(tmpL == ~R1L);
+ tmpL = ~R2L; BOOST_CHECK(tmpL == ~R2L);
+ tmpL = ~MaxL; BOOST_CHECK(tmpL == ~MaxL);
+}
+
+void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift)
+{
+ for (unsigned int T=0; T < arrayLength; ++T)
+ {
+ unsigned int F = (T+bitsToShift/8);
+ if (F < arrayLength)
+ to[T] = from[F] >> (bitsToShift%8);
+ else
+ to[T] = 0;
+ if (F + 1 < arrayLength)
+ to[T] |= from[(F+1)] << (8-bitsToShift%8);
+ }
+}
+
+void shiftArrayLeft(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift)
+{
+ for (unsigned int T=0; T < arrayLength; ++T)
+ {
+ if (T >= bitsToShift/8)
+ {
+ unsigned int F = T-bitsToShift/8;
+ to[T] = from[F] << (bitsToShift%8);
+ if (T >= bitsToShift/8+1)
+ to[T] |= from[F-1] >> (8-bitsToShift%8);
+ }
+ else {
+ to[T] = 0;
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>="
+ unsigned char TmpArray[32];
+ arith_uint256 TmpL;
+ for (unsigned int i = 0; i < 256; ++i)
+ {
+ shiftArrayLeft(TmpArray, OneArray, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (OneL << i));
+ TmpL = OneL; TmpL <<= i;
+ BOOST_CHECK(TmpL == (OneL << i));
+ BOOST_CHECK((HalfL >> (255-i)) == (OneL << i));
+ TmpL = HalfL; TmpL >>= (255-i);
+ BOOST_CHECK(TmpL == (OneL << i));
+
+ shiftArrayLeft(TmpArray, R1Array, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L << i));
+ TmpL = R1L; TmpL <<= i;
+ BOOST_CHECK(TmpL == (R1L << i));
+
+ shiftArrayRight(TmpArray, R1Array, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L >> i));
+ TmpL = R1L; TmpL >>= i;
+ BOOST_CHECK(TmpL == (R1L >> i));
+
+ shiftArrayLeft(TmpArray, MaxArray, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL << i));
+ TmpL = MaxL; TmpL <<= i;
+ BOOST_CHECK(TmpL == (MaxL << i));
+
+ shiftArrayRight(TmpArray, MaxArray, 32, i);
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL >> i));
+ TmpL = MaxL; TmpL >>= i;
+ BOOST_CHECK(TmpL == (MaxL >> i));
+ }
+ arith_uint256 c1L = arith_uint256(0x0123456789abcdefULL);
+ arith_uint256 c2L = c1L << 128;
+ for (unsigned int i = 0; i < 128; ++i) {
+ BOOST_CHECK((c1L << i) == (c2L >> (128-i)));
+ }
+ for (unsigned int i = 128; i < 256; ++i) {
+ BOOST_CHECK((c1L << i) == (c2L << (i-128)));
+ }
+}
+
+BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ -
+{
+ BOOST_CHECK(!ZeroL);
+ BOOST_CHECK(!(!OneL));
+ for (unsigned int i = 0; i < 256; ++i)
+ BOOST_CHECK(!(!(OneL<<i)));
+ BOOST_CHECK(!(!R1L));
+ BOOST_CHECK(!(!MaxL));
+
+ BOOST_CHECK(~ZeroL == MaxL);
+
+ unsigned char TmpArray[32];
+ for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = ~R1Array[i]; }
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (~R1L));
+
+ BOOST_CHECK(-ZeroL == ZeroL);
+ BOOST_CHECK(-R1L == (~R1L)+1);
+ for (unsigned int i = 0; i < 256; ++i)
+ BOOST_CHECK(-(OneL<<i) == (MaxL << i));
+}
+
+
+// Check if doing _A_ _OP_ _B_ results in the same as applying _OP_ onto each
+// element of Aarray and Barray, and then converting the result into a arith_uint256.
+#define CHECKBITWISEOPERATOR(_A_,_B_,_OP_) \
+ for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \
+ BOOST_CHECK(arith_uint256V(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L));
+
+#define CHECKASSIGNMENTOPERATOR(_A_,_B_,_OP_) \
+ TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L));
+
+BOOST_AUTO_TEST_CASE( bitwiseOperators )
+{
+ unsigned char TmpArray[32];
+
+ CHECKBITWISEOPERATOR(R1,R2,|)
+ CHECKBITWISEOPERATOR(R1,R2,^)
+ CHECKBITWISEOPERATOR(R1,R2,&)
+ CHECKBITWISEOPERATOR(R1,Zero,|)
+ CHECKBITWISEOPERATOR(R1,Zero,^)
+ CHECKBITWISEOPERATOR(R1,Zero,&)
+ CHECKBITWISEOPERATOR(R1,Max,|)
+ CHECKBITWISEOPERATOR(R1,Max,^)
+ CHECKBITWISEOPERATOR(R1,Max,&)
+ CHECKBITWISEOPERATOR(Zero,R1,|)
+ CHECKBITWISEOPERATOR(Zero,R1,^)
+ CHECKBITWISEOPERATOR(Zero,R1,&)
+ CHECKBITWISEOPERATOR(Max,R1,|)
+ CHECKBITWISEOPERATOR(Max,R1,^)
+ CHECKBITWISEOPERATOR(Max,R1,&)
+
+ arith_uint256 TmpL;
+ CHECKASSIGNMENTOPERATOR(R1,R2,|)
+ CHECKASSIGNMENTOPERATOR(R1,R2,^)
+ CHECKASSIGNMENTOPERATOR(R1,R2,&)
+ CHECKASSIGNMENTOPERATOR(R1,Zero,|)
+ CHECKASSIGNMENTOPERATOR(R1,Zero,^)
+ CHECKASSIGNMENTOPERATOR(R1,Zero,&)
+ CHECKASSIGNMENTOPERATOR(R1,Max,|)
+ CHECKASSIGNMENTOPERATOR(R1,Max,^)
+ CHECKASSIGNMENTOPERATOR(R1,Max,&)
+ CHECKASSIGNMENTOPERATOR(Zero,R1,|)
+ CHECKASSIGNMENTOPERATOR(Zero,R1,^)
+ CHECKASSIGNMENTOPERATOR(Zero,R1,&)
+ CHECKASSIGNMENTOPERATOR(Max,R1,|)
+ CHECKASSIGNMENTOPERATOR(Max,R1,^)
+ CHECKASSIGNMENTOPERATOR(Max,R1,&)
+
+ uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL;
+ TmpL = R1L; TmpL |= Tmp64; BOOST_CHECK(TmpL == (R1L | arith_uint256(Tmp64)));
+ TmpL = R1L; TmpL |= 0; BOOST_CHECK(TmpL == R1L);
+ TmpL ^= 0; BOOST_CHECK(TmpL == R1L);
+ TmpL ^= Tmp64; BOOST_CHECK(TmpL == (R1L ^ arith_uint256(Tmp64)));
+}
+
+BOOST_AUTO_TEST_CASE( comparison ) // <= >= < >
+{
+ arith_uint256 TmpL;
+ for (unsigned int i = 0; i < 256; ++i) {
+ TmpL= OneL<< i;
+ BOOST_CHECK( TmpL >= ZeroL && TmpL > ZeroL && ZeroL < TmpL && ZeroL <= TmpL);
+ BOOST_CHECK( TmpL >= 0 && TmpL > 0 && 0 < TmpL && 0 <= TmpL);
+ TmpL |= R1L;
+ BOOST_CHECK( TmpL >= R1L ); BOOST_CHECK( (TmpL == R1L) != (TmpL > R1L)); BOOST_CHECK( (TmpL == R1L) || !( TmpL <= R1L));
+ BOOST_CHECK( R1L <= TmpL ); BOOST_CHECK( (R1L == TmpL) != (R1L < TmpL)); BOOST_CHECK( (TmpL == R1L) || !( R1L >= TmpL));
+ BOOST_CHECK(! (TmpL < R1L)); BOOST_CHECK(! (R1L > TmpL));
+ }
+}
+
+BOOST_AUTO_TEST_CASE( plusMinus )
+{
+ arith_uint256 TmpL = 0;
+ BOOST_CHECK(R1L+R2L == arith_uint256(R1LplusR2L));
+ TmpL += R1L;
+ BOOST_CHECK(TmpL == R1L);
+ TmpL += R2L;
+ BOOST_CHECK(TmpL == R1L + R2L);
+ BOOST_CHECK(OneL+MaxL == ZeroL);
+ BOOST_CHECK(MaxL+OneL == ZeroL);
+ for (unsigned int i = 1; i < 256; ++i) {
+ BOOST_CHECK( (MaxL >> i) + OneL == (HalfL >> (i-1)) );
+ BOOST_CHECK( OneL + (MaxL >> i) == (HalfL >> (i-1)) );
+ TmpL = (MaxL>>i); TmpL += OneL;
+ BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
+ TmpL = (MaxL>>i); TmpL += 1;
+ BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
+ TmpL = (MaxL>>i);
+ BOOST_CHECK( TmpL++ == (MaxL>>i) );
+ BOOST_CHECK( TmpL == (HalfL >> (i-1)));
+ }
+ BOOST_CHECK(arith_uint256(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == arith_uint256(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL));
+ TmpL = arith_uint256(0xbedc77e27940a7ULL); TmpL += 0xee8d836fce66fbULL;
+ BOOST_CHECK(TmpL == arith_uint256(0xbedc77e27940a7ULL+0xee8d836fce66fbULL));
+ TmpL -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpL == 0xbedc77e27940a7ULL);
+ TmpL = R1L;
+ BOOST_CHECK(++TmpL == R1L+1);
+
+ BOOST_CHECK(R1L -(-R2L) == R1L+R2L);
+ BOOST_CHECK(R1L -(-OneL) == R1L+OneL);
+ BOOST_CHECK(R1L - OneL == R1L+(-OneL));
+ for (unsigned int i = 1; i < 256; ++i) {
+ BOOST_CHECK((MaxL>>i) - (-OneL) == (HalfL >> (i-1)));
+ BOOST_CHECK((HalfL >> (i-1)) - OneL == (MaxL>>i));
+ TmpL = (HalfL >> (i-1));
+ BOOST_CHECK(TmpL-- == (HalfL >> (i-1)));
+ BOOST_CHECK(TmpL == (MaxL >> i));
+ TmpL = (HalfL >> (i-1));
+ BOOST_CHECK(--TmpL == (MaxL >> i));
+ }
+ TmpL = R1L;
+ BOOST_CHECK(--TmpL == R1L-1);
+}
+
+BOOST_AUTO_TEST_CASE( multiply )
+{
+ BOOST_CHECK((R1L * R1L).ToString() == "62a38c0486f01e45879d7910a7761bf30d5237e9873f9bff3642a732c4d84f10");
+ BOOST_CHECK((R1L * R2L).ToString() == "de37805e9986996cfba76ff6ba51c008df851987d9dd323f0e5de07760529c40");
+ BOOST_CHECK((R1L * ZeroL) == ZeroL);
+ BOOST_CHECK((R1L * OneL) == R1L);
+ BOOST_CHECK((R1L * MaxL) == -R1L);
+ BOOST_CHECK((R2L * R1L) == (R1L * R2L));
+ BOOST_CHECK((R2L * R2L).ToString() == "ac8c010096767d3cae5005dec28bb2b45a1d85ab7996ccd3e102a650f74ff100");
+ BOOST_CHECK((R2L * ZeroL) == ZeroL);
+ BOOST_CHECK((R2L * OneL) == R2L);
+ BOOST_CHECK((R2L * MaxL) == -R2L);
+
+ BOOST_CHECK(MaxL * MaxL == OneL);
+
+ BOOST_CHECK((R1L * 0) == 0);
+ BOOST_CHECK((R1L * 1) == R1L);
+ BOOST_CHECK((R1L * 3).ToString() == "7759b1c0ed14047f961ad09b20ff83687876a0181a367b813634046f91def7d4");
+ BOOST_CHECK((R2L * 0x87654321UL).ToString() == "23f7816e30c4ae2017257b7a0fa64d60402f5234d46e746b61c960d09a26d070");
+}
+
+BOOST_AUTO_TEST_CASE( divide )
+{
+ arith_uint256 D1L("AD7133AC1977FA2B7");
+ arith_uint256 D2L("ECD751716");
+ BOOST_CHECK((R1L / D1L).ToString() == "00000000000000000b8ac01106981635d9ed112290f8895545a7654dde28fb3a");
+ BOOST_CHECK((R1L / D2L).ToString() == "000000000873ce8efec5b67150bad3aa8c5fcb70e947586153bf2cec7c37c57a");
+ BOOST_CHECK(R1L / OneL == R1L);
+ BOOST_CHECK(R1L / MaxL == ZeroL);
+ BOOST_CHECK(MaxL / R1L == 2);
+ BOOST_CHECK_THROW(R1L / ZeroL, uint_error);
+ BOOST_CHECK((R2L / D1L).ToString() == "000000000000000013e1665895a1cc981de6d93670105a6b3ec3b73141b3a3c5");
+ BOOST_CHECK((R2L / D2L).ToString() == "000000000e8f0abe753bb0afe2e9437ee85d280be60882cf0bd1aaf7fa3cc2c4");
+ BOOST_CHECK(R2L / OneL == R2L);
+ BOOST_CHECK(R2L / MaxL == ZeroL);
+ BOOST_CHECK(MaxL / R2L == 1);
+ BOOST_CHECK_THROW(R2L / ZeroL, uint_error);
+}
+
+
+bool almostEqual(double d1, double d2)
+{
+ return fabs(d1-d2) <= 4*fabs(d1)*std::numeric_limits<double>::epsilon();
+}
+
+BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex size() GetLow64 GetSerializeSize, Serialize, Unserialize
+{
+ BOOST_CHECK(R1L.GetHex() == R1L.ToString());
+ BOOST_CHECK(R2L.GetHex() == R2L.ToString());
+ BOOST_CHECK(OneL.GetHex() == OneL.ToString());
+ BOOST_CHECK(MaxL.GetHex() == MaxL.ToString());
+ arith_uint256 TmpL(R1L);
+ BOOST_CHECK(TmpL == R1L);
+ TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L);
+ TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == 0);
+ TmpL.SetHex(HalfL.ToString()); BOOST_CHECK(TmpL == HalfL);
+
+ TmpL.SetHex(R1L.ToString());
+ BOOST_CHECK(R1L.size() == 32);
+ BOOST_CHECK(R2L.size() == 32);
+ BOOST_CHECK(ZeroL.size() == 32);
+ BOOST_CHECK(MaxL.size() == 32);
+ BOOST_CHECK(R1L.GetLow64() == R1LLow64);
+ BOOST_CHECK(HalfL.GetLow64() ==0x0000000000000000ULL);
+ BOOST_CHECK(OneL.GetLow64() ==0x0000000000000001ULL);
+
+ for (unsigned int i = 0; i < 255; ++i)
+ {
+ BOOST_CHECK((OneL << i).getdouble() == ldexp(1.0,i));
+ }
+ BOOST_CHECK(ZeroL.getdouble() == 0.0);
+ for (int i = 256; i > 53; --i)
+ BOOST_CHECK(almostEqual((R1L>>(256-i)).getdouble(), ldexp(R1Ldouble,i)));
+ uint64_t R1L64part = (R1L>>192).GetLow64();
+ for (int i = 53; i > 0; --i) // doubles can store all integers in {0,...,2^54-1} exactly
+ {
+ BOOST_CHECK((R1L>>(256-i)).getdouble() == (double)(R1L64part >> (64-i)));
+ }
+}
+
+BOOST_AUTO_TEST_CASE(bignum_SetCompact)
+{
+ arith_uint256 num;
+ bool fNegative;
+ bool fOverflow;
+ num.SetCompact(0, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x00123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x01003456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x02000056, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x03000000, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x04000000, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x00923456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x01803456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x02800056, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x03800000, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x04800000, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x01123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000012");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x01120000U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ // Make sure that we don't generate compacts with the 0x00800000 bit set
+ num = 0x80;
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x02008000U);
+
+ num.SetCompact(0x01fedcba, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "000000000000000000000000000000000000000000000000000000000000007e");
+ BOOST_CHECK_EQUAL(num.GetCompact(true), 0x01fe0000U);
+ BOOST_CHECK_EQUAL(fNegative, true);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x02123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000001234");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x02123400U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x03123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000123456");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x03123456U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x04123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x04123456U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x04923456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
+ BOOST_CHECK_EQUAL(num.GetCompact(true), 0x04923456U);
+ BOOST_CHECK_EQUAL(fNegative, true);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x05009234, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000092340000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x05009234U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0x20123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(num.GetHex(), "1234560000000000000000000000000000000000000000000000000000000000");
+ BOOST_CHECK_EQUAL(num.GetCompact(), 0x20123456U);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, false);
+
+ num.SetCompact(0xff123456, &fNegative, &fOverflow);
+ BOOST_CHECK_EQUAL(fNegative, false);
+ BOOST_CHECK_EQUAL(fOverflow, true);
+}
+
+
+BOOST_AUTO_TEST_CASE( getmaxcoverage ) // some more tests just to get 100% coverage
+{
+ // ~R1L give a base_uint<256>
+ BOOST_CHECK((~~R1L >> 10) == (R1L >> 10));
+ BOOST_CHECK((~~R1L << 10) == (R1L << 10));
+ BOOST_CHECK(!(~~R1L < R1L));
+ BOOST_CHECK(~~R1L <= R1L);
+ BOOST_CHECK(!(~~R1L > R1L));
+ BOOST_CHECK(~~R1L >= R1L);
+ BOOST_CHECK(!(R1L < ~~R1L));
+ BOOST_CHECK(R1L <= ~~R1L);
+ BOOST_CHECK(!(R1L > ~~R1L));
+ BOOST_CHECK(R1L >= ~~R1L);
+
+ BOOST_CHECK(~~R1L + R2L == R1L + ~~R2L);
+ BOOST_CHECK(~~R1L - R2L == R1L - ~~R2L);
+ BOOST_CHECK(~R1L != R1L); BOOST_CHECK(R1L != ~R1L);
+ unsigned char TmpArray[32];
+ CHECKBITWISEOPERATOR(~R1,R2,|)
+ CHECKBITWISEOPERATOR(~R1,R2,^)
+ CHECKBITWISEOPERATOR(~R1,R2,&)
+ CHECKBITWISEOPERATOR(R1,~R2,|)
+ CHECKBITWISEOPERATOR(R1,~R2,^)
+ CHECKBITWISEOPERATOR(R1,~R2,&)
+}
+
+BOOST_AUTO_TEST_SUITE_END()
// Copyright (c) 2012-2013 The Bitcoin Core 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 "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(base32_tests)
+BOOST_FIXTURE_TEST_SUITE(base32_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(base32_testvectors)
{
// Copyright (c) 2011-2014 The Bitcoin Core 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"
#include "uint256.h"
#include "util.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
using namespace json_spirit;
extern Array read_json(const std::string& jsondata);
-BOOST_AUTO_TEST_SUITE(base58_tests)
+BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup)
// Goal: test low-level base58 encoding functionality
BOOST_AUTO_TEST_CASE(base58_EncodeBase58)
std::vector<unsigned char> result;
CBitcoinSecret secret;
CBitcoinAddress addr;
+ SelectParams(CBaseChainParams::MAIN);
BOOST_FOREACH(Value& tv, tests)
{
BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest);
}
}
- SelectParams(CBaseChainParams::UNITTEST);
}
// Goal: check that generated keys match test vectors
CTxDestination nodest = CNoDestination();
BOOST_CHECK(!dummyAddr.Set(nodest));
- SelectParams(CBaseChainParams::UNITTEST);
+ SelectParams(CBaseChainParams::MAIN);
}
// Goal: check that base58 parsing code is robust against a variety of corrupted data
// Copyright (c) 2011-2013 The Bitcoin Core 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 "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(base64_tests)
+BOOST_FIXTURE_TEST_SUITE(base64_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(base64_testvectors)
{
# Copyright 2014 BitPay, Inc.
-# 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.
import subprocess
// 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-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_TEST_BIGNUM_H
if (!BN_copy(this, &b))
{
BN_clear_free(this);
- throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
+ throw bignum_error("CBigNum::CBigNum(const CBigNum&): BN_copy failed");
}
}
CBigNum& operator=(const CBigNum& b)
{
if (!BN_copy(this, &b))
- throw bignum_error("CBigNum::operator= : BN_copy failed");
+ throw bignum_error("CBigNum::operator=: BN_copy failed");
return (*this);
}
{
CBigNum r;
if (!BN_add(&r, &a, &b))
- throw bignum_error("CBigNum::operator+ : BN_add failed");
+ throw bignum_error("CBigNum::operator+: BN_add failed");
return r;
}
{
CBigNum r;
if (!BN_sub(&r, &a, &b))
- throw bignum_error("CBigNum::operator- : BN_sub failed");
+ throw bignum_error("CBigNum::operator-: BN_sub failed");
return r;
}
// Copyright (c) 2013 The Bitcoin Core 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 <boost/test/unit_test.hpp>
#include "key.h"
#include "uint256.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#include <string>
#include <vector>
}
}
-BOOST_AUTO_TEST_SUITE(bip32_tests)
+BOOST_FIXTURE_TEST_SUITE(bip32_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(bip32_test1) {
RunTest(test1);
#!/usr/bin/python
# Copyright 2014 BitPay, Inc.
-# 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.
import os
// Copyright (c) 2012-2013 The Bitcoin Core 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 "bloom.h"
#include "base58.h"
#include "clientversion.h"
#include "key.h"
-#include "main.h"
+#include "merkleblock.h"
#include "serialize.h"
+#include "streams.h"
#include "uint256.h"
#include "util.h"
+#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <vector>
#include <boost/tuple/tuple.hpp>
using namespace std;
-using namespace boost::tuples;
-BOOST_AUTO_TEST_SUITE(bloom_tests)
+BOOST_FIXTURE_TEST_SUITE(bloom_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize)
{
spendStream >> spendingTx;
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
- filter.insert(uint256("0xb4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b"));
+ filter.insert(uint256S("0xb4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b"));
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match tx hash");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match output address");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
- filter.insert(COutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
+ filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match COutPoint");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
- COutPoint prevOutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0);
+ COutPoint prevOutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0);
{
vector<unsigned char> data(32 + sizeof(unsigned int));
memcpy(&data[0], prevOutPoint.hash.begin(), 32);
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match manually serialized COutPoint");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
- filter.insert(uint256("00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436"));
+ filter.insert(uint256S("00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436"));
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random tx hash");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random address");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
- filter.insert(COutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 1));
+ filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 1));
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
- filter.insert(COutPoint(uint256("0x000000d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
+ filter.insert(COutPoint(uint256S("0x000000d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about");
}
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the last transaction
- filter.insert(uint256("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"));
+ filter.insert(uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 8);
vector<uint256> vMatched;
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
// Also match the 8th transaction
- filter.insert(uint256("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"));
+ filter.insert(uint256S("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"));
merkleBlock = CMerkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair);
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xdd1fd2a6fc16404faf339881a90adbde7f4f728691ac62e8f168809cdfae1053"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 7);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the first transaction
- filter.insert(uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
+ filter.insert(uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
vector<uint256> vMatched;
BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
- BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1);
- BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256("0x6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0x6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2"));
BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 2);
- BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
BOOST_CHECK(merkleBlock.vMatchedTxn[3].first == 3);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_NONE);
// Match the first transaction
- filter.insert(uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
+ filter.insert(uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xe980fe9f792d014e73b95203dc1335c5f9ce19ac537a419e6df5b47aecb93b70"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
vector<uint256> vMatched;
BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
- BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1);
- BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 3);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the only transaction
- filter.insert(uint256("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
+ filter.insert(uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
vector<uint256> vMatched;
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the last transaction
- filter.insert(uint256("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"));
+ filter.insert(uint256S("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x0a2a92f0bda4727d0a13eaddf4dd9ac6b5c61a1429e6b2b818f19b15df0ac154"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 6);
vector<uint256> vMatched;
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
// Also match the 4th transaction
- filter.insert(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
+ filter.insert(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
merkleBlock = CMerkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2);
- BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
+ BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 3);
BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
// We should match the generation outpoint
- BOOST_CHECK(filter.contains(COutPoint(uint256("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
+ BOOST_CHECK(filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
// ... but not the 4th transaction's output (its not pay-2-pubkey)
- BOOST_CHECK(!filter.contains(COutPoint(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
+ BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
}
BOOST_AUTO_TEST_CASE(merkle_block_4_test_update_none)
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
// We shouldn't match any outpoints (UPDATE_NONE)
- BOOST_CHECK(!filter.contains(COutPoint(uint256("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
- BOOST_CHECK(!filter.contains(COutPoint(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
+ BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
+ BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
}
BOOST_AUTO_TEST_SUITE_END()
// Copyright (c) 2013-2014 The Bitcoin Core 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 "clientversion.h"
#include "main.h"
#include "utiltime.h"
+#include "test/test_bitcoin.h"
#include <cstdio>
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(CheckBlock_tests)
+BOOST_FIXTURE_TEST_SUITE(CheckBlock_tests, BasicTestingSetup)
bool read_block(const std::string& filename, CBlock& block)
{
#include "coins.h"
#include "random.h"
#include "uint256.h"
+#include "test/test_bitcoin.h"
#include <vector>
#include <map>
};
}
-BOOST_AUTO_TEST_SUITE(coins_tests)
+BOOST_FIXTURE_TEST_SUITE(coins_tests, BasicTestingSetup)
static const unsigned int NUM_SIMULATION_ITERATIONS = 40000;
// Copyright (c) 2012-2013 The Bitcoin Core 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 "compressor.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#include <stdint.h>
// amounts 50 .. 21000000
#define NUM_MULTIPLES_50BTC 420000
-BOOST_AUTO_TEST_SUITE(compress_tests)
+BOOST_FIXTURE_TEST_SUITE(compress_tests, BasicTestingSetup)
bool static TestEncode(uint64_t in) {
return in == CTxOutCompressor::DecompressAmount(CTxOutCompressor::CompressAmount(in));
// Copyright (c) 2014 The Bitcoin Core 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 "crypto/ripemd160.h"
#include "crypto/sha1.h"
-#include "crypto/sha2.h"
+#include "crypto/sha256.h"
+#include "crypto/sha512.h"
+#include "crypto/hmac_sha256.h"
+#include "crypto/hmac_sha512.h"
#include "random.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <vector>
+#include <boost/assign/list_of.hpp>
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(crypto_tests)
+BOOST_FIXTURE_TEST_SUITE(crypto_tests, BasicTestingSetup)
template<typename Hasher, typename In, typename Out>
void TestVector(const Hasher &h, const In &in, const Out &out) {
void TestSHA512(const std::string &in, const std::string &hexout) { TestVector(CSHA512(), in, ParseHex(hexout));}
void TestRIPEMD160(const std::string &in, const std::string &hexout) { TestVector(CRIPEMD160(), in, ParseHex(hexout));}
+void TestHMACSHA256(const std::string &hexkey, const std::string &hexin, const std::string &hexout) {
+ std::vector<unsigned char> key = ParseHex(hexkey);
+ TestVector(CHMAC_SHA256(&key[0], key.size()), ParseHex(hexin), ParseHex(hexout));
+}
+
void TestHMACSHA512(const std::string &hexkey, const std::string &hexin, const std::string &hexout) {
std::vector<unsigned char> key = ParseHex(hexkey);
TestVector(CHMAC_SHA512(&key[0], key.size()), ParseHex(hexin), ParseHex(hexout));
"37de8c3ef5459d76a52cedc02dc499a3c9ed9dedbfb3281afd9653b8a112fafc");
}
+BOOST_AUTO_TEST_CASE(hmac_sha256_testvectors) {
+ // test cases 1, 2, 3, 4, 6 and 7 of RFC 4231
+ TestHMACSHA256("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
+ "4869205468657265",
+ "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7");
+ TestHMACSHA256("4a656665",
+ "7768617420646f2079612077616e7420666f72206e6f7468696e673f",
+ "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843");
+ TestHMACSHA256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
+ "dddddddddddddddddddddddddddddddddddd",
+ "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe");
+ TestHMACSHA256("0102030405060708090a0b0c0d0e0f10111213141516171819",
+ "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
+ "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
+ "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b");
+ TestHMACSHA256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaa",
+ "54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a"
+ "65204b6579202d2048617368204b6579204669727374",
+ "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54");
+ TestHMACSHA256("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaa",
+ "5468697320697320612074657374207573696e672061206c6172676572207468"
+ "616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074"
+ "68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565"
+ "647320746f20626520686173686564206265666f7265206265696e6720757365"
+ "642062792074686520484d414320616c676f726974686d2e",
+ "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2");
+}
+
BOOST_AUTO_TEST_CASE(hmac_sha512_testvectors) {
// test cases 1, 2, 3, 4, 6 and 7 of RFC 4231
TestHMACSHA512("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
License
--------
-The data files in this directory are
-
- Copyright (c) 2012-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.
+The data files in this directory are distributed under the MIT software
+license, see the accompanying file COPYING or
+http://www.opensource.org/licenses/mit-license.php.
{ "exec": "./bitcoin-tx",
"args": ["-create", "outscript=0:"],
"output_cmp": "txcreate2.hex"
+ },
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
+ "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
+ "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]",
+ "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\"}]",
+ "sign=ALL",
+ "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
+ "output_cmp": "txcreatesign.hex"
}
]
[
-["
-Format is: [scriptPubKey, scriptSig, flags, ... comments]
-It is evaluated as if there was a crediting coinbase transaction with two 0
-pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,
-followed by a spending transaction which spends this output as only input (and
-correct prevout hash), using the given scriptSig. All nLockTimes are 0, all
-nSequences are max.
-"],
+["Format is: [scriptSig, scriptPubKey, flags, ... comments]"],
+["It is evaluated as if there was a crediting coinbase transaction with two 0"],
+["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"],
+["followed by a spending transaction which spends this output as only input (and"],
+["correct prevout hash), using the given scriptSig. All nLockTimes are 0, all"],
+["nSequences are max."],
["", "DEPTH", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation"],
[" ", "DEPTH", "P2SH,STRICTENC", "and multiple spaces should not change that."],
["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "MINIMALDATA"],
+["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."],
[
- "0x47 0x30440220304eff7556bba9560df47873275e64db45f3cd735998ce3f00d2e57b1bb5f31302205c0c9d14b8b80d43e2ac9b87532f1af6d8a3271262bc694ec4e14068392bb0a001",
+ "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 1",
+ "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT",
+ "STRICTENC",
+ "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid."
+],
+
+["Increase DERSIG test coverage"],
+["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Overly long signature is incorrectly encoded for DERSIG"],
+["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Missing S is incorrectly encoded for DERSIG"],
+["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "S with invalid S length is incorrectly encoded for DERSIG"],
+["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer R is incorrectly encoded for DERSIG"],
+["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer S is incorrectly encoded for DERSIG"],
+["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Zero-length R is incorrectly encoded for DERSIG"],
+["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "Zero-length S is incorrectly encoded for DERSIG"],
+["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Negative S is incorrectly encoded for DERSIG"],
+
+["Automatically generated test cases"],
+[
+ "0x47 0x3044022053205076a7bb12d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801",
"0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
"",
"P2PK, bad sig"
],
[
- "0x47 0x3044022037fcdb8e08f41e27588de8bc036d2c4b16eb3d09c1ba53b8f47a0a9c27722a39022058664b7a53b507e71dfafb77193e3786c3f0c119d78ce9104480ee7ece04f09301 0x21 0x03363d90d446b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640",
+ "0x47 0x30440220151ea78fa148b59f399b23731b634645ebc142f299ee9838d46fb78cf7e0bc0102200d62327dcd54ac6bcfb1516b035b1bf8eaea438c52c62d3450d1f3a8f030e0de01 0x21 0x03363d90d446b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640",
"DUP HASH160 0x14 0xc0834c0c158f53be706d234c38fd52de7eece656 EQUALVERIFY CHECKSIG",
"",
"P2PKH, bad pubkey"
],
[
- "0x47 0x3044022035e5b6742d299861c84cebaf2ea64145ee427a95facab39e2594d6deebb0c1d602200acb16778faa2e467a59006f342f2535b1418d55ba63a8605b387b7f9ac86d9a01",
+ "0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790201",
"0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG",
"",
"P2PK anyonecanpay marked with normal hashtype"
],
[
- "0x47 0x3044022029b2b8765ca950cf75a69e80b73b7ddfcaa8b27080c2db4c23b36aae60688e790220598ff368e17872ee065aa54d7d3a590682ca5204325b23b31d7da3c4a21ae67901 0x23 0x210279be667ef9dcbbac54a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac",
+ "0x47 0x304402202166fcd5e607de452d3c6f15e059505cf21654346592f9650ba906b9e8be88fa022005d976d28eb8de477102feba28807b3ad361e7fa24796d259c9d61452f7c318c01 0x23 0x210279be667ef9dcbbac54a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac",
"HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL",
"P2SH",
"P2SH(P2PK), bad redeemscript"
],
[
- "0x47 0x30440220647f906e63890df5ef1d3fed47ba892b31976c634281079e2bd38504fb54a1fb022021e8811f38fbe90efb6b74cb78da01d9badbac3bafdf70a861d7538a220d0b2601 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac",
+ "0x47 0x3044022064cc90ca89ad721384b231653b945579359a24b928ef8539b331172628c9cc6102203e238869ab5dac3fc293db53c12e7dd3079e86cfde9024b689efc7227e4d671001 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac",
"HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL",
"P2SH",
"P2SH(P2PKH), bad sig"
],
[
- "0 0x47 0x304402203ef170402f8887f2ac183f31b1f503b0bc60bfc968dd469b097ea6124aefac5002200612febadc4e4cacc086982cb85830a17af3680c1b6a3cf77c1708af7621cf1301 0 0x47 0x304402207821838251a24a2234844f68e7169e6d11945cdf052ea12bd3e4e37457aceb4402200b6b46c81361e314c740ae5133c072af5fa5c209d65d2db1679e1716f19a538101",
+ "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402206d32e6d6b131ef2fe77b6a9b90b120d74e3e238e79dcffb10523a6ec94f93d65022067ae8772632ddf4c389258c6b70ed0ff94f20ee8f60207aa192a52a2469cddd901 0",
"3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG",
"",
"3-of-3, 2 sigs"
],
[
- "0 0 0x47 0x304402204661f7795e8db7be3132e8974e9a76d1d24b31f23df94c6fbcea07d1c205789102203f5e45a1c0b085279b58d11b36d5fea5449c3cf16f844ad10124e9b65e8777d201 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae",
+ "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae",
"HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL",
"P2SH",
"P2SH(2-of-3), 1 sig"
],
[
- "0x47 0x304402200052bc1600ca45c71f3538720fe62a5e8548dffd137af04467598c98466e9c0a0220789318ddbc9991ee477974089220a2feb6a6298a7c93d5ff6c25a92a2f4b48d501",
+ "0x47 0x30440220001d6702bfa4f49c3a2542af9b1c2844a2eaac55f86f310f42d26a5dd17d6a8002202cdadbe608c00b50dd951c6ba0877d5b07a970f3e265c18697bc413a0a86f69901",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
- "STRICTENC",
+ "DERSIG",
"P2PK with too much R padding"
],
[
- "0x48 0x304502206eb7b92628bfb3c4d2a04b65b986987bcbb1af4fceedb144d5a0437b7ee410590221005f57a52df4aa26366742eed0db182fce51fbcd7159011b0644a7c05943eb228901",
+ "0x48 0x304502207d2b258e959605e2ea50b46fea1325b7391ffb0c14a5b58ef8ad3851da3644380221007e75136df5f2e38216c4338b31c97e8307102edb97d611e06914e1f8fba68ead01",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
- "STRICTENC",
+ "DERSIG",
"P2PK with too much S padding"
],
[
- "0x47 0x30440220d8ad1efd55a3d2b8896495c38aba72056e1b3ca4a6ca15760e843eb1a9b9907602203eb0e8f3d6bec998262dfd03eaeb0f31c4e5105965436dec77550724b3771f3201",
+ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
- "STRICTENC",
+ "DERSIG",
"P2PK with too little R padding"
],
[
- "0x47 0x30440220001d0f82c127470cb38316c96b1719b33382353687a1146a776dee8259606905022062cd1fc8eacef819d68f0f41cc9ae9fdc2e29b70c3c7ad2c6c18f39b4e35c42701",
+ "0x47 0x30440220003040725f724b0e2142fc44ac71f6e13161f6410aeb6dee477952ede3b6a6ca022041ff4940ee3d88116ad281d7cc556e1f2c9427d82290bd7974a25addbcd5bede01",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT",
"DERSIG",
"P2PK NOT with bad sig with too much R padding"
],
[
- "0x47 0x30440220005d727e2a82d6e8a98a6da6fbc281325644d1a40455e386fdb17883a8e6bc4d02202d15cca42ce136047a980d288e60c679d7e84cce18c3ceffb6bc81b9e9ba517801",
+ "0x47 0x30440220003040725f724a0e2142fc44ac71f6e13161f6410aeb6dee477952ede3b6a6ca022041ff4940ee3d88116ad281d7cc556e1f2c9427d82290bd7974a25addbcd5bede01",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT",
"",
"P2PK NOT with too much R padding but no DERSIG"
],
[
- "0x47 0x30440220006e8bc4f82032b12bd594847c16d8b2986de734aa3b0528bd89d664d41e6d1c02200cfd582694891bcfa2e630e899bda257486eba00a007222fae71144dba07dc2901",
+ "0x47 0x30440220003040725f724a0e2142fc44ac71f6e13161f6410aeb6dee477952ede3b6a6ca022041ff4940ee3d88116ad281d7cc556e1f2c9427d82290bd7974a25addbcd5bede01",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT",
"DERSIG",
"P2PK NOT with too much R padding"
],
[
- "0x48 0x304502206c43e065c8a8db3bbe69015afb86a51fb2fc8870defd41d436da2a197d9d6c12022100fcec35816ee2d84ec271ad159fcabf5dd712157051169e48ac328a7818cdb51e01",
+ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "DERSIG",
+ "BIP66 example 1, with DERSIG"
+],
+[
+ "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "",
+ "BIP66 example 2, without DERSIG"
+],
+[
+ "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "DERSIG",
+ "BIP66 example 2, with DERSIG"
+],
+[
+ "0",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "",
+ "BIP66 example 3, without DERSIG"
+],
+[
+ "0",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "DERSIG",
+ "BIP66 example 3, with DERSIG"
+],
+[
+ "1",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "",
+ "BIP66 example 5, without DERSIG"
+],
+[
+ "1",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "DERSIG",
+ "BIP66 example 5, with DERSIG"
+],
+[
+ "1",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "DERSIG",
+ "BIP66 example 6, with DERSIG"
+],
+[
+ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x304402200b3d0b0375bb15c14620afa4aa10ae90a0d6a046ce217bc20fe0bc1ced68c1b802204b550acab90ae6d3478057c9ad24f9df743815b799b6449dd7e7f6d3bc6e274c01",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "DERSIG",
+ "BIP66 example 7, with DERSIG"
+],
+[
+ "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "",
+ "BIP66 example 8, without DERSIG"
+],
+[
+ "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "DERSIG",
+ "BIP66 example 8, with DERSIG"
+],
+[
+ "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "",
+ "BIP66 example 9, without DERSIG"
+],
+[
+ "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "DERSIG",
+ "BIP66 example 9, with DERSIG"
+],
+[
+ "0 0 0x47 0x30440220afa76a8f60622f813b05711f051c6c3407e32d1b1b70b0576c1f01b54e4c05c702200d58e9df044fd1845cabfbeef6e624ba0401daf7d7e084736f9ff601c3783bf501",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "DERSIG",
+ "BIP66 example 10, with DERSIG"
+],
+[
+ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "",
+ "BIP66 example 11, without DERSIG"
+],
+[
+ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "DERSIG",
+ "BIP66 example 11, with DERSIG"
+],
+[
+ "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
+ "DERSIG",
+ "P2PK with multi-byte hashtype, with DERSIG"
+],
+[
+ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
- "LOW_S,STRICTENC",
+ "LOW_S",
"P2PK with high S"
],
[
- "0x47 0x304402203aab50cd7c30cc1e1475dee615b295bcee6ccf8aa8a7f6cda6b696c70d79cbb40220558e43fe7596c31146e2d077698d5a9c38351d8ba567549a2ae43ca97231c39501",
+ "0x47 0x30440220745d63eb70d45652128b450aa5ca7d9b513439963f261cb1c40a60f0785e7ee402204877785b38945ca9dbec78e1c1d4dd12148cc25c868bd27480023b49ae0f310501",
"0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
"STRICTENC",
"P2PK with hybrid pubkey"
],
[
- "0x47 0x304402205745e8f846110c185ee1185c01843a108588b81463d2c34d4a3f2445529f12fe02206ee6a2657bbc4e2bb74bfc44c3a5c4f410ed6356ca68982465de6ca807c807c201",
+ "0x47 0x30440220606f6f9f6cebc94ebfb6a4bff0b682bd99f05511295545ce9b275e98be3c946102206871d6a76f4e1b43d9763cfc5647844e4811682b1cab0325f060f44ddf44002201",
"0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT",
"",
"P2PK NOT with hybrid pubkey but no STRICTENC"
],
[
- "0x47 0x3044022078033e4227aa05ded69d8da579966578e230d8a7fb44d5f1a0620c3853c24f78022006a2e3f4d872ac8dfdc529110aa37301d65a76255a4b6cce2992adacd4d2c4e201",
+ "0x47 0x30440220606f6f9f6cebc94ebfb6a4bff0b682bd99f05511295545ce9b275e98be3c946102206871d6a76f4e1b43d9763cfc5647844e4811682b1cab0325f060f44ddf44002201",
"0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT",
"STRICTENC",
"P2PK NOT with hybrid pubkey"
],
[
- "0x47 0x304402207592427de20e315d644839754f2a5cca5b978b983a15e6da82109ede01722baa022032ceaf78590faa3f7743821e1b47b897ed1a57f6ee1c8a7519d23774d8de3c4401",
+ "0x47 0x30440220606f6f9f6cebc84ebfb6a4bff0b682bd99f05511295545ce9b275e98be3c946102206871d6a76f4e1b43d9763cfc5647844e4811682b1cab0325f060f44ddf44002201",
"0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT",
"STRICTENC",
"P2PK NOT with invalid hybrid pubkey"
],
[
- "0 0x47 0x304402206797289d3dc81692edae58430276d04641ea5d86967be557163f8494da32fd78022006fc6ab77aaed4ac11ea69cd878ab26e3e24290f47a43e9adf34075d52b7142c01",
+ "0 0x47 0x304402203cdcf66792fe97e3955655ede5dad004950e58b369831ffa7743132c507b272c022031fbcfb4a72b3e00217abf2f5557585f1f9891f12827d2f0a2ae2978e7f9f11001",
"1 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 2 CHECKMULTISIG",
"STRICTENC",
"1-of-2 with the first 1 hybrid pubkey"
],
[
- "0x47 0x304402201f82b99a813c9c48c8dee8d2c43b8f637b72353fe9bdcc084537bc17e2ab770402200c43b96a5f7e115f0114eabda32e068145965cb6c7b5ef64833bb4fcf9fc1b3b05",
+ "0x47 0x304402201c215cb13e4954e60ce4f6de74941904c771f998de7b1d9627e82a1949fde517022031c2197455f3dbecbb78321201308d7b039424e38d480772d7cd4eb465a083f405",
"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",
+ "0x47 0x304402207409b5b320296e5e2136a7b281a7f803028ca4ca44e2b83eebd46932677725de02202d4eea1c8d3c98e6f42614f54764e6e5e6542e213eb4d079737e9a8b6e9812ec05",
"0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT",
"STRICTENC",
"P2PK NOT with invalid sig and undefined hashtype"
],
[
- "0x01 0x01 0x47 0x304402200e48ba1cf4d7182db94ffb57bd72ea31b5545dc0d1c512e665779b4fb2badc52022054b8388dfc074c708a75b62359b7be46402751ee40c0a111aef38a837b6ed09801 0x47 0x304402201c9820f59c49107bb30e6175cfc9ec95f897b03beb628b4bc854d2b80392aa0602200235d986ae418bcd111b8814f4c26a0ab5f475fb542a44884fc14912a97a252301 0x47 0x304402204cd7894c6f10a871f5b0c1f9c13228f8cdd4050248f0d0f498ee86be69ee3080022051bd2932c7d585eb600c7194235c74da820935f0d67972fd9545673aa1fd023301",
+ "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402206d32e6d6b131ef2fe77b6a9b90b120d74e3e238e79dcffb10523a6ec94f93d65022067ae8772632ddf4c389258c6b70ed0ff94f20ee8f60207aa192a52a2469cddd901 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901",
"3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG",
"NULLDUMMY",
"3-of-3 with nonzero dummy"
],
[
- "0x01 0x01 0x47 0x304402201847fc3b8f7597768e7f543c58da1fca6e8e35eb28979431e6b637572ce6eaa4022048dd58608e040841d0bf52a70cfb70e1a9c8d2826fad068f4e9d2bf5c87766a501 0x47 0x30440220711311a72516affed73363763983d05c3d6a06a2eadf5d76b90b4354162ba94302204841a69e5955a7dc8e4ab3105fd0c86040c1dac6016297a51ddbf5079c28756801 0x47 0x30440220267e331a378191e7282fd10d61c97bf74bc97c233c5833d677936424ac08dee502201eee83d88b91988e1c4d9b979df2404aa190e0987a8ca09c4e5cd61da1d48ecc01",
+ "1 0x47 0x304402201bb2edab700a5d020236df174fefed78087697143731f659bea59642c759c16d022061f42cdbae5bcd3e8790f20bf76687443436e94a634321c16a72aa54cbc7c2ea01 0x47 0x304402204bb4a64f2a6e5c7fb2f07fef85ee56fde5e6da234c6a984262307a20e99842d702206f8303aaba5e625d223897e2ffd3f88ef1bcffef55f38dc3768e5f2e94c923f901 0x47 0x3044022040c2809b71fffb155ec8b82fe7a27f666bd97f941207be4e14ade85a1249dd4d02204d56c85ec525dd18e29a0533d5ddf61b6b1bb32980c2f63edf951aebf7a27bfe01",
"3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT",
"NULLDUMMY",
"3-of-3 NOT with invalid sig with nonzero dummy"
],
[
- "0 0x47 0x3044022035341cc377b19138f944f90c45772cb06338c6d56a4c0c31a65bf1a8a105fadc022046dd232850b6bacb25879c9da82a7a628982aa19d055f1753468f68047662e0301 DUP",
+ "0 0x47 0x304402206cb053202e1501e6faa24e6e309bf46a2f9255aa9484ff4a26efb7434f78a58a0220132b10419c3b99601f154bf86cf12259aacd8c6f363a73dacb1d0b941680bb4c01 DUP",
"2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG",
"SIGPUSHONLY",
"2-of-2 with two identical keys and sigs pushed using OP_DUP"
],
[
- "0x47 0x304402204d8b99eea2f53382fd67e0dbc8ed0596bd614aa0dad6bc6843c7860c79b901c3022062f022a71993013e3d9b22302a8e4b40109d7bb057aeb250b9aab2197b3e96b801 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac",
+ "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
"",
"P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY"
],
[
- "0x47 0x30440220078c887c33abc67fbbd827ceb3f661c1c459e78218161b652f23e3ca76cfabbd022047df245eacb8a88d8c5ca7b5228e3b4d070c102d2f542433362d3f443cd24eda01 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac",
+ "0x47 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb125101 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
"SIGPUSHONLY",
"P2SH(P2PK) with non-push scriptSig"
],
+[
+ "11 0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801",
+ "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
+ "CLEANSTACK,P2SH",
+ "P2PK with unnecessary input"
+],
+[
+ "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
+ "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL",
+ "CLEANSTACK,P2SH",
+ "P2SH with unnecessary input"
+],
["The End"]
]
[
-["
-Format is: [scriptPubKey, scriptSig, flags, ... comments]
-It is evaluated as if there was a crediting coinbase transaction with two 0
-pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,
-followed by a spending transaction which spends this output as only input (and
-correct prevout hash), using the given scriptSig. All nLockTimes are 0, all
-nSequences are max.
-"],
+["Format is: [scriptSig, scriptPubKey, flags, ... comments]"],
+["It is evaluated as if there was a crediting coinbase transaction with two 0"],
+["pushes as scriptSig, and one output of 0 satoshi and given scriptPubKey,"],
+["followed by a spending transaction which spends this output as only input (and"],
+["correct prevout hash), using the given scriptSig. All nLockTimes are 0, all"],
+["nSequences are max."],
["", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "Test the test: we should have an empty stack after scriptSig evaluation"],
[" ", "DEPTH 0 EQUAL", "P2SH,STRICTENC", "and multiple spaces should not change that."],
["0 0 0x02 0x0000", "CHECKMULTISIGVERIFY 1", ""],
["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", ""],
+["While not really correctly DER encoded, the empty signature is allowed by"],
+["STRICTENC to provide a compact way to provide a delibrately invalid signature."],
+["0", "0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 CHECKSIG NOT", "STRICTENC"],
+["0 0", "1 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 1 CHECKMULTISIG NOT", "STRICTENC"],
+
+["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."
+],
+["Increase test coverage for DERSIG"],
+["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Overly long signature is correctly encoded"],
+["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Missing S is correctly encoded"],
+["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "", "S with invalid S length is correctly encoded"],
+["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer R is correctly encoded"],
+["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer S is correctly encoded"],
+["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Zero-length R is correctly encoded"],
+["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "Zero-length S is correctly encoded for DERSIG"],
+["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Negative S is correctly encoded"],
+
+["Automatically generated test cases"],
[
- "0x47 0x3044022007415aa37ce7eaa6146001ac8bdefca0ddcba0e37c5dc08c4ac99392124ebac802207d382307fd53f65778b07b9c63b6e196edeadf0be719130c5db21ff1e700d67501",
+ "0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801",
"0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
"",
"P2PK"
],
[
- "0x47 0x3044022069d40999786aeb2fd874f9eb2636461a062dc963471627ed8390a3a5f9556f640220350132a52415ce622f2aadd07f791c591500917ec1f8c5edbc5381ef7942534d01 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508",
+ "0x47 0x304402206e05a6fe23c59196ffe176c9ddc31e73a9885638f9d1328d47c0c703863b8876022076feb53811aa5b04e0e79f938eb19906cc5e67548bc555a8e8b8b0fc603d840c01 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508",
"DUP HASH160 0x14 0x1018853670f9f3b0582c5b9ee8ce93764ac32b93 EQUALVERIFY CHECKSIG",
"",
"P2PKH"
],
[
- "0x47 0x30440220519f2a6632ffa134c7811ea2819e9dcc951f0c7baf461f2dffdd09133f3b080a02203ec6bab5eb6619ed7f41b8701d7c6d70cfc83bb26c5c97f54b2ca6e304fc2bb581",
+ "0x47 0x304402204710a85181663b32d25c70ec2bbd14adff5ddfff6cb50d09e155ef5f541fc86c0220056b0cc949be9386ecc5f6c2ac0493269031dbb185781db90171b54ac127790281",
"0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG",
"",
"P2PK anyonecanpay"
],
[
- "0x47 0x30440220279dad2170ffb5639f0a1ea71fc462ee37d75d420d86f84c978bac523c09b7f20220683b2789f5c5528a9e0a0d78f6e40db3f616cf1adb5a5fdef117d5974795cfe201 0x23 0x210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac",
+ "0x47 0x304402202166fcd5e607de452d3c6f15e059505cf21654346592f9650ba906b9e8be88fa022005d976d28eb8de477102feba28807b3ad361e7fa24796d259c9d61452f7c318c01 0x23 0x210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac",
"HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL",
"P2SH",
"P2SH(P2PK)"
],
[
- "0x47 0x3044022066acbfb5ac96b7cbf3f05a2aaf358c32438c45d1d7359dee9fc1ee636940735f02205606a03fd8cbf6a6fcbcba60c8abb1e385c0b5753cb57a97538159106fd3684e01 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac",
+ "0x47 0x3044022064cc90ca89ad721384b231653b945579359a24b928ef8539b331172628c9cc6102203e238869ab5dac3fc293db53c12e7dd3079e86cfde9024b689efc7227e4d671001 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac",
"HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL",
"",
"P2SH(P2PKH), bad sig but no VERIFY_P2SH"
],
[
- "0 0x47 0x3044022004e791dd30a64c70e55e84e150c002af9feb3ce0ab1f20e86c53d1209003927502205a60453987fcd72aebaaacebc8ce4b15449cdd79e54cc82cefb83e69dbcfeabf01 0x47 0x304402201d021808ce93dd8574cc4f99ae4f11b44305528b0aecbd9f156f08315173643802200944a0ea5c884bd86180aef76d8b1e444860776b251e47d2d6c651a1c6f9930801 0x47 0x30440220446336d7b7de05ebb5683b82b05248ec7d78e88ae8d6125985f5776c887a4cf90220674ab2b2c2f954ba1cf35457d273c90d0c0c1c224d0ae128628740e81129486801",
+ "0 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402206d32e6d6b131ef2fe77b6a9b90b120d74e3e238e79dcffb10523a6ec94f93d65022067ae8772632ddf4c389258c6b70ed0ff94f20ee8f60207aa192a52a2469cddd901 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901",
"3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG",
"",
"3-of-3"
],
[
- "0 0x47 0x30440220288b06d057cf0eac434ed0c3be9257cc0ca144dd99c11cc8f1a49467a37d8e8002203c496c72253c528e6bc81c42e683aba974d46041a96ef7b00915c863eb2a702901 0x47 0x304402207ffb4da33f40cac839a43000a187bd76a1ee5bf95e46dc1534b38bb7bd0321db022038c078f29d1831f8eb68ffdc2634c654fb01c3467b6457b98ad220653bb2478501 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae",
+ "0 0x47 0x304402205b7d2c2f177ae76cfbbf14d589c113b0b35db753d305d5562dd0b61cbf366cfb02202e56f93c4f08a27f986cd424ffc48a462c3202c4902104d4d0ff98ed28f4bf8001 0x47 0x304402204511cf05e85c2be07c6c176c5338a08ed3cb34212667f39613340881169986c002207cc48b27aa3691a20706a5773ec9923cadd20fedffd00c24457d85f83f0b51fe01 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae",
"HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL",
"P2SH",
"P2SH(2-of-3)"
],
[
- "0x47 0x30440220001fff8863c84c0efc8eea5bffb7f388313f966f23a00ad3c0acc30ff5339684022016e6d78f51a3a1c362745931ca40b24f71cba2903dbfe5a6d392a9189127d83701",
+ "0x47 0x30440220001d6702bfa4f49c3a2542af9b1c2844a2eaac55f86f310f42d26a5dd17d6a8002202cdadbe608c00b50dd951c6ba0877d5b07a970f3e265c18697bc413a0a86f69901",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
"",
"P2PK with too much R padding but no DERSIG"
],
[
- "0x48 0x304502202323d56f293842b544cacedd06baafb999196dfa1c2975314848c158ac606655022100514bd98186b8a3a1cc87f4aff76aed797781389f13f50d87bf95b2df6e488fcc01",
+ "0x48 0x304502207d2b258e959605e2ea50b46fea1325b7391ffb0c14a5b58ef8ad3851da3644380221007e75136df5f2e38216c4338b31c97e8307102edb97d611e06914e1f8fba68ead01",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
"",
"P2PK with too much S padding but no DERSIG"
],
[
- "0x47 0x30440220d31c24bb6c08a496e7698a08fd41975115d7b55bfaa31cb2d573e09481e59a6702206a691239996434076b78a4e1cf46fc8e993b468a9c77fb1832186aa8040a61a201",
+ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201",
"0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
"",
"P2PK with too little R padding but no DERSIG"
],
[
- "0x47 0x30440220007c2cc7aef1801c2937447703c87ef2a3744209ad98da2abadd4ba8bb2e3ea00220503a275582c9f9e9ff30260c81b7f64b8b696f22105605cc8241fb76a797316201",
+ "0x47 0x30440220003040725f724b0e2142fc44ac71f6e13161f6410aeb6dee477952ede3b6a6ca022041ff4940ee3d88116ad281d7cc556e1f2c9427d82290bd7974a25addbcd5bede01",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT",
"",
"P2PK NOT with bad sig with too much R padding but no DERSIG"
],
[
- "0x48 0x3045022021bf9184d94f208ac9f4757ebca9b1cbebf008cfc244fe5be1360b1b9aba0e92022100e55074f72f3a1bfddf2ea4ea7ba984f78822e136fe04c8f9c1363238e0233bd801",
+ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG",
+ "",
+ "BIP66 example 1, without DERSIG"
+],
+[
+ "0",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "",
+ "BIP66 example 4, without DERSIG"
+],
+[
+ "0",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "DERSIG",
+ "BIP66 example 4, with DERSIG"
+],
+[
+ "1",
+ "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT",
+ "",
+ "BIP66 example 6, without DERSIG"
+],
+[
+ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x304402200b3d0b0375bb15c14620afa4aa10ae90a0d6a046ce217bc20fe0bc1ced68c1b802204b550acab90ae6d3478057c9ad24f9df743815b799b6449dd7e7f6d3bc6e274c01",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG",
+ "",
+ "BIP66 example 7, without DERSIG"
+],
+[
+ "0 0 0x47 0x30440220afa76a8f60622f813b05711f051c6c3407e32d1b1b70b0576c1f01b54e4c05c702200d58e9df044fd1845cabfbeef6e624ba0401daf7d7e084736f9ff601c3783bf501",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "",
+ "BIP66 example 10, without DERSIG"
+],
+[
+ "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "",
+ "BIP66 example 12, without DERSIG"
+],
+[
+ "0 0x47 0x30440220f00a77260d34ec2f0c59621dc710f58169d0ca06df1a88cd4b1f1b97bd46991b02201ee220c7e04f26aed03f94aa97fb09ca5627163bf4ba07e6979972ec737db22601 0",
+ "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT",
+ "DERSIG",
+ "BIP66 example 12, with DERSIG"
+],
+[
+ "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
- "STRICTENC",
+ "",
+ "P2PK with multi-byte hashtype, without DERSIG"
+],
+[
+ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
+ "",
"P2PK with high S but no LOW_S"
],
[
- "0x47 0x304402202163bc732c21b7de0251297d3c6c2ece182782e85fc5e19d6036f1130a79051e022033827811634924ebba68767537d78dd7bd9109ae2a89a60587927abdc25eb06401",
+ "0x47 0x30440220745d63eb70d45652128b450aa5ca7d9b513439963f261cb1c40a60f0785e7ee402204877785b38945ca9dbec78e1c1d4dd12148cc25c868bd27480023b49ae0f310501",
"0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
"",
"P2PK with hybrid pubkey but no STRICTENC"
],
[
- "0x47 0x3044022078d6c447887e88dcbe1bc5b613645280df6f4e5935648bc226e9d91da71b3216022047d6b7ef0949b228fc1b359afb8d50500268711354298217b983c26970790c7601",
+ "0x47 0x30440220606f6f9f6cebc84ebfb6a4bff0b682bd99f05511295545ce9b275e98be3c946102206871d6a76f4e1b43d9763cfc5647844e4811682b1cab0325f060f44ddf44002201",
"0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT",
"",
"P2PK NOT with invalid hybrid pubkey but no STRICTENC"
],
[
- "0 0x47 0x304402203b269b9fbc0936877bf855b5fb41757218d9548b246370d991442a5f5bd1c3440220235268a4eaa8c67e543c6e37da81dd36d3b1be2de6b4fef04113389ca6ddc04501",
+ "0 0x47 0x304402203a5ee39032637c431af0a3ac42e32e0627390bd44f6f98c9c04e6d714635ad0202207b42fcd889c3ae8a1b515608f38535f1f9be815176ee8d1b65a27c767cf37aed01",
"1 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG",
"",
"1-of-2 with the second 1 hybrid pubkey and no STRICTENC"
],
[
- "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501",
+ "0 0x47 0x304402203a5ee39032637c431af0a3ac42e32e0627390bd44f6f98c9c04e6d714635ad0202207b42fcd889c3ae8a1b515608f38535f1f9be815176ee8d1b65a27c767cf37aed01",
"1 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG",
"STRICTENC",
"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",
+ "0x47 0x304402201c215cb13e4954e60ce4f6de74941904c771f998de7b1d9627e82a1949fde517022031c2197455f3dbecbb78321201308d7b039424e38d480772d7cd4eb465a083f405",
"0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG",
"",
"P2PK with undefined hashtype but no STRICTENC"
],
[
- "0x47 0x304402207f1cf1866a2df0bb4b8d84d0ade72aa3abb6aaab0639d608b23d9e10ead0c48202203caa97f22c3439443eea4b89f7f6729854df0f567a8184d6ecc6e8b6c68c3e9d05",
+ "0x47 0x304402207409b5b320296e5e2136a7b281a7f803028ca4ca44e2b83eebd46932677725de02202d4eea1c8d3c98e6f42614f54764e6e5e6542e213eb4d079737e9a8b6e9812ec05",
"0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT",
"",
"P2PK NOT with invalid sig and undefined hashtype but no STRICTENC"
],
[
- "1 0x47 0x3044022046ce33d1771b0127dd4c4cef8fdc3218ebdfa60e3793ed700292d8ebd93fb1f402201029d47a414db83e96e31443c2d8b552f971469c4800f5eff7df2f0648521aed01 0x47 0x304402205c53911ad55b054920043962bbda98cf6e57e2db1cd5611138251490baabaa8702201dc80dfceae6007e7772dc13ff6e7ca66a983cb017fe5d46d30118462d83bcf801 0x47 0x304402201937e44a4ec12364f9d32f9d25e7ecbc68aee9ef90069af80efef4c05f6ace9602206c515101c00c75710b32ff7ff8dbaf7c9a0be6e86ed14a0755b47626604f31fd01",
+ "1 0x47 0x3044022051254b9fb476a52d85530792b578f86fea70ec1ffb4393e661bcccb23d8d63d3022076505f94a403c86097841944e044c70c2045ce90e36de51f7e9d3828db98a07501 0x47 0x304402206d32e6d6b131ef2fe77b6a9b90b120d74e3e238e79dcffb10523a6ec94f93d65022067ae8772632ddf4c389258c6b70ed0ff94f20ee8f60207aa192a52a2469cddd901 0x47 0x304402200955d031fff71d8653221e85e36c3c85533d2312fc3045314b19650b7ae2f81002202a6bb8505e36201909d0921f01abff390ae6b7ff97bbf959f98aedeb0a56730901",
"3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG",
"",
"3-of-3 with nonzero dummy but no NULLDUMMY"
],
[
- "1 0x47 0x30440220195038dbc6b2ae1199f86a6777824f7c5149789d85f655a3534a4422b8fba38c02204df9db87d2eb9fe06edc66870d9ac4c9ce673459f9d43cee0347ce4ffb02ee5a01 0x47 0x3044022010a45f30c6fa97a186eba9e6b595ab87d3dfcbf05dcaf1f1b8e3e7bf39515bb802203474e78d3d372e5f5c0f8c257ce8300c4bb8f37c51d4a894e11a91b5817da6ed01 0x47 0x30440220039cffd8e39850f95112662b1220b14b3c0d3d8a2772e13c947bfbf96345a64e02204154bfa77e2c0134d5434353bed82141e5da1cc479954aa288d5f0671480a04b01",
+ "1 0x47 0x304402201bb2edab700a5d020236df174fefed78087697143731f659bea59642c759c16d022061f42cdbae5bcd3e8790f20bf76687443436e94a634321c16a72aa54cbc7c2ea01 0x47 0x304402204bb4a64f2a6e5c7fb2f07fef85ee56fde5e6da234c6a984262307a20e99842d702206f8303aaba5e625d223897e2ffd3f88ef1bcffef55f38dc3768e5f2e94c923f901 0x47 0x3044022040c2809b71fffb155ec8b82fe7a27f666bd97f941207be4e14ade85a1249dd4d02204d56c85ec525dd18e29a0533d5ddf61b6b1bb32980c2f63edf951aebf7a27bfe01",
"3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG NOT",
"",
"3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY"
],
[
- "0 0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01 DUP",
+ "0 0x47 0x304402206cb053202e1501e6faa24e6e309bf46a2f9255aa9484ff4a26efb7434f78a58a0220132b10419c3b99601f154bf86cf12259aacd8c6f363a73dacb1d0b941680bb4c01 DUP",
"2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG",
"",
"2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY"
],
[
- "0 0x47 0x304402203acf75dd59bbef171aeeedae4f1020b824195820db82575c2b323b8899f95de9022067df297d3a5fad049ba0bb81255d0e495643cbcf9abae9e396988618bc0c6dfe01 0x47 0x304402205f8b859230c1cab7d4e8de38ff244d2ebe046b64e8d3f4219b01e483c203490a022071bdc488e31b557f7d9e5c8a8bec90dc92289ca70fa317685f4f140e38b30c4601",
+ "0 0x47 0x304402206cb053202e1501e6faa24e6e309bf46a2f9255aa9484ff4a26efb7434f78a58a0220132b10419c3b99601f154bf86cf12259aacd8c6f363a73dacb1d0b941680bb4c01 0x47 0x304402206cb053202e1501e6faa24e6e309bf46a2f9255aa9484ff4a26efb7434f78a58a0220132b10419c3b99601f154bf86cf12259aacd8c6f363a73dacb1d0b941680bb4c01",
"2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG",
"SIGPUSHONLY",
"2-of-2 with two identical keys and sigs pushed"
],
+[
+ "11 0x47 0x3044022053205076a7bb13d2db3162a2d97d8197631f829b065948b7019b15482af819a902204328dcc02c994ca086b1226d0d5f1674d23cfae0d846143df812b81cab3391e801",
+ "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG",
+ "P2SH",
+ "P2PK with unnecessary input but no CLEANSTACK"
+],
+[
+ "11 0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
+ "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL",
+ "P2SH",
+ "P2SH with unnecessary input but no CLEANSTACK"
+],
+[
+ "0x47 0x304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f01 0x43 0x410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac",
+ "HASH160 0x14 0x31edc23bdafda4639e669f89ad6b2318dd79d032 EQUAL",
+ "CLEANSTACK,P2SH",
+ "P2SH with CLEANSTACK"
+],
["The End"]
]
+++ /dev/null
-[
- "300602010002010001",
- "3008020200ff020200ff01",
- "304402203932c892e2e550f3af8ee4ce9c215a87f9bb831dcac87b2838e2c2eaa891df0c022030b61dd36543125d56b9f9f3a1f9353189e5af33cdda8d77a5209aec03978fa001",
- "30450220076045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a0221008fffd599910eefe00bc803c688c2eca1d2ba7f6b180620eaa03488e6585db6ba01",
- "3046022100876045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a0221008fffd599910eefe00bc803c688c2eca1d2ba7f6b180620eaa03488e6585db6ba01"
-]
+++ /dev/null
-[
- "non-hex strings are ignored",
-
- "too short:", "30050201FF020001",
- "too long:", "30470221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105022200002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "hashtype:", "304402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed11",
- "type:", "314402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "total length:", "304502205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "S len oob:", "301F01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb101",
- "R+S:", "304502205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed0001",
-
- "R type:", "304401205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "R len = 0:", "3024020002202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "R<0:", "304402208990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "R padded:", "30450221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610502202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
-
-
- "S type:", "304402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba610501202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "S len = 0:", "302402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105020001",
- "S<0:", "304402205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61050220fd5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01",
- "S padded:", "304502205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61050221002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed01"
-]
[[["ad503f72c18df5801ee64d76090afe4c607fb2b822e9b7b63c5826c50e22fc3b", 0, "0x21 0x027c3a97665bf283a102a587a62a30a0c102d4d3b141015e2cae6f64e2543113e5 CHECKSIG NOT"]],
"01000000013bfc220ec526583cb6b7e922b8b27f604cfe0a09764de61e80f58dc1723f50ad0000000000ffffffff0101000000000000002321027c3a97665bf283a102a587a62a30a0c102d4d3b141015e2cae6f64e2543113e5ac00000000", "P2SH"],
+
+["Inverted versions of tx_valid CODESEPARATOR IF block tests"],
+
+["CODESEPARATOR in an unexecuted IF block does not change what is hashed"],
+[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]],
+"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a48304502207a6974a77c591fa13dff60cabbb85a0de9e025c09c65a4b2285e47ce8e22f761022100f0efaac9ff8ac36b10721e0aae1fb975c90500b50c56e8a0cc52b0403f0425dd0151ffffffff010000000000000000016a00000000", "P2SH"],
+
+["As above, with the IF block executed"],
+[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]],
+"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a483045022100fa4a74ba9fd59c59f46c3960cf90cbe0d2b743c471d24a3d5d6db6002af5eebb02204d70ec490fd0f7055a7c45f86514336e3a7f03503dacecabb247fc23f15c83510100ffffffff010000000000000000016a00000000", "P2SH"],
+
+
["Make diffs cleaner by leaving a comment here without comma at the end"]
]
[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIGVERIFY CODESEPARATOR 0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIGVERIFY CODESEPARATOR 1"]],
"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a900000000924830450221009c0a27f886a1d8cb87f6f595fbc3163d28f7a81ec3c4b252ee7f3ac77fd13ffa02203caa8dfa09713c8c4d7ef575c75ed97812072405d932bd11e6a1593a98b679370148304502201e3861ef39a526406bad1e20ecad06be7375ad40ddb582c9be42d26c3a0d7b240221009d0a3985e96522e59635d19cc4448547477396ce0ef17a58e7d74c3ef464292301ffffffff010000000000000000016a00000000", "P2SH"],
+["CODESEPARATOR in an unexecuted IF block does not change what is hashed"],
+[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]],
+"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a48304502207a6974a77c591fa13dff60cabbb85a0de9e025c09c65a4b2285e47ce8e22f761022100f0efaac9ff8ac36b10721e0aae1fb975c90500b50c56e8a0cc52b0403f0425dd0100ffffffff010000000000000000016a00000000", "P2SH"],
+
+["As above, with the IF block executed"],
+[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]],
+"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a483045022100fa4a74ba9fd59c59f46c3960cf90cbe0d2b743c471d24a3d5d6db6002af5eebb02204d70ec490fd0f7055a7c45f86514336e3a7f03503dacecabb247fc23f15c83510151ffffffff010000000000000000016a00000000", "P2SH"],
+
+
["CHECKSIG is legal in scriptSigs"],
[[["ccf7f4053a02e653c36ac75c891b7496d0dc5ce5214f6c913d9cf8f1329ebee0", 0, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]],
"0100000001e0be9e32f1f89c3d916c4f21e55cdcd096741b895cc76ac353e6023a05f4f7cc00000000d86149304602210086e5f736a2c3622ebb62bd9d93d8e5d76508b98be922b97160edc3dcca6d8c47022100b23c312ac232a4473f19d2aeb95ab7bdf2b65518911a0d72d50e38b5dd31dc820121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ac4730440220508fa761865c8abd81244a168392876ee1d94e8ed83897066b5e2df2400dad24022043f5ee7538e87e9c6aef7ef55133d3e51da7cc522830a9c4d736977a76ef755c0121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH"],
--- /dev/null
+01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d0000000000ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000
// Copyright (c) 2012-2013 The Bitcoin Core 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 "util.h"
+#include "test/test_bitcoin.h"
#include <string>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(getarg_tests)
+BOOST_FIXTURE_TEST_SUITE(getarg_tests, BasicTestingSetup)
static void ResetArgs(const std::string& strArg)
{
// Copyright (c) 2013 The Bitcoin Core 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 "hash.h"
#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <vector>
using namespace std;
-BOOST_AUTO_TEST_SUITE(hash_tests)
+BOOST_FIXTURE_TEST_SUITE(hash_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(murmurhash3)
{
// Copyright (c) 2012-2013 The Bitcoin Core 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 "key.h"
#include "script/script.h"
#include "uint256.h"
#include "util.h"
+#include "utilstrencodings.h"
+#include "test/test_bitcoin.h"
#include <string>
#include <vector>
#endif
-BOOST_AUTO_TEST_SUITE(key_tests)
+BOOST_FIXTURE_TEST_SUITE(key_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(key_test1)
{
BOOST_CHECK(rkey1C == pubkey1C);
BOOST_CHECK(rkey2C == pubkey2C);
}
+
+ // test deterministic signing
+
+ std::vector<unsigned char> detsig, detsigc;
+ string strMsg = "Very deterministic message";
+ uint256 hashMsg = Hash(strMsg.begin(), strMsg.end());
+ BOOST_CHECK(key1.Sign(hashMsg, detsig));
+ BOOST_CHECK(key1C.Sign(hashMsg, detsigc));
+ BOOST_CHECK(detsig == detsigc);
+ BOOST_CHECK(detsig == ParseHex("304402205dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2d377bbe59d31d022014ddda21494a4e221f0824f0b8b924c43fa43c0ad57dccdaa11f81a6bd4582f6"));
+ BOOST_CHECK(key2.Sign(hashMsg, detsig));
+ BOOST_CHECK(key2C.Sign(hashMsg, detsigc));
+ BOOST_CHECK(detsig == detsigc);
+ BOOST_CHECK(detsig == ParseHex("3044022052d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2bfa8ac9dc1cd5022061d8ae5e0f6c1a16bde3719c64c2fd70e404b6428ab9a69566962e8771b5944d"));
+ BOOST_CHECK(key1.SignCompact(hashMsg, detsig));
+ BOOST_CHECK(key1C.SignCompact(hashMsg, detsigc));
+ BOOST_CHECK(detsig == ParseHex("1c5dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2d377bbe59d31d14ddda21494a4e221f0824f0b8b924c43fa43c0ad57dccdaa11f81a6bd4582f6"));
+ BOOST_CHECK(detsigc == ParseHex("205dbbddda71772d95ce91cd2d14b592cfbc1dd0aabd6a394b6c2d377bbe59d31d14ddda21494a4e221f0824f0b8b924c43fa43c0ad57dccdaa11f81a6bd4582f6"));
+ BOOST_CHECK(key2.SignCompact(hashMsg, detsig));
+ BOOST_CHECK(key2C.SignCompact(hashMsg, detsigc));
+ BOOST_CHECK(detsig == ParseHex("1c52d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2bfa8ac9dc1cd561d8ae5e0f6c1a16bde3719c64c2fd70e404b6428ab9a69566962e8771b5944d"));
+ BOOST_CHECK(detsigc == ParseHex("2052d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2bfa8ac9dc1cd561d8ae5e0f6c1a16bde3719c64c2fd70e404b6428ab9a69566962e8771b5944d"));
}
BOOST_AUTO_TEST_SUITE_END()
// Copyright (c) 2014 The Bitcoin Core 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 "core/transaction.h"
+#include "primitives/transaction.h"
#include "main.h"
+#include "test/test_bitcoin.h"
+
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(main_tests)
+BOOST_FIXTURE_TEST_SUITE(main_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(subsidy_limit_test)
{
BOOST_CHECK(nSum == 2099999997690000ULL);
}
+bool ReturnFalse() { return false; }
+bool ReturnTrue() { return true; }
+
+BOOST_AUTO_TEST_CASE(test_combiner_all)
+{
+ boost::signals2::signal<bool (), CombinerAll> Test;
+ BOOST_CHECK(Test());
+ Test.connect(&ReturnFalse);
+ BOOST_CHECK(!Test());
+ Test.connect(&ReturnTrue);
+ BOOST_CHECK(!Test());
+ Test.disconnect(&ReturnFalse);
+ BOOST_CHECK(Test());
+ Test.disconnect(&ReturnTrue);
+ BOOST_CHECK(Test());
+}
+
BOOST_AUTO_TEST_SUITE_END()
// Copyright (c) 2011-2014 The Bitcoin Core 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 "main.h"
#include "uint256.h"
#include "util.h"
+#include "test/test_bitcoin.h"
+
#include <boost/test/unit_test.hpp>
-BOOST_AUTO_TEST_SUITE(miner_tests)
+BOOST_FIXTURE_TEST_SUITE(miner_tests, TestingSetup)
static
struct {
// Copyright (c) 2012-2013 The Bitcoin Core 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 "mruset.h"
#include "random.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#include <set>
}
};
-BOOST_AUTO_TEST_SUITE(mruset_tests)
+BOOST_FIXTURE_TEST_SUITE(mruset_tests, BasicTestingSetup)
// Test that an mruset behaves like a set, as long as no more than MAX_SIZE elements are in it
BOOST_AUTO_TEST_CASE(mruset_like_set)
// Copyright (c) 2011-2013 The Bitcoin Core 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 "key.h"
#include "script/interpreter.h"
#include "script/sign.h"
#include "uint256.h"
+#include "test/test_bitcoin.h"
#ifdef ENABLE_WALLET
#include "wallet_ismine.h"
#endif
-#include <boost/assign/std/vector.hpp>
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
using namespace std;
-using namespace boost::assign;
typedef vector<unsigned char> valtype;
-BOOST_AUTO_TEST_SUITE(multisig_tests)
+BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
CScript
sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, int whichIn)
CScript s;
// Test a AND b:
- keys.clear();
- keys += key[0],key[1]; // magic operator+= from boost.assign
+ keys.assign(1,key[0]);
+ keys.push_back(key[1]);
s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK(VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err));
+ BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
for (int i = 0; i < 4; i++)
{
- keys.clear();
- keys += key[i];
+ keys.assign(1,key[i]);
s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err), strprintf("a&b 1: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 1: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
- keys.clear();
- keys += key[1],key[i];
+ keys.assign(1,key[1]);
+ keys.push_back(key[i]);
s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0), &err), strprintf("a&b 2: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 2: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
// Test a OR b:
for (int i = 0; i < 4; i++)
{
- keys.clear();
- keys += key[i];
+ keys.assign(1,key[i]);
s = sign_multisig(a_or_b, keys, txTo[1], 0);
if (i == 0 || i == 1)
{
- BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i));
+ BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
else
{
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err), strprintf("a|b: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
}
s.clear();
- s << OP_0 << OP_0;
- BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err));
- BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
- s.clear();
s << OP_0 << OP_1;
- BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0), &err));
+ BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
{
- keys.clear();
- keys += key[i],key[j];
+ keys.assign(1,key[i]);
+ keys.push_back(key[j]);
s = sign_multisig(escrow, keys, txTo[2], 0);
if (i < j && i < 3 && j < 3)
{
- BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j));
+ BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
else
{
- BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
}
// Copyright (c) 2012-2013 The Bitcoin Core 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 "netbase.h"
+#include "test/test_bitcoin.h"
#include <string>
using namespace std;
-BOOST_AUTO_TEST_SUITE(netbase_tests)
+BOOST_FIXTURE_TEST_SUITE(netbase_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(netbase_networks)
{
// Copyright (c) 2012-2013 The Bitcoin Core 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 "main.h"
+#include "merkleblock.h"
#include "serialize.h"
+#include "streams.h"
#include "uint256.h"
+#include "arith_uint256.h"
+#include "version.h"
+#include "random.h"
+#include "test/test_bitcoin.h"
#include <vector>
+#include <boost/assign/list_of.hpp>
#include <boost/test/unit_test.hpp>
using namespace std;
public:
// flip one bit in one of the hashes - this should break the authentication
void Damage() {
- unsigned int n = rand() % vHash.size();
- int bit = rand() % 256;
- uint256 &hash = vHash[n];
- hash ^= ((uint256)1 << bit);
+ unsigned int n = insecure_rand() % vHash.size();
+ int bit = insecure_rand() % 256;
+ *(vHash[n].begin() + (bit>>3)) ^= 1<<(bit&7);
}
};
-BOOST_AUTO_TEST_SUITE(pmt_tests)
+BOOST_FIXTURE_TEST_SUITE(pmt_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(pmt_test1)
{
+ seed_insecure_rand(false);
static const unsigned int nTxCounts[] = {1, 4, 7, 17, 56, 100, 127, 256, 312, 513, 1000, 4095};
for (int n = 0; n < 12; n++) {
CBlock block;
for (unsigned int j=0; j<nTx; j++) {
CMutableTransaction tx;
- tx.nLockTime = rand(); // actual transaction data doesn't matter; just make the nLockTime's unique
+ tx.nLockTime = j; // actual transaction data doesn't matter; just make the nLockTime's unique
block.vtx.push_back(CTransaction(tx));
}
// calculate actual merkle root and height
uint256 merkleRoot1 = block.BuildMerkleTree();
- std::vector<uint256> vTxid(nTx, 0);
+ std::vector<uint256> vTxid(nTx, uint256());
for (unsigned int j=0; j<nTx; j++)
vTxid[j] = block.vtx[j].GetHash();
int nHeight = 1, nTx_ = nTx;
std::vector<bool> vMatch(nTx, false);
std::vector<uint256> vMatchTxid1;
for (unsigned int j=0; j<nTx; j++) {
- bool fInclude = (rand() & ((1 << (att/2)) - 1)) == 0;
+ bool fInclude = (insecure_rand() & ((1 << (att/2)) - 1)) == 0;
vMatch[j] = fInclude;
if (fInclude)
vMatchTxid1.push_back(vTxid[j]);
// check that it has the same merkle root as the original, and a valid one
BOOST_CHECK(merkleRoot1 == merkleRoot2);
- BOOST_CHECK(merkleRoot2 != 0);
+ BOOST_CHECK(!merkleRoot2.IsNull());
// check that it contains the matched transactions (in the same order!)
BOOST_CHECK(vMatchTxid1 == vMatchTxid2);
}
}
+BOOST_AUTO_TEST_CASE(pmt_malleability)
+{
+ std::vector<uint256> vTxid = boost::assign::list_of
+ (ArithToUint256(1))(ArithToUint256(2))
+ (ArithToUint256(3))(ArithToUint256(4))
+ (ArithToUint256(5))(ArithToUint256(6))
+ (ArithToUint256(7))(ArithToUint256(8))
+ (ArithToUint256(9))(ArithToUint256(10))
+ (ArithToUint256(9))(ArithToUint256(10));
+ std::vector<bool> vMatch = boost::assign::list_of(false)(false)(false)(false)(false)(false)(false)(false)(false)(true)(true)(false);
+
+ CPartialMerkleTree tree(vTxid, vMatch);
+ std::vector<uint256> vTxid2;
+ BOOST_CHECK(tree.ExtractMatches(vTxid).IsNull());
+}
+
BOOST_AUTO_TEST_SUITE_END()
--- /dev/null
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "main.h"
+#include "pow.h"
+#include "util.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup)
+
+/* Test calculation of next difficulty target with no constraints applying */
+BOOST_AUTO_TEST_CASE(get_next_work)
+{
+ SelectParams(CBaseChainParams::MAIN);
+
+ int64_t nLastRetargetTime = 1261130161; // Block #30240
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 32255;
+ pindexLast.nTime = 1262152739; // Block #32255
+ pindexLast.nBits = 0x1d00ffff;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00d86a);
+}
+
+/* Test the constraint on the upper bound for next work */
+BOOST_AUTO_TEST_CASE(get_next_work_pow_limit)
+{
+ SelectParams(CBaseChainParams::MAIN);
+
+ int64_t nLastRetargetTime = 1231006505; // Block #0
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 2015;
+ pindexLast.nTime = 1233061996; // Block #2015
+ pindexLast.nBits = 0x1d00ffff;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00ffff);
+}
+
+/* Test the constraint on the lower bound for actual time taken */
+BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual)
+{
+ SelectParams(CBaseChainParams::MAIN);
+
+ int64_t nLastRetargetTime = 1279008237; // Block #66528
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 68543;
+ pindexLast.nTime = 1279297671; // Block #68543
+ pindexLast.nBits = 0x1c05a3f4;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1c0168fd);
+}
+
+/* Test the constraint on the upper bound for actual time taken */
+BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 46367;
+ pindexLast.nTime = 1269211443; // Block #46367
+ pindexLast.nBits = 0x1c387f6f;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00e1fd);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
// Copyright (c) 2012-2013 The Bitcoin Core 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"
#include "base58.h"
#include "netbase.h"
+#include "test/test_bitcoin.h"
+
#include <boost/algorithm/string.hpp>
#include <boost/test/unit_test.hpp>
Value result = (*method)(params, false);
return result;
}
- catch (Object& objError)
- {
+ catch (const Object& objError) {
throw runtime_error(find_value(objError, "message").get_str());
}
}
-BOOST_AUTO_TEST_SUITE(rpc_tests)
+BOOST_FIXTURE_TEST_SUITE(rpc_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(rpc_rawparams)
{
// Copyright (c) 2013-2014 The Bitcoin Core 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"
#include "base58.h"
#include "wallet.h"
+#include "test/test_bitcoin.h"
+
#include <boost/algorithm/string.hpp>
#include <boost/test/unit_test.hpp>
extern CWallet* pwalletMain;
-BOOST_AUTO_TEST_SUITE(rpc_wallet_tests)
+BOOST_FIXTURE_TEST_SUITE(rpc_wallet_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(rpc_addmultisig)
{
/* 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X (33 chars) is an illegal address (should be 34 chars) */
BOOST_CHECK_THROW(CallRPC("setaccount 1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4X nullaccount"), runtime_error);
+
+ /*********************************
+ * getbalance
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("getbalance"));
+ BOOST_CHECK_NO_THROW(CallRPC("getbalance " + demoAddress.ToString()));
+
/*********************************
* listunspent
*********************************/
BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0 true"));
BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 true extra"), runtime_error);
+ /*********************************
+ * listsinceblock
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listsinceblock"));
+
+ /*********************************
+ * listtransactions
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions"));
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString()));
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20"));
+ BOOST_CHECK_NO_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " 20 0"));
+ BOOST_CHECK_THROW(CallRPC("listtransactions " + demoAddress.ToString() + " not_int"), runtime_error);
+
+ /*********************************
+ * listlockunspent
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listlockunspent"));
+
+ /*********************************
+ * listaccounts
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listaccounts"));
+
+ /*********************************
+ * listaddressgroupings
+ *********************************/
+ BOOST_CHECK_NO_THROW(CallRPC("listaddressgroupings"));
+
/*********************************
* getrawchangeaddress
*********************************/
BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get());
}
-
BOOST_AUTO_TEST_SUITE_END()
--- /dev/null
+// Copyright (c) 2012-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "compat/sanity.h"
+#include "key.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(sanity_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(basic_sanity)
+{
+ BOOST_CHECK_MESSAGE(glibc_sanity_test() == true, "libc sanity test");
+ BOOST_CHECK_MESSAGE(glibcxx_sanity_test() == true, "stdlib sanity test");
+ BOOST_CHECK_MESSAGE(ECC_InitSanityCheck() == true, "openssl ECC test");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
// Copyright (c) 2012-2013 The Bitcoin Core 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 "key.h"
#include "script/script.h"
#include "script/script_error.h"
#include "script/sign.h"
+#include "test/test_bitcoin.h"
#ifdef ENABLE_WALLET
#include "wallet_ismine.h"
txTo.vin[0].scriptSig = scriptSig;
txTo.vout[0].nValue = 1;
- return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, SignatureChecker(txTo, 0), &err);
+ return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0), &err);
}
-BOOST_AUTO_TEST_SUITE(script_P2SH_tests)
+BOOST_FIXTURE_TEST_SUITE(script_P2SH_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(sign)
{
BOOST_AUTO_TEST_CASE(is)
{
// Test CScript::IsPayToScriptHash()
- uint160 dummy(0);
+ uint160 dummy;
CScript p2sh;
p2sh << OP_HASH160 << ToByteVector(dummy) << OP_EQUAL;
BOOST_CHECK(p2sh.IsPayToScriptHash());
#include "script/script_error.h"
#include "script/sign.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#if defined(HAVE_CONSENSUS_LIB)
#include "script/bitcoinconsensus.h"
#include <string>
#include <vector>
-#include <boost/algorithm/string/classification.hpp>
-#include <boost/algorithm/string/predicate.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <boost/algorithm/string/split.hpp>
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
#include "json/json_spirit_reader_template.h"
using namespace std;
using namespace json_spirit;
-using namespace boost::algorithm;
// Uncomment if you want to output updated JSON tests.
// #define UPDATE_JSON_TESTS
return v.get_array();
}
-BOOST_AUTO_TEST_SUITE(script_tests)
+BOOST_FIXTURE_TEST_SUITE(script_tests, BasicTestingSetup)
CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
{
ScriptError err;
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(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&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);
std::vector<unsigned char> r, s;
r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
- unsigned char hashtype = vchSig.back();
// Really ugly to implement mod-n negation here, but it would be feature creep to expose such functionality from libsecp256k1.
static const unsigned char order[33] = {
vchSig.push_back(0x02);
vchSig.push_back(s.size());
vchSig.insert(vchSig.end(), s.begin(), s.end());
- vchSig.push_back(hashtype);
}
namespace
{
uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType);
std::vector<unsigned char> vchSig, r, s;
+ uint32_t iter = 0;
do {
- key.Sign(hash, vchSig);
+ key.Sign(hash, vchSig, iter++);
if ((lenS == 33) != (vchSig[5 + vchSig[3]] == 33)) {
NegateSignatureS(vchSig);
}
"P2PK NOT with too much R padding", SCRIPT_VERIFY_DERSIG
).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000"));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 1, without DERSIG", 0
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 1, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 2, without DERSIG", 0
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 2, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 3, without DERSIG", 0
+ ).Num(0));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 3, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 4, without DERSIG", 0
+ ).Num(0));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 4, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 5, without DERSIG", 0
+ ).Num(1));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
+ "BIP66 example 5, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(1));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 6, without DERSIG", 0
+ ).Num(1));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
+ "BIP66 example 6, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(1));
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 7, without DERSIG", 0
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 7, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 8, without DERSIG", 0
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 8, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 9, without DERSIG", 0
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 9, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 10, without DERSIG", 0
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 10, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 11, without DERSIG", 0
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
+ "BIP66 example 11, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 12, without DERSIG", 0
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
+ "BIP66 example 12, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
+ "P2PK with multi-byte hashtype, without DERSIG", 0
+ ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
+ "P2PK with multi-byte hashtype, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101"));
+
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
"P2PK with high S but no LOW_S", 0
).PushSig(keys.key2, SIGHASH_ALL, 32, 33));
"2-of-2 with two identical keys and sigs pushed", SCRIPT_VERIFY_SIGPUSHONLY
).Num(0).PushSig(keys.key1).PushSig(keys.key1));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2PK with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH
+ ).Num(11).PushSig(keys.key0));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2PK with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH
+ ).Num(11).PushSig(keys.key0));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2SH with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH, true
+ ).Num(11).PushSig(keys.key0).PushRedeem());
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2SH with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true
+ ).Num(11).PushSig(keys.key0).PushRedeem());
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
+ "P2SH with CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true
+ ).PushSig(keys.key0).PushRedeem());
+
- std::map<std::string, Array> tests_good;
- std::map<std::string, Array> tests_bad;
+ std::set<std::string> tests_good;
+ std::set<std::string> tests_bad;
{
Array json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid)));
Array json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid)));
BOOST_FOREACH(Value& tv, json_good) {
- Array test = tv.get_array();
- if (test.size() >= 4) {
- tests_good[test[3].get_str()] = test;
- }
+ tests_good.insert(write_string(Value(tv.get_array()), true));
}
BOOST_FOREACH(Value& tv, json_bad) {
- Array test = tv.get_array();
- if (test.size() >= 4) {
- tests_bad[test[3].get_str()] = test;
- }
+ tests_bad.insert(write_string(Value(tv.get_array()), true));
}
}
BOOST_FOREACH(TestBuilder& test, good) {
test.Test(true);
- if (tests_good.count(test.GetComment()) == 0) {
+ std::string str = write_string(Value(test.GetJSON()), true);
#ifndef UPDATE_JSON_TESTS
+ if (tests_good.count(str) == 0) {
BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + test.GetComment());
-#endif
- strGood += write_string(Value(test.GetJSON()), true) + ",\n";
- } else {
- BOOST_CHECK_MESSAGE(ParseScript(tests_good[test.GetComment()][1].get_str()) == test.GetScriptPubKey(), "ScriptPubKey mismatch in auto script_valid test: " + test.GetComment());
- strGood += write_string(Value(tests_good[test.GetComment()]), true) + ",\n";
}
+#endif
+ strGood += str + ",\n";
}
BOOST_FOREACH(TestBuilder& test, bad) {
test.Test(false);
- if (tests_bad.count(test.GetComment()) == 0) {
+ std::string str = write_string(Value(test.GetJSON()), true);
#ifndef UPDATE_JSON_TESTS
+ if (tests_bad.count(str) == 0) {
BOOST_CHECK_MESSAGE(false, "Missing auto script_invalid test: " + test.GetComment());
-#endif
- strBad += write_string(Value(test.GetJSON()), true) + ",\n";
- } else {
- BOOST_CHECK_MESSAGE(ParseScript(tests_bad[test.GetComment()][1].get_str()) == test.GetScriptPubKey(), "ScriptPubKey mismatch in auto script_invalid test: " + test.GetComment());
- strBad += write_string(Value(tests_bad[test.GetComment()]), true) + ",\n";
}
+#endif
+ strBad += str + ",\n";
}
#ifdef UPDATE_JSON_TESTS
ScriptError err;
vector<vector<unsigned char> > directStack;
- BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), true, BaseSignatureChecker(), &err));
+ BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
vector<vector<unsigned char> > pushdata1Stack;
- BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), true, BaseSignatureChecker(), &err));
+ BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
BOOST_CHECK(pushdata1Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
vector<vector<unsigned char> > pushdata2Stack;
- BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), true, BaseSignatureChecker(), &err));
+ BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
BOOST_CHECK(pushdata2Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
vector<vector<unsigned char> > pushdata4Stack;
- BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), true, BaseSignatureChecker(), &err));
+ BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err));
BOOST_CHECK(pushdata4Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12);
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12);
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
txTo12.vout[0].nValue = 2;
- BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err));
+ BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12);
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12);
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
}
std::vector<CKey> keys;
keys.push_back(key1); keys.push_back(key2);
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key1); keys.push_back(key3);
CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key3);
CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear();
keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
keys.clear(); // Must have signatures
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, SignatureChecker(txTo23, 0), &err));
+ BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
}
// Copyright (c) 2012-2014 The Bitcoin Core 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 "bignum.h"
#include "script/script.h"
+#include "test/test_bitcoin.h"
+
#include <boost/test/unit_test.hpp>
#include <limits.h>
#include <stdint.h>
-BOOST_AUTO_TEST_SUITE(scriptnum_tests)
+
+BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup)
static const int64_t values[] = \
{ 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, LONG_MIN, LONG_MAX };
// Copyright (c) 2012-2013 The Bitcoin Core 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 "serialize.h"
#include "streams.h"
+#include "hash.h"
+#include "test/test_bitcoin.h"
#include <stdint.h>
using namespace std;
-BOOST_AUTO_TEST_SUITE(serialize_tests)
+BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(sizes)
+{
+ BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(char(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int8_t), GetSerializeSize(int8_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(uint8_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int16_t), GetSerializeSize(int16_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint16_t), GetSerializeSize(uint16_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int32_t), GetSerializeSize(int32_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint32_t), GetSerializeSize(uint32_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int64_t), GetSerializeSize(int64_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint64_t), GetSerializeSize(uint64_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(float), GetSerializeSize(float(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(double), GetSerializeSize(double(0), 0));
+ // Bool is serialized as char
+ BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(bool(0), 0));
+
+ // Sanity-check GetSerializeSize and c++ type matching
+ BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint16_t(0), 0), 2);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int32_t(0), 0), 4);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint32_t(0), 0), 4);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int64_t(0), 0), 8);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint64_t(0), 0), 8);
+ BOOST_CHECK_EQUAL(GetSerializeSize(float(0), 0), 4);
+ BOOST_CHECK_EQUAL(GetSerializeSize(double(0), 0), 8);
+ BOOST_CHECK_EQUAL(GetSerializeSize(bool(0), 0), 1);
+}
+
+BOOST_AUTO_TEST_CASE(floats_conversion)
+{
+ // Choose values that map unambigiously to binary floating point to avoid
+ // rounding issues at the compiler side.
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x00000000), 0.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f000000), 0.5F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f800000), 1.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40000000), 2.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40800000), 4.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x44444444), 785.066650390625F);
+
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(0.0F), 0x00000000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(0.5F), 0x3f000000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(1.0F), 0x3f800000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(2.0F), 0x40000000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(4.0F), 0x40800000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(785.066650390625F), 0x44444444);
+}
+
+BOOST_AUTO_TEST_CASE(doubles_conversion)
+{
+ // Choose values that map unambigiously to binary floating point to avoid
+ // rounding issues at the compiler side.
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x0000000000000000ULL), 0.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3fe0000000000000ULL), 0.5);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3ff0000000000000ULL), 1.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4000000000000000ULL), 2.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4010000000000000ULL), 4.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4088888880000000ULL), 785.066650390625);
+
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(0.0), 0x0000000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(0.5), 0x3fe0000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(1.0), 0x3ff0000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(2.0), 0x4000000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(4.0), 0x4010000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(785.066650390625), 0x4088888880000000ULL);
+}
+/*
+Python code to generate the below hashes:
+
+ def reversed_hex(x):
+ return binascii.hexlify(''.join(reversed(x)))
+ def dsha256(x):
+ return hashlib.sha256(hashlib.sha256(x).digest()).digest()
+
+ reversed_hex(dsha256(''.join(struct.pack('<f', x) for x in range(0,1000)))) == '8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c'
+ reversed_hex(dsha256(''.join(struct.pack('<d', x) for x in range(0,1000)))) == '43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96'
+*/
+BOOST_AUTO_TEST_CASE(floats)
+{
+ CDataStream ss(SER_DISK, 0);
+ // encode
+ for (int i = 0; i < 1000; i++) {
+ ss << float(i);
+ }
+ BOOST_CHECK(Hash(ss.begin(), ss.end()) == uint256S("8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c"));
+
+ // decode
+ for (int i = 0; i < 1000; i++) {
+ float j;
+ ss >> j;
+ BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(doubles)
+{
+ CDataStream ss(SER_DISK, 0);
+ // encode
+ for (int i = 0; i < 1000; i++) {
+ ss << double(i);
+ }
+ BOOST_CHECK(Hash(ss.begin(), ss.end()) == uint256S("43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96"));
+
+ // decode
+ for (int i = 0; i < 1000; i++) {
+ double j;
+ ss >> j;
+ BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
+ }
+}
BOOST_AUTO_TEST_CASE(varints)
{
// Copyright (c) 2013 The Bitcoin Core 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 "data/sighash.json.h"
#include "script/interpreter.h"
#include "util.h"
#include "version.h"
+#include "test/test_bitcoin.h"
#include <iostream>
// Old script.cpp SignatureHash function
uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
{
+ static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
if (nIn >= txTo.vin.size())
{
- printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);
- return 1;
+ printf("ERROR: SignatureHash(): nIn=%d out of range\n", nIn);
+ return one;
}
CMutableTransaction txTmp(txTo);
unsigned int nOut = nIn;
if (nOut >= txTmp.vout.size())
{
- printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);
- return 1;
+ printf("ERROR: SignatureHash(): nOut=%d out of range\n", nOut);
+ return one;
}
txTmp.vout.resize(nOut+1);
for (unsigned int i = 0; i < nOut; i++)
}
}
-BOOST_AUTO_TEST_SUITE(sighash_tests)
+BOOST_FIXTURE_TEST_SUITE(sighash_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(sighash_test)
{
// Copyright (c) 2012-2013 The Bitcoin Core 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 "pubkey.h"
#include "script/script.h"
#include "script/standard.h"
#include "uint256.h"
+#include "test/test_bitcoin.h"
#include <vector>
return sSerialized;
}
-BOOST_AUTO_TEST_SUITE(sigopcount_tests)
+BOOST_FIXTURE_TEST_SUITE(sigopcount_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(GetSigOpCount)
{
BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0U);
BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0U);
- uint160 dummy(0);
+ uint160 dummy;
s1 << OP_1 << ToByteVector(dummy) << ToByteVector(dummy) << OP_2 << OP_CHECKMULTISIG;
BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2U);
s1 << OP_IF << OP_CHECKSIG << OP_ENDIF;
// Copyright (c) 2014 The Bitcoin Core 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 "main.h"
#include "random.h"
#include "util.h"
+#include "test/test_bitcoin.h"
#include <vector>
#define SKIPLIST_LENGTH 300000
-BOOST_AUTO_TEST_SUITE(skiplist_tests)
+BOOST_FIXTURE_TEST_SUITE(skiplist_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(skiplist_test)
{
std::vector<uint256> vHashMain(100000);
std::vector<CBlockIndex> vBlocksMain(100000);
for (unsigned int i=0; i<vBlocksMain.size(); i++) {
- vHashMain[i] = i; // Set the hash equal to the height, so we can quickly check the distances.
+ vHashMain[i] = ArithToUint256(i); // Set the hash equal to the height, so we can quickly check the distances.
vBlocksMain[i].nHeight = i;
vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : NULL;
vBlocksMain[i].phashBlock = &vHashMain[i];
vBlocksMain[i].BuildSkip();
- BOOST_CHECK_EQUAL((int)vBlocksMain[i].GetBlockHash().GetLow64(), vBlocksMain[i].nHeight);
+ BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksMain[i].GetBlockHash()).GetLow64(), vBlocksMain[i].nHeight);
BOOST_CHECK(vBlocksMain[i].pprev == NULL || vBlocksMain[i].nHeight == vBlocksMain[i].pprev->nHeight + 1);
}
std::vector<uint256> vHashSide(50000);
std::vector<CBlockIndex> vBlocksSide(50000);
for (unsigned int i=0; i<vBlocksSide.size(); i++) {
- vHashSide[i] = i + 50000 + (uint256(1) << 128); // Add 1<<128 to the hashes, so GetLow64() still returns the height.
+ vHashSide[i] = ArithToUint256(i + 50000 + (arith_uint256(1) << 128)); // Add 1<<128 to the hashes, so GetLow64() still returns the height.
vBlocksSide[i].nHeight = i + 50000;
vBlocksSide[i].pprev = i ? &vBlocksSide[i - 1] : &vBlocksMain[49999];
vBlocksSide[i].phashBlock = &vHashSide[i];
vBlocksSide[i].BuildSkip();
- BOOST_CHECK_EQUAL((int)vBlocksSide[i].GetBlockHash().GetLow64(), vBlocksSide[i].nHeight);
+ BOOST_CHECK_EQUAL((int)UintToArith256(vBlocksSide[i].GetBlockHash()).GetLow64(), vBlocksSide[i].nHeight);
BOOST_CHECK(vBlocksSide[i].pprev == NULL || vBlocksSide[i].nHeight == vBlocksSide[i].pprev->nHeight + 1);
}
// Entries 1 through 11 (inclusive) go back one step each.
for (unsigned int i = 1; i < 12 && i < locator.vHave.size() - 1; i++) {
- BOOST_CHECK_EQUAL(locator.vHave[i].GetLow64(), tip->nHeight - i);
+ BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i]).GetLow64(), tip->nHeight - i);
}
// The further ones (excluding the last one) go back with exponential steps.
unsigned int dist = 2;
for (unsigned int i = 12; i < locator.vHave.size() - 1; i++) {
- BOOST_CHECK_EQUAL(locator.vHave[i - 1].GetLow64() - locator.vHave[i].GetLow64(), dist);
+ BOOST_CHECK_EQUAL(UintToArith256(locator.vHave[i - 1]).GetLow64() - UintToArith256(locator.vHave[i]).GetLow64(), dist);
dist *= 2;
}
}
// Copyright (c) 2011-2013 The Bitcoin Core 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.
#define BOOST_TEST_MODULE Bitcoin Test Suite
+#include "test_bitcoin.h"
+
#include "main.h"
#include "random.h"
#include "txdb.h"
extern bool fPrintToConsole;
extern void noui_connect();
-struct TestingSetup {
- CCoinsViewDB *pcoinsdbview;
- boost::filesystem::path pathTemp;
- boost::thread_group threadGroup;
-
- TestingSetup() {
+BasicTestingSetup::BasicTestingSetup()
+{
fPrintToDebugLog = false; // don't want to write to debug.log file
- SelectParams(CBaseChainParams::UNITTEST);
- noui_connect();
+ SelectParams(CBaseChainParams::MAIN);
+}
+BasicTestingSetup::~BasicTestingSetup()
+{
+}
+
+TestingSetup::TestingSetup()
+{
#ifdef ENABLE_WALLET
bitdb.MakeMock();
#endif
+ ClearDatadirCache();
pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000)));
boost::filesystem::create_directories(pathTemp);
mapArgs["-datadir"] = pathTemp.string();
for (int i=0; i < nScriptCheckThreads-1; i++)
threadGroup.create_thread(&ThreadScriptCheck);
RegisterNodeSignals(GetNodeSignals());
- }
- ~TestingSetup()
- {
+}
+
+TestingSetup::~TestingSetup()
+{
+ UnregisterNodeSignals(GetNodeSignals());
threadGroup.interrupt_all();
threadGroup.join_all();
- UnregisterNodeSignals(GetNodeSignals());
#ifdef ENABLE_WALLET
+ UnregisterValidationInterface(pwalletMain);
delete pwalletMain;
pwalletMain = NULL;
#endif
+ UnloadBlockIndex();
delete pcoinsTip;
delete pcoinsdbview;
delete pblocktree;
#ifdef ENABLE_WALLET
bitdb.Flush(true);
+ bitdb.Reset();
#endif
boost::filesystem::remove_all(pathTemp);
- }
-};
-
-BOOST_GLOBAL_FIXTURE(TestingSetup);
+}
void Shutdown(void* parg)
{
--- /dev/null
+#ifndef BITCOIN_TEST_TEST_BITCOIN_H
+#define BITCOIN_TEST_TEST_BITCOIN_H
+
+#include "txdb.h"
+
+#include <boost/filesystem.hpp>
+#include <boost/thread.hpp>
+
+/** Basic testing setup.
+ * This just configures logging and chain parameters.
+ */
+struct BasicTestingSetup {
+ BasicTestingSetup();
+ ~BasicTestingSetup();
+};
+
+/** Testing setup that configures a complete environment.
+ * Included are data directory, coins database, script check threads
+ * and wallet (if enabled) setup.
+ */
+struct TestingSetup: public BasicTestingSetup {
+ CCoinsViewDB *pcoinsdbview;
+ boost::filesystem::path pathTemp;
+ boost::thread_group threadGroup;
+
+ TestingSetup();
+ ~TestingSetup();
+};
+
+#endif
// Copyright (c) 2011-2014 The Bitcoin Core 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"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
using namespace std;
-BOOST_AUTO_TEST_SUITE(timedata_tests)
+BOOST_FIXTURE_TEST_SUITE(timedata_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(util_MedianFilter)
{
// Copyright (c) 2011-2014 The Bitcoin Core 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 "data/tx_invalid.json.h"
#include "data/tx_valid.json.h"
+#include "test/test_bitcoin.h"
#include "clientversion.h"
#include "key.h"
using namespace std;
using namespace json_spirit;
-using namespace boost::algorithm;
// In script_tests.cpp
extern Array read_json(const std::string& jsondata);
(string("SIGPUSHONLY"), (unsigned int)SCRIPT_VERIFY_SIGPUSHONLY)
(string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA)
(string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY)
- (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS);
+ (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
+ (string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK);
unsigned int ParseScriptFlags(string strFlags)
{
}
unsigned int flags = 0;
vector<string> words;
- split(words, strFlags, is_any_of(","));
+ boost::algorithm::split(words, strFlags, boost::algorithm::is_any_of(","));
BOOST_FOREACH(string word, words)
{
return ret.substr(0, ret.size() - 1);
}
-BOOST_AUTO_TEST_SUITE(transaction_tests)
+BOOST_FIXTURE_TEST_SUITE(transaction_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(tx_valid)
{
break;
}
- mapprevOutScriptPubKeys[COutPoint(uint256(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
+ mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
}
if (!fValid)
{
unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
- verify_flags, SignatureChecker(tx, i), &err),
+ verify_flags, TransactionSignatureChecker(&tx, i), &err),
strTest);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
break;
}
- mapprevOutScriptPubKeys[COutPoint(uint256(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
+ mapprevOutScriptPubKeys[COutPoint(uint256S(vinput[0].get_str()), vinput[1].get_int())] = ParseScript(vinput[2].get_str());
}
if (!fValid)
{
unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
- verify_flags, SignatureChecker(tx, i), &err);
+ verify_flags, TransactionSignatureChecker(&tx, i), &err);
}
BOOST_CHECK_MESSAGE(!fValid, strTest);
BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err));
t.vout[0].scriptPubKey = CScript() << OP_1;
BOOST_CHECK(!IsStandardTx(t, reason));
- // 40-byte TX_NULL_DATA (standard)
- t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
+ // 80-byte TX_NULL_DATA (standard)
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
BOOST_CHECK(IsStandardTx(t, reason));
- // 41-byte TX_NULL_DATA (non-standard)
- t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800");
+ // 81-byte TX_NULL_DATA (non-standard)
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800");
BOOST_CHECK(!IsStandardTx(t, reason));
// TX_NULL_DATA w/o PUSHDATA
// Copyright (c) 2011-2013 The Bitcoin Core 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 "arith_uint256.h"
+#include "uint256.h"
+#include "version.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
#include <stdint.h>
#include <iomanip>
#include <limits>
#include <cmath>
-#include "uint256.h"
#include <string>
-#include "version.h"
+#include <stdio.h>
-BOOST_AUTO_TEST_SUITE(uint256_tests)
-
-const unsigned char R1Array[] =
+BOOST_FIXTURE_TEST_SUITE(uint256_tests, BasicTestingSetup)
+
+const unsigned char R1Array[] =
"\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2"
"\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d";
const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c";
-const double R1Ldouble = 0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256
-const double R1Sdouble = 0.7096329412477836074;
const uint256 R1L = uint256(std::vector<unsigned char>(R1Array,R1Array+32));
const uint160 R1S = uint160(std::vector<unsigned char>(R1Array,R1Array+20));
-const uint64_t R1LLow64 = 0x121156cfdb4a529cULL;
-const unsigned char R2Array[] =
+const unsigned char R2Array[] =
"\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf"
"\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7";
const uint256 R2L = uint256(std::vector<unsigned char>(R2Array,R2Array+32));
const uint160 R2S = uint160(std::vector<unsigned char>(R2Array,R2Array+20));
-const char R1LplusR2L[] = "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C";
-
-const unsigned char ZeroArray[] =
+const unsigned char ZeroArray[] =
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
const uint256 ZeroL = uint256(std::vector<unsigned char>(ZeroArray,ZeroArray+32));
const uint160 ZeroS = uint160(std::vector<unsigned char>(ZeroArray,ZeroArray+20));
-
-const unsigned char OneArray[] =
+
+const unsigned char OneArray[] =
"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
const uint256 OneL = uint256(std::vector<unsigned char>(OneArray,OneArray+32));
const uint160 OneS = uint160(std::vector<unsigned char>(OneArray,OneArray+20));
-const unsigned char MaxArray[] =
+const unsigned char MaxArray[] =
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
const uint256 MaxL = uint256(std::vector<unsigned char>(MaxArray,MaxArray+32));
const uint160 MaxS = uint160(std::vector<unsigned char>(MaxArray,MaxArray+20));
-const uint256 HalfL = (OneL << 255);
-const uint160 HalfS = (OneS << 159);
std::string ArrayToString(const unsigned char A[], unsigned int width)
{
std::stringstream Stream;
Stream << std::hex;
- for (unsigned int i = 0; i < width; ++i)
+ for (unsigned int i = 0; i < width; ++i)
{
Stream<<std::setw(2)<<std::setfill('0')<<(unsigned int)A[width-i-1];
- }
+ }
return Stream.str();
}
+inline uint160 uint160S(const char *str)
+{
+ uint160 rv;
+ rv.SetHex(str);
+ return rv;
+}
+inline uint160 uint160S(const std::string& str)
+{
+ uint160 rv;
+ rv.SetHex(str);
+ return rv;
+}
+
BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
{
BOOST_CHECK(1 == 0+1);
BOOST_CHECK(ZeroL != OneL && ZeroS != OneS);
BOOST_CHECK(OneL != ZeroL && OneS != ZeroS);
BOOST_CHECK(MaxL != ZeroL && MaxS != ZeroS);
- BOOST_CHECK(~MaxL == ZeroL && ~MaxS == ZeroS);
- BOOST_CHECK( ((R1L ^ R2L) ^ R1L) == R2L);
- BOOST_CHECK( ((R1S ^ R2S) ^ R1S) == R2S);
-
- uint64_t Tmp64 = 0xc4dab720d9c7acaaULL;
- for (unsigned int i = 0; i < 256; ++i)
- {
- BOOST_CHECK(ZeroL != (OneL << i));
- BOOST_CHECK((OneL << i) != ZeroL);
- BOOST_CHECK(R1L != (R1L ^ (OneL << i)));
- BOOST_CHECK(((uint256(Tmp64) ^ (OneL << i) ) != Tmp64 ));
- }
- BOOST_CHECK(ZeroL == (OneL << 256));
-
- for (unsigned int i = 0; i < 160; ++i)
- {
- BOOST_CHECK(ZeroS != (OneS << i));
- BOOST_CHECK((OneS << i) != ZeroS);
- BOOST_CHECK(R1S != (R1S ^ (OneS << i)));
- BOOST_CHECK(((uint160(Tmp64) ^ (OneS << i) ) != Tmp64 ));
- }
- BOOST_CHECK(ZeroS == (OneS << 256));
// String Constructor and Copy Constructor
- BOOST_CHECK(uint256("0x"+R1L.ToString()) == R1L);
- BOOST_CHECK(uint256("0x"+R2L.ToString()) == R2L);
- BOOST_CHECK(uint256("0x"+ZeroL.ToString()) == ZeroL);
- BOOST_CHECK(uint256("0x"+OneL.ToString()) == OneL);
- BOOST_CHECK(uint256("0x"+MaxL.ToString()) == MaxL);
- BOOST_CHECK(uint256(R1L.ToString()) == R1L);
- BOOST_CHECK(uint256(" 0x"+R1L.ToString()+" ") == R1L);
- BOOST_CHECK(uint256("") == ZeroL);
- BOOST_CHECK(R1L == uint256(R1ArrayHex));
+ BOOST_CHECK(uint256S("0x"+R1L.ToString()) == R1L);
+ BOOST_CHECK(uint256S("0x"+R2L.ToString()) == R2L);
+ BOOST_CHECK(uint256S("0x"+ZeroL.ToString()) == ZeroL);
+ BOOST_CHECK(uint256S("0x"+OneL.ToString()) == OneL);
+ BOOST_CHECK(uint256S("0x"+MaxL.ToString()) == MaxL);
+ BOOST_CHECK(uint256S(R1L.ToString()) == R1L);
+ BOOST_CHECK(uint256S(" 0x"+R1L.ToString()+" ") == R1L);
+ BOOST_CHECK(uint256S("") == ZeroL);
+ BOOST_CHECK(R1L == uint256S(R1ArrayHex));
BOOST_CHECK(uint256(R1L) == R1L);
- BOOST_CHECK((uint256(R1L^R2L)^R2L) == R1L);
BOOST_CHECK(uint256(ZeroL) == ZeroL);
BOOST_CHECK(uint256(OneL) == OneL);
- BOOST_CHECK(uint160("0x"+R1S.ToString()) == R1S);
- BOOST_CHECK(uint160("0x"+R2S.ToString()) == R2S);
- BOOST_CHECK(uint160("0x"+ZeroS.ToString()) == ZeroS);
- BOOST_CHECK(uint160("0x"+OneS.ToString()) == OneS);
- BOOST_CHECK(uint160("0x"+MaxS.ToString()) == MaxS);
- BOOST_CHECK(uint160(R1S.ToString()) == R1S);
- BOOST_CHECK(uint160(" 0x"+R1S.ToString()+" ") == R1S);
- BOOST_CHECK(uint160("") == ZeroS);
- BOOST_CHECK(R1S == uint160(R1ArrayHex));
+ BOOST_CHECK(uint160S("0x"+R1S.ToString()) == R1S);
+ BOOST_CHECK(uint160S("0x"+R2S.ToString()) == R2S);
+ BOOST_CHECK(uint160S("0x"+ZeroS.ToString()) == ZeroS);
+ BOOST_CHECK(uint160S("0x"+OneS.ToString()) == OneS);
+ BOOST_CHECK(uint160S("0x"+MaxS.ToString()) == MaxS);
+ BOOST_CHECK(uint160S(R1S.ToString()) == R1S);
+ BOOST_CHECK(uint160S(" 0x"+R1S.ToString()+" ") == R1S);
+ BOOST_CHECK(uint160S("") == ZeroS);
+ BOOST_CHECK(R1S == uint160S(R1ArrayHex));
BOOST_CHECK(uint160(R1S) == R1S);
- BOOST_CHECK((uint160(R1S^R2S)^R2S) == R1S);
BOOST_CHECK(uint160(ZeroS) == ZeroS);
BOOST_CHECK(uint160(OneS) == OneS);
-
- // uint64_t constructor
- BOOST_CHECK( (R1L & uint256("0xffffffffffffffff")) == uint256(R1LLow64));
- BOOST_CHECK(ZeroL == uint256(0));
- BOOST_CHECK(OneL == uint256(1));
- BOOST_CHECK(uint256("0xffffffffffffffff") = uint256(0xffffffffffffffffULL));
- BOOST_CHECK( (R1S & uint160("0xffffffffffffffff")) == uint160(R1LLow64));
- BOOST_CHECK(ZeroS == uint160(0));
- BOOST_CHECK(OneS == uint160(1));
- BOOST_CHECK(uint160("0xffffffffffffffff") = uint160(0xffffffffffffffffULL));
-
- // Assignment (from base_uint)
- uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL);
- tmpL = ~OneL; BOOST_CHECK(tmpL == ~OneL);
- tmpL = ~R1L; BOOST_CHECK(tmpL == ~R1L);
- tmpL = ~R2L; BOOST_CHECK(tmpL == ~R2L);
- tmpL = ~MaxL; BOOST_CHECK(tmpL == ~MaxL);
- uint160 tmpS = ~ZeroS; BOOST_CHECK(tmpS == ~ZeroS);
- tmpS = ~OneS; BOOST_CHECK(tmpS == ~OneS);
- tmpS = ~R1S; BOOST_CHECK(tmpS == ~R1S);
- tmpS = ~R2S; BOOST_CHECK(tmpS == ~R2S);
- tmpS = ~MaxS; BOOST_CHECK(tmpS == ~MaxS);
-
- // Wrong length must throw exception.
- BOOST_CHECK_THROW(uint256(std::vector<unsigned char>(OneArray,OneArray+31)), uint_error);
- BOOST_CHECK_THROW(uint256(std::vector<unsigned char>(OneArray,OneArray+20)), uint_error);
- BOOST_CHECK_THROW(uint160(std::vector<unsigned char>(OneArray,OneArray+32)), uint_error);
- BOOST_CHECK_THROW(uint160(std::vector<unsigned char>(OneArray,OneArray+19)), uint_error);
-}
-
-void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift)
-{
- for (unsigned int T=0; T < arrayLength; ++T)
- {
- unsigned int F = (T+bitsToShift/8);
- if (F < arrayLength)
- to[T] = from[F] >> (bitsToShift%8);
- else
- to[T] = 0;
- if (F + 1 < arrayLength)
- to[T] |= from[(F+1)] << (8-bitsToShift%8);
- }
-}
-
-void shiftArrayLeft(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift)
-{
- for (unsigned int T=0; T < arrayLength; ++T)
- {
- if (T >= bitsToShift/8)
- {
- unsigned int F = T-bitsToShift/8;
- to[T] = from[F] << (bitsToShift%8);
- if (T >= bitsToShift/8+1)
- to[T] |= from[F-1] >> (8-bitsToShift%8);
- }
- else {
- to[T] = 0;
- }
- }
-}
-
-BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>="
- unsigned char TmpArray[32];
- uint256 TmpL;
- for (unsigned int i = 0; i < 256; ++i)
- {
- shiftArrayLeft(TmpArray, OneArray, 32, i);
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (OneL << i));
- TmpL = OneL; TmpL <<= i;
- BOOST_CHECK(TmpL == (OneL << i));
- BOOST_CHECK((HalfL >> (255-i)) == (OneL << i));
- TmpL = HalfL; TmpL >>= (255-i);
- BOOST_CHECK(TmpL == (OneL << i));
-
- shiftArrayLeft(TmpArray, R1Array, 32, i);
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L << i));
- TmpL = R1L; TmpL <<= i;
- BOOST_CHECK(TmpL == (R1L << i));
-
- shiftArrayRight(TmpArray, R1Array, 32, i);
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L >> i));
- TmpL = R1L; TmpL >>= i;
- BOOST_CHECK(TmpL == (R1L >> i));
-
- shiftArrayLeft(TmpArray, MaxArray, 32, i);
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL << i));
- TmpL = MaxL; TmpL <<= i;
- BOOST_CHECK(TmpL == (MaxL << i));
-
- shiftArrayRight(TmpArray, MaxArray, 32, i);
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL >> i));
- TmpL = MaxL; TmpL >>= i;
- BOOST_CHECK(TmpL == (MaxL >> i));
- }
- uint256 c1L = uint256(0x0123456789abcdefULL);
- uint256 c2L = c1L << 128;
- for (unsigned int i = 0; i < 128; ++i) {
- BOOST_CHECK((c1L << i) == (c2L >> (128-i)));
- }
- for (unsigned int i = 128; i < 256; ++i) {
- BOOST_CHECK((c1L << i) == (c2L << (i-128)));
- }
-
- uint160 TmpS;
- for (unsigned int i = 0; i < 160; ++i)
- {
- shiftArrayLeft(TmpArray, OneArray, 20, i);
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (OneS << i));
- TmpS = OneS; TmpS <<= i;
- BOOST_CHECK(TmpS == (OneS << i));
- BOOST_CHECK((HalfS >> (159-i)) == (OneS << i));
- TmpS = HalfS; TmpS >>= (159-i);
- BOOST_CHECK(TmpS == (OneS << i));
-
- shiftArrayLeft(TmpArray, R1Array, 20, i);
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (R1S << i));
- TmpS = R1S; TmpS <<= i;
- BOOST_CHECK(TmpS == (R1S << i));
-
- shiftArrayRight(TmpArray, R1Array, 20, i);
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (R1S >> i));
- TmpS = R1S; TmpS >>= i;
- BOOST_CHECK(TmpS == (R1S >> i));
-
- shiftArrayLeft(TmpArray, MaxArray, 20, i);
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (MaxS << i));
- TmpS = MaxS; TmpS <<= i;
- BOOST_CHECK(TmpS == (MaxS << i));
-
- shiftArrayRight(TmpArray, MaxArray, 20, i);
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (MaxS >> i));
- TmpS = MaxS; TmpS >>= i;
- BOOST_CHECK(TmpS == (MaxS >> i));
- }
- uint160 c1S = uint160(0x0123456789abcdefULL);
- uint160 c2S = c1S << 80;
- for (unsigned int i = 0; i < 80; ++i) {
- BOOST_CHECK((c1S << i) == (c2S >> (80-i)));
- }
- for (unsigned int i = 80; i < 160; ++i) {
- BOOST_CHECK((c1S << i) == (c2S << (i-80)));
- }
-}
-
-BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ -
-{
- BOOST_CHECK(!ZeroL); BOOST_CHECK(!ZeroS);
- BOOST_CHECK(!(!OneL));BOOST_CHECK(!(!OneS));
- for (unsigned int i = 0; i < 256; ++i)
- BOOST_CHECK(!(!(OneL<<i)));
- for (unsigned int i = 0; i < 160; ++i)
- BOOST_CHECK(!(!(OneS<<i)));
- BOOST_CHECK(!(!R1L));BOOST_CHECK(!(!R1S));
- BOOST_CHECK(!(!R2S));BOOST_CHECK(!(!R2S));
- BOOST_CHECK(!(!MaxL));BOOST_CHECK(!(!MaxS));
-
- BOOST_CHECK(~ZeroL == MaxL); BOOST_CHECK(~ZeroS == MaxS);
-
- unsigned char TmpArray[32];
- for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = ~R1Array[i]; }
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (~R1L));
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (~R1S));
-
- BOOST_CHECK(-ZeroL == ZeroL); BOOST_CHECK(-ZeroS == ZeroS);
- BOOST_CHECK(-R1L == (~R1L)+1);
- BOOST_CHECK(-R1S == (~R1S)+1);
- for (unsigned int i = 0; i < 256; ++i)
- BOOST_CHECK(-(OneL<<i) == (MaxL << i));
- for (unsigned int i = 0; i < 160; ++i)
- BOOST_CHECK(-(OneS<<i) == (MaxS << i));
-}
-
-
-// Check if doing _A_ _OP_ _B_ results in the same as applying _OP_ onto each
-// element of Aarray and Barray, and then converting the result into a uint256.
-#define CHECKBITWISEOPERATOR(_A_,_B_,_OP_) \
- for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \
- BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); \
- for (unsigned int i = 0; i < 20; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \
- BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (_A_##S _OP_ _B_##S));
-
-#define CHECKASSIGNMENTOPERATOR(_A_,_B_,_OP_) \
- TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L)); \
- TmpS = _A_##S; TmpS _OP_##= _B_##S; BOOST_CHECK(TmpS == (_A_##S _OP_ _B_##S));
-
-BOOST_AUTO_TEST_CASE( bitwiseOperators )
-{
- unsigned char TmpArray[32];
-
- CHECKBITWISEOPERATOR(R1,R2,|)
- CHECKBITWISEOPERATOR(R1,R2,^)
- CHECKBITWISEOPERATOR(R1,R2,&)
- CHECKBITWISEOPERATOR(R1,Zero,|)
- CHECKBITWISEOPERATOR(R1,Zero,^)
- CHECKBITWISEOPERATOR(R1,Zero,&)
- CHECKBITWISEOPERATOR(R1,Max,|)
- CHECKBITWISEOPERATOR(R1,Max,^)
- CHECKBITWISEOPERATOR(R1,Max,&)
- CHECKBITWISEOPERATOR(Zero,R1,|)
- CHECKBITWISEOPERATOR(Zero,R1,^)
- CHECKBITWISEOPERATOR(Zero,R1,&)
- CHECKBITWISEOPERATOR(Max,R1,|)
- CHECKBITWISEOPERATOR(Max,R1,^)
- CHECKBITWISEOPERATOR(Max,R1,&)
-
- uint256 TmpL;
- uint160 TmpS;
- CHECKASSIGNMENTOPERATOR(R1,R2,|)
- CHECKASSIGNMENTOPERATOR(R1,R2,^)
- CHECKASSIGNMENTOPERATOR(R1,R2,&)
- CHECKASSIGNMENTOPERATOR(R1,Zero,|)
- CHECKASSIGNMENTOPERATOR(R1,Zero,^)
- CHECKASSIGNMENTOPERATOR(R1,Zero,&)
- CHECKASSIGNMENTOPERATOR(R1,Max,|)
- CHECKASSIGNMENTOPERATOR(R1,Max,^)
- CHECKASSIGNMENTOPERATOR(R1,Max,&)
- CHECKASSIGNMENTOPERATOR(Zero,R1,|)
- CHECKASSIGNMENTOPERATOR(Zero,R1,^)
- CHECKASSIGNMENTOPERATOR(Zero,R1,&)
- CHECKASSIGNMENTOPERATOR(Max,R1,|)
- CHECKASSIGNMENTOPERATOR(Max,R1,^)
- CHECKASSIGNMENTOPERATOR(Max,R1,&)
-
- uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL;
- TmpL = R1L; TmpL |= Tmp64; BOOST_CHECK(TmpL == (R1L | uint256(Tmp64)));
- TmpS = R1S; TmpS |= Tmp64; BOOST_CHECK(TmpS == (R1S | uint160(Tmp64)));
- TmpL = R1L; TmpL |= 0; BOOST_CHECK(TmpL == R1L);
- TmpS = R1S; TmpS |= 0; BOOST_CHECK(TmpS == R1S);
- TmpL ^= 0; BOOST_CHECK(TmpL == R1L);
- TmpS ^= 0; BOOST_CHECK(TmpS == R1S);
- TmpL ^= Tmp64; BOOST_CHECK(TmpL == (R1L ^ uint256(Tmp64)));
- TmpS ^= Tmp64; BOOST_CHECK(TmpS == (R1S ^ uint160(Tmp64)));
}
BOOST_AUTO_TEST_CASE( comparison ) // <= >= < >
{
- uint256 TmpL;
- for (unsigned int i = 0; i < 256; ++i) {
- TmpL= OneL<< i;
- BOOST_CHECK( TmpL >= ZeroL && TmpL > ZeroL && ZeroL < TmpL && ZeroL <= TmpL);
- BOOST_CHECK( TmpL >= 0 && TmpL > 0 && 0 < TmpL && 0 <= TmpL);
- TmpL |= R1L;
- BOOST_CHECK( TmpL >= R1L ); BOOST_CHECK( (TmpL == R1L) != (TmpL > R1L)); BOOST_CHECK( (TmpL == R1L) || !( TmpL <= R1L));
- BOOST_CHECK( R1L <= TmpL ); BOOST_CHECK( (R1L == TmpL) != (R1L < TmpL)); BOOST_CHECK( (TmpL == R1L) || !( R1L >= TmpL));
- BOOST_CHECK(! (TmpL < R1L)); BOOST_CHECK(! (R1L > TmpL));
- }
- uint160 TmpS;
- for (unsigned int i = 0; i < 160; ++i) {
- TmpS= OneS<< i;
- BOOST_CHECK( TmpS >= ZeroS && TmpS > ZeroS && ZeroS < TmpS && ZeroS <= TmpS);
- BOOST_CHECK( TmpS >= 0 && TmpS > 0 && 0 < TmpS && 0 <= TmpS);
- TmpS |= R1S;
- BOOST_CHECK( TmpS >= R1S ); BOOST_CHECK( (TmpS == R1S) != (TmpS > R1S)); BOOST_CHECK( (TmpS == R1S) || !( TmpS <= R1S));
- BOOST_CHECK( R1S <= TmpS ); BOOST_CHECK( (R1S == TmpS) != (R1S < TmpS)); BOOST_CHECK( (TmpS == R1S) || !( R1S >= TmpS));
- BOOST_CHECK(! (TmpS < R1S)); BOOST_CHECK(! (R1S > TmpS));
+ uint256 LastL;
+ for (int i = 255; i >= 0; --i) {
+ uint256 TmpL;
+ *(TmpL.begin() + (i>>3)) |= 1<<(7-(i&7));
+ BOOST_CHECK( LastL < TmpL );
+ LastL = TmpL;
}
-}
-BOOST_AUTO_TEST_CASE( plusMinus )
-{
- uint256 TmpL = 0;
- BOOST_CHECK(R1L+R2L == uint256(R1LplusR2L));
- TmpL += R1L;
- BOOST_CHECK(TmpL == R1L);
- TmpL += R2L;
- BOOST_CHECK(TmpL == R1L + R2L);
- BOOST_CHECK(OneL+MaxL == ZeroL);
- BOOST_CHECK(MaxL+OneL == ZeroL);
- for (unsigned int i = 1; i < 256; ++i) {
- BOOST_CHECK( (MaxL >> i) + OneL == (HalfL >> (i-1)) );
- BOOST_CHECK( OneL + (MaxL >> i) == (HalfL >> (i-1)) );
- TmpL = (MaxL>>i); TmpL += OneL;
- BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
- TmpL = (MaxL>>i); TmpL += 1;
- BOOST_CHECK( TmpL == (HalfL >> (i-1)) );
- TmpL = (MaxL>>i);
- BOOST_CHECK( TmpL++ == (MaxL>>i) );
- BOOST_CHECK( TmpL == (HalfL >> (i-1)));
+ BOOST_CHECK( ZeroL < R1L );
+ BOOST_CHECK( R2L < R1L );
+ BOOST_CHECK( ZeroL < OneL );
+ BOOST_CHECK( OneL < MaxL );
+ BOOST_CHECK( R1L < MaxL );
+ BOOST_CHECK( R2L < MaxL );
+
+ uint160 LastS;
+ for (int i = 159; i >= 0; --i) {
+ uint160 TmpS;
+ *(TmpS.begin() + (i>>3)) |= 1<<(7-(i&7));
+ BOOST_CHECK( LastS < TmpS );
+ LastS = TmpS;
}
- BOOST_CHECK(uint256(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == uint256(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL));
- TmpL = uint256(0xbedc77e27940a7ULL); TmpL += 0xee8d836fce66fbULL;
- BOOST_CHECK(TmpL == uint256(0xbedc77e27940a7ULL+0xee8d836fce66fbULL));
- TmpL -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpL == 0xbedc77e27940a7ULL);
- TmpL = R1L;
- BOOST_CHECK(++TmpL == R1L+1);
-
- BOOST_CHECK(R1L -(-R2L) == R1L+R2L);
- BOOST_CHECK(R1L -(-OneL) == R1L+OneL);
- BOOST_CHECK(R1L - OneL == R1L+(-OneL));
- for (unsigned int i = 1; i < 256; ++i) {
- BOOST_CHECK((MaxL>>i) - (-OneL) == (HalfL >> (i-1)));
- BOOST_CHECK((HalfL >> (i-1)) - OneL == (MaxL>>i));
- TmpL = (HalfL >> (i-1));
- BOOST_CHECK(TmpL-- == (HalfL >> (i-1)));
- BOOST_CHECK(TmpL == (MaxL >> i));
- TmpL = (HalfL >> (i-1));
- BOOST_CHECK(--TmpL == (MaxL >> i));
- }
- TmpL = R1L;
- BOOST_CHECK(--TmpL == R1L-1);
-
- // 160-bit; copy-pasted
- uint160 TmpS = 0;
- BOOST_CHECK(R1S+R2S == uint160(R1LplusR2L));
- TmpS += R1S;
- BOOST_CHECK(TmpS == R1S);
- TmpS += R2S;
- BOOST_CHECK(TmpS == R1S + R2S);
- BOOST_CHECK(OneS+MaxS == ZeroS);
- BOOST_CHECK(MaxS+OneS == ZeroS);
- for (unsigned int i = 1; i < 160; ++i) {
- BOOST_CHECK( (MaxS >> i) + OneS == (HalfS >> (i-1)) );
- BOOST_CHECK( OneS + (MaxS >> i) == (HalfS >> (i-1)) );
- TmpS = (MaxS>>i); TmpS += OneS;
- BOOST_CHECK( TmpS == (HalfS >> (i-1)) );
- TmpS = (MaxS>>i); TmpS += 1;
- BOOST_CHECK( TmpS == (HalfS >> (i-1)) );
- TmpS = (MaxS>>i);
- BOOST_CHECK( TmpS++ == (MaxS>>i) );
- BOOST_CHECK( TmpS == (HalfS >> (i-1)));
- }
- BOOST_CHECK(uint160(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == uint160(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL));
- TmpS = uint160(0xbedc77e27940a7ULL); TmpS += 0xee8d836fce66fbULL;
- BOOST_CHECK(TmpS == uint160(0xbedc77e27940a7ULL+0xee8d836fce66fbULL));
- TmpS -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpS == 0xbedc77e27940a7ULL);
- TmpS = R1S;
- BOOST_CHECK(++TmpS == R1S+1);
-
- BOOST_CHECK(R1S -(-R2S) == R1S+R2S);
- BOOST_CHECK(R1S -(-OneS) == R1S+OneS);
- BOOST_CHECK(R1S - OneS == R1S+(-OneS));
- for (unsigned int i = 1; i < 160; ++i) {
- BOOST_CHECK((MaxS>>i) - (-OneS) == (HalfS >> (i-1)));
- BOOST_CHECK((HalfS >> (i-1)) - OneS == (MaxS>>i));
- TmpS = (HalfS >> (i-1));
- BOOST_CHECK(TmpS-- == (HalfS >> (i-1)));
- BOOST_CHECK(TmpS == (MaxS >> i));
- TmpS = (HalfS >> (i-1));
- BOOST_CHECK(--TmpS == (MaxS >> i));
- }
- TmpS = R1S;
- BOOST_CHECK(--TmpS == R1S-1);
-
-}
-
-BOOST_AUTO_TEST_CASE( multiply )
-{
- BOOST_CHECK((R1L * R1L).ToString() == "62a38c0486f01e45879d7910a7761bf30d5237e9873f9bff3642a732c4d84f10");
- BOOST_CHECK((R1L * R2L).ToString() == "de37805e9986996cfba76ff6ba51c008df851987d9dd323f0e5de07760529c40");
- BOOST_CHECK((R1L * ZeroL) == ZeroL);
- BOOST_CHECK((R1L * OneL) == R1L);
- BOOST_CHECK((R1L * MaxL) == -R1L);
- BOOST_CHECK((R2L * R1L) == (R1L * R2L));
- BOOST_CHECK((R2L * R2L).ToString() == "ac8c010096767d3cae5005dec28bb2b45a1d85ab7996ccd3e102a650f74ff100");
- BOOST_CHECK((R2L * ZeroL) == ZeroL);
- BOOST_CHECK((R2L * OneL) == R2L);
- BOOST_CHECK((R2L * MaxL) == -R2L);
-
- BOOST_CHECK((R1S * R1S).ToString() == "a7761bf30d5237e9873f9bff3642a732c4d84f10");
- BOOST_CHECK((R1S * R2S).ToString() == "ba51c008df851987d9dd323f0e5de07760529c40");
- BOOST_CHECK((R1S * ZeroS) == ZeroS);
- BOOST_CHECK((R1S * OneS) == R1S);
- BOOST_CHECK((R1S * MaxS) == -R1S);
- BOOST_CHECK((R2S * R1S) == (R1S * R2S));
- BOOST_CHECK((R2S * R2S).ToString() == "c28bb2b45a1d85ab7996ccd3e102a650f74ff100");
- BOOST_CHECK((R2S * ZeroS) == ZeroS);
- BOOST_CHECK((R2S * OneS) == R2S);
- BOOST_CHECK((R2S * MaxS) == -R2S);
-
- BOOST_CHECK(MaxL * MaxL == OneL);
- BOOST_CHECK(MaxS * MaxS == OneS);
-
- BOOST_CHECK((R1L * 0) == 0);
- BOOST_CHECK((R1L * 1) == R1L);
- BOOST_CHECK((R1L * 3).ToString() == "7759b1c0ed14047f961ad09b20ff83687876a0181a367b813634046f91def7d4");
- BOOST_CHECK((R2L * 0x87654321UL).ToString() == "23f7816e30c4ae2017257b7a0fa64d60402f5234d46e746b61c960d09a26d070");
- BOOST_CHECK((R1S * 0) == 0);
- BOOST_CHECK((R1S * 1) == R1S);
- BOOST_CHECK((R1S * 7).ToString() == "f7a987f3c3bf758d927f202d7e795faeff084244");
- BOOST_CHECK((R2S * 0xFFFFFFFFUL).ToString() == "1c6f6c930353e17f7d6127213bb18d2883e2cd90");
-}
-
-BOOST_AUTO_TEST_CASE( divide )
-{
- uint256 D1L("AD7133AC1977FA2B7");
- uint256 D2L("ECD751716");
- BOOST_CHECK((R1L / D1L).ToString() == "00000000000000000b8ac01106981635d9ed112290f8895545a7654dde28fb3a");
- BOOST_CHECK((R1L / D2L).ToString() == "000000000873ce8efec5b67150bad3aa8c5fcb70e947586153bf2cec7c37c57a");
- BOOST_CHECK(R1L / OneL == R1L);
- BOOST_CHECK(R1L / MaxL == ZeroL);
- BOOST_CHECK(MaxL / R1L == 2);
- BOOST_CHECK_THROW(R1L / ZeroL, uint_error);
- BOOST_CHECK((R2L / D1L).ToString() == "000000000000000013e1665895a1cc981de6d93670105a6b3ec3b73141b3a3c5");
- BOOST_CHECK((R2L / D2L).ToString() == "000000000e8f0abe753bb0afe2e9437ee85d280be60882cf0bd1aaf7fa3cc2c4");
- BOOST_CHECK(R2L / OneL == R2L);
- BOOST_CHECK(R2L / MaxL == ZeroL);
- BOOST_CHECK(MaxL / R2L == 1);
- BOOST_CHECK_THROW(R2L / ZeroL, uint_error);
-
- uint160 D1S("D3C5EDCDEA54EB92679F0A4B4");
- uint160 D2S("13037");
- BOOST_CHECK((R1S / D1S).ToString() == "0000000000000000000000000db9af3beade6c02");
- BOOST_CHECK((R1S / D2S).ToString() == "000098dfb6cc40ca592bf74366794f298ada205c");
- BOOST_CHECK(R1S / OneS == R1S);
- BOOST_CHECK(R1S / MaxS == ZeroS);
- BOOST_CHECK(MaxS / R1S == 1);
- BOOST_CHECK_THROW(R1S / ZeroS, uint_error);
- BOOST_CHECK((R2S / D1S).ToString() == "0000000000000000000000000c5608e781182047");
- BOOST_CHECK((R2S / D2S).ToString() == "00008966751b7187c3c67c1fda5cea7db2c1c069");
- BOOST_CHECK(R2S / OneS == R2S);
- BOOST_CHECK(R2S / MaxS == ZeroS);
- BOOST_CHECK(MaxS / R2S == 1);
- BOOST_CHECK_THROW(R2S / ZeroS, uint_error);
-}
-
-
-bool almostEqual(double d1, double d2)
-{
- return fabs(d1-d2) <= 4*fabs(d1)*std::numeric_limits<double>::epsilon();
+ BOOST_CHECK( ZeroS < R1S );
+ BOOST_CHECK( R2S < R1S );
+ BOOST_CHECK( ZeroS < OneS );
+ BOOST_CHECK( OneS < MaxS );
+ BOOST_CHECK( R1S < MaxS );
+ BOOST_CHECK( R2S < MaxS );
}
BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize
uint256 TmpL(R1L);
BOOST_CHECK(TmpL == R1L);
TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L);
- TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == 0);
- TmpL.SetHex(HalfL.ToString()); BOOST_CHECK(TmpL == HalfL);
+ TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == uint256());
TmpL.SetHex(R1L.ToString());
BOOST_CHECK(memcmp(R1L.begin(), R1Array, 32)==0);
BOOST_CHECK(memcmp(R2L.begin(), R2Array, 32)==0);
BOOST_CHECK(memcmp(ZeroL.begin(), ZeroArray, 32)==0);
BOOST_CHECK(memcmp(OneL.begin(), OneArray, 32)==0);
+ BOOST_CHECK(R1L.size() == sizeof(R1L));
+ BOOST_CHECK(sizeof(R1L) == 32);
BOOST_CHECK(R1L.size() == 32);
BOOST_CHECK(R2L.size() == 32);
BOOST_CHECK(ZeroL.size() == 32);
BOOST_CHECK(OneL.begin() + 32 == OneL.end());
BOOST_CHECK(MaxL.begin() + 32 == MaxL.end());
BOOST_CHECK(TmpL.begin() + 32 == TmpL.end());
- BOOST_CHECK(R1L.GetLow64() == R1LLow64);
- BOOST_CHECK(HalfL.GetLow64() ==0x0000000000000000ULL);
- BOOST_CHECK(OneL.GetLow64() ==0x0000000000000001ULL);
BOOST_CHECK(R1L.GetSerializeSize(0,PROTOCOL_VERSION) == 32);
BOOST_CHECK(ZeroL.GetSerializeSize(0,PROTOCOL_VERSION) == 32);
uint160 TmpS(R1S);
BOOST_CHECK(TmpS == R1S);
TmpS.SetHex(R2S.ToString()); BOOST_CHECK(TmpS == R2S);
- TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == 0);
- TmpS.SetHex(HalfS.ToString()); BOOST_CHECK(TmpS == HalfS);
+ TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == uint160());
TmpS.SetHex(R1S.ToString());
BOOST_CHECK(memcmp(R1S.begin(), R1Array, 20)==0);
BOOST_CHECK(memcmp(R2S.begin(), R2Array, 20)==0);
BOOST_CHECK(memcmp(ZeroS.begin(), ZeroArray, 20)==0);
BOOST_CHECK(memcmp(OneS.begin(), OneArray, 20)==0);
+ BOOST_CHECK(R1S.size() == sizeof(R1S));
+ BOOST_CHECK(sizeof(R1S) == 20);
BOOST_CHECK(R1S.size() == 20);
BOOST_CHECK(R2S.size() == 20);
BOOST_CHECK(ZeroS.size() == 20);
BOOST_CHECK(OneS.begin() + 20 == OneS.end());
BOOST_CHECK(MaxS.begin() + 20 == MaxS.end());
BOOST_CHECK(TmpS.begin() + 20 == TmpS.end());
- BOOST_CHECK(R1S.GetLow64() == R1LLow64);
- BOOST_CHECK(HalfS.GetLow64() ==0x0000000000000000ULL);
- BOOST_CHECK(OneS.GetLow64() ==0x0000000000000001ULL);
BOOST_CHECK(R1S.GetSerializeSize(0,PROTOCOL_VERSION) == 20);
BOOST_CHECK(ZeroS.GetSerializeSize(0,PROTOCOL_VERSION) == 20);
TmpS.Unserialize(ss,0,PROTOCOL_VERSION);
BOOST_CHECK(MaxS == TmpS);
ss.str("");
-
- for (unsigned int i = 0; i < 255; ++i)
- {
- BOOST_CHECK((OneL << i).getdouble() == ldexp(1.0,i));
- if (i < 160) BOOST_CHECK((OneS << i).getdouble() == ldexp(1.0,i));
- }
- BOOST_CHECK(ZeroL.getdouble() == 0.0);
- BOOST_CHECK(ZeroS.getdouble() == 0.0);
- for (int i = 256; i > 53; --i)
- BOOST_CHECK(almostEqual((R1L>>(256-i)).getdouble(), ldexp(R1Ldouble,i)));
- for (int i = 160; i > 53; --i)
- BOOST_CHECK(almostEqual((R1S>>(160-i)).getdouble(), ldexp(R1Sdouble,i)));
- uint64_t R1L64part = (R1L>>192).GetLow64();
- uint64_t R1S64part = (R1S>>96).GetLow64();
- for (int i = 53; i > 0; --i) // doubles can store all integers in {0,...,2^54-1} exactly
- {
- BOOST_CHECK((R1L>>(256-i)).getdouble() == (double)(R1L64part >> (64-i)));
- BOOST_CHECK((R1S>>(160-i)).getdouble() == (double)(R1S64part >> (64-i)));
- }
}
-BOOST_AUTO_TEST_CASE(bignum_SetCompact)
+BOOST_AUTO_TEST_CASE( conversion )
{
- uint256 num;
- bool fNegative;
- bool fOverflow;
- num.SetCompact(0, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x00123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x01003456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x02000056, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x03000000, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x04000000, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x00923456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x01803456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x02800056, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x03800000, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x04800000, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x01123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000000012");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x01120000U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- // Make sure that we don't generate compacts with the 0x00800000 bit set
- num = 0x80;
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x02008000U);
-
- num.SetCompact(0x01fedcba, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "000000000000000000000000000000000000000000000000000000000000007e");
- BOOST_CHECK_EQUAL(num.GetCompact(true), 0x01fe0000U);
- BOOST_CHECK_EQUAL(fNegative, true);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x02123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000001234");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x02123400U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x03123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000000123456");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x03123456U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x04123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x04123456U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x04923456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000012345600");
- BOOST_CHECK_EQUAL(num.GetCompact(true), 0x04923456U);
- BOOST_CHECK_EQUAL(fNegative, true);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x05009234, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "0000000000000000000000000000000000000000000000000000000092340000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x05009234U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0x20123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(num.GetHex(), "1234560000000000000000000000000000000000000000000000000000000000");
- BOOST_CHECK_EQUAL(num.GetCompact(), 0x20123456U);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, false);
-
- num.SetCompact(0xff123456, &fNegative, &fOverflow);
- BOOST_CHECK_EQUAL(fNegative, false);
- BOOST_CHECK_EQUAL(fOverflow, true);
-}
-
-
-BOOST_AUTO_TEST_CASE( getmaxcoverage ) // some more tests just to get 100% coverage
-{
- // ~R1L give a base_uint<256>
- BOOST_CHECK((~~R1L >> 10) == (R1L >> 10)); BOOST_CHECK((~~R1S >> 10) == (R1S >> 10));
- BOOST_CHECK((~~R1L << 10) == (R1L << 10)); BOOST_CHECK((~~R1S << 10) == (R1S << 10));
- BOOST_CHECK(!(~~R1L < R1L)); BOOST_CHECK(!(~~R1S < R1S));
- BOOST_CHECK(~~R1L <= R1L); BOOST_CHECK(~~R1S <= R1S);
- BOOST_CHECK(!(~~R1L > R1L)); BOOST_CHECK(!(~~R1S > R1S));
- BOOST_CHECK(~~R1L >= R1L); BOOST_CHECK(~~R1S >= R1S);
- BOOST_CHECK(!(R1L < ~~R1L)); BOOST_CHECK(!(R1S < ~~R1S));
- BOOST_CHECK(R1L <= ~~R1L); BOOST_CHECK(R1S <= ~~R1S);
- BOOST_CHECK(!(R1L > ~~R1L)); BOOST_CHECK(!(R1S > ~~R1S));
- BOOST_CHECK(R1L >= ~~R1L); BOOST_CHECK(R1S >= ~~R1S);
-
- BOOST_CHECK(~~R1L + R2L == R1L + ~~R2L);
- BOOST_CHECK(~~R1S + R2S == R1S + ~~R2S);
- BOOST_CHECK(~~R1L - R2L == R1L - ~~R2L);
- BOOST_CHECK(~~R1S - R2S == R1S - ~~R2S);
- BOOST_CHECK(~R1L != R1L); BOOST_CHECK(R1L != ~R1L);
- BOOST_CHECK(~R1S != R1S); BOOST_CHECK(R1S != ~R1S);
- unsigned char TmpArray[32];
- CHECKBITWISEOPERATOR(~R1,R2,|)
- CHECKBITWISEOPERATOR(~R1,R2,^)
- CHECKBITWISEOPERATOR(~R1,R2,&)
- CHECKBITWISEOPERATOR(R1,~R2,|)
- CHECKBITWISEOPERATOR(R1,~R2,^)
- CHECKBITWISEOPERATOR(R1,~R2,&)
+ BOOST_CHECK(ArithToUint256(UintToArith256(ZeroL)) == ZeroL);
+ BOOST_CHECK(ArithToUint256(UintToArith256(OneL)) == OneL);
+ BOOST_CHECK(ArithToUint256(UintToArith256(R1L)) == R1L);
+ BOOST_CHECK(ArithToUint256(UintToArith256(R2L)) == R2L);
+ BOOST_CHECK(UintToArith256(ZeroL) == 0);
+ BOOST_CHECK(UintToArith256(OneL) == 1);
+ BOOST_CHECK(ArithToUint256(0) == ZeroL);
+ BOOST_CHECK(ArithToUint256(1) == OneL);
+ BOOST_CHECK(arith_uint256(R1L.GetHex()) == UintToArith256(R1L));
+ BOOST_CHECK(arith_uint256(R2L.GetHex()) == UintToArith256(R2L));
+ BOOST_CHECK(R1L.GetHex() == UintToArith256(R1L).GetHex());
+ BOOST_CHECK(R2L.GetHex() == UintToArith256(R2L).GetHex());
}
BOOST_AUTO_TEST_SUITE_END()
-
// Copyright 2014 BitPay, Inc.
-// 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 <stdint.h>
#include <string>
#include <map>
#include "univalue/univalue.h"
+#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
using namespace std;
-BOOST_AUTO_TEST_SUITE(univalue_tests)
+BOOST_FIXTURE_TEST_SUITE(univalue_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(univalue_constructor)
{
// Copyright (c) 2011-2014 The Bitcoin Core 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 "util.h"
#include "clientversion.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "random.h"
#include "sync.h"
#include "utilstrencodings.h"
#include "utilmoneystr.h"
+#include "test/test_bitcoin.h"
#include <stdint.h>
#include <vector>
using namespace std;
-BOOST_AUTO_TEST_SUITE(util_tests)
+BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(util_criticalsection)
{
{
int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */
uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */
- BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 "E);
- BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 "E);
- BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff "E);
+ BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 " E);
+ BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 " E);
+ BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff " E);
size_t st = 12345678; /* unsigned size_t test value */
ssize_t sst = -12345678; /* signed size_t test value */
- BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 "E);
- BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 "E);
- BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e "E);
+ BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 " E);
+ BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 " E);
+ BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e " E);
ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */
ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */
- BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 "E);
- BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 "E);
- BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 "E);
+ BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 " E);
+ BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 " E);
+ BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 " E);
}
#undef B
#undef E
BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 0), "test\ntest");
BOOST_CHECK_EQUAL(FormatParagraph("testerde test ", 4, 0), "testerde\ntest");
BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 4), "test\n test");
+ BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string. This is a second sentence in the very long test string."), "This is a very long test string. This is a second sentence in the very long\ntest string.");
}
BOOST_AUTO_TEST_CASE(test_FormatSubVersion)
// Copyright (c) 2012-2014 The Bitcoin Core 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 "wallet.h"
#include <utility>
#include <vector>
+#include "test/test_bitcoin.h"
+
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
typedef set<pair<const CWalletTx*,unsigned int> > CoinSet;
-BOOST_AUTO_TEST_SUITE(wallet_tests)
+BOOST_FIXTURE_TEST_SUITE(wallet_tests, TestingSetup)
static CWallet wallet;
static vector<COutput> vCoins;
// 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-2012 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_THREADSAFETY_H
-// Copyright (c) 2014 The Bitcoin developers
+// 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.
return (n >= 0 ? n : -n);
}
-void AddTimeData(const CNetAddr& ip, int64_t nTime)
+void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
{
- int64_t nOffsetSample = nTime - GetTime();
-
LOCK(cs_nTimeOffset);
// Ignore duplicates
static set<CNetAddr> setKnown;
-// Copyright (c) 2014 The Bitcoin developers
+// 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.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "txdb.h"
using namespace std;
+static const char DB_COINS = 'c';
+static const char DB_BLOCK_FILES = 'f';
+static const char DB_TXINDEX = 't';
+static const char DB_BLOCK_INDEX = 'b';
+
+static const char DB_BEST_BLOCK = 'B';
+static const char DB_FLAG = 'F';
+static const char DB_REINDEX_FLAG = 'R';
+static const char DB_LAST_BLOCK = 'l';
+
+
void static BatchWriteCoins(CLevelDBBatch &batch, const uint256 &hash, const CCoins &coins) {
if (coins.IsPruned())
- batch.Erase(make_pair('c', hash));
+ batch.Erase(make_pair(DB_COINS, hash));
else
- batch.Write(make_pair('c', hash), coins);
+ batch.Write(make_pair(DB_COINS, hash), coins);
}
void static BatchWriteHashBestChain(CLevelDBBatch &batch, const uint256 &hash) {
- batch.Write('B', hash);
+ batch.Write(DB_BEST_BLOCK, hash);
}
CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) {
}
bool CCoinsViewDB::GetCoins(const uint256 &txid, CCoins &coins) const {
- return db.Read(make_pair('c', txid), coins);
+ return db.Read(make_pair(DB_COINS, txid), coins);
}
bool CCoinsViewDB::HaveCoins(const uint256 &txid) const {
- return db.Exists(make_pair('c', txid));
+ return db.Exists(make_pair(DB_COINS, txid));
}
uint256 CCoinsViewDB::GetBestBlock() const {
uint256 hashBestChain;
- if (!db.Read('B', hashBestChain))
- return uint256(0);
+ if (!db.Read(DB_BEST_BLOCK, hashBestChain))
+ return uint256();
return hashBestChain;
}
CCoinsMap::iterator itOld = it++;
mapCoins.erase(itOld);
}
- if (hashBlock != uint256(0))
+ if (!hashBlock.IsNull())
BatchWriteHashBestChain(batch, hashBlock);
LogPrint("coindb", "Committing %u changed transactions (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count);
CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevelDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) {
}
-bool CBlockTreeDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)
-{
- return Write(make_pair('b', blockindex.GetBlockHash()), blockindex);
-}
-
-bool CBlockTreeDB::WriteBlockFileInfo(int nFile, const CBlockFileInfo &info) {
- return Write(make_pair('f', nFile), info);
-}
-
bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) {
- return Read(make_pair('f', nFile), info);
-}
-
-bool CBlockTreeDB::WriteLastBlockFile(int nFile) {
- return Write('l', nFile);
+ return Read(make_pair(DB_BLOCK_FILES, nFile), info);
}
bool CBlockTreeDB::WriteReindexing(bool fReindexing) {
if (fReindexing)
- return Write('R', '1');
+ return Write(DB_REINDEX_FLAG, '1');
else
- return Erase('R');
+ return Erase(DB_REINDEX_FLAG);
}
bool CBlockTreeDB::ReadReindexing(bool &fReindexing) {
- fReindexing = Exists('R');
+ fReindexing = Exists(DB_REINDEX_FLAG);
return true;
}
bool CBlockTreeDB::ReadLastBlockFile(int &nFile) {
- return Read('l', nFile);
+ return Read(DB_LAST_BLOCK, nFile);
}
bool CCoinsViewDB::GetStats(CCoinsStats &stats) const {
CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
char chType;
ssKey >> chType;
- if (chType == 'c') {
+ if (chType == DB_COINS) {
leveldb::Slice slValue = pcursor->value();
CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
CCoins coins;
ss << VARINT(0);
}
pcursor->Next();
- } catch (std::exception &e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ } catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
}
stats.nHeight = mapBlockIndex.find(GetBestBlock())->second->nHeight;
return true;
}
+bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) {
+ CLevelDBBatch batch;
+ for (std::vector<std::pair<int, const CBlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) {
+ batch.Write(make_pair(DB_BLOCK_FILES, it->first), *it->second);
+ }
+ batch.Write(DB_LAST_BLOCK, nLastFile);
+ for (std::vector<const CBlockIndex*>::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) {
+ batch.Write(make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it));
+ }
+ return WriteBatch(batch, true);
+}
+
bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) {
- return Read(make_pair('t', txid), pos);
+ return Read(make_pair(DB_TXINDEX, txid), pos);
}
bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> >&vect) {
CLevelDBBatch batch;
for (std::vector<std::pair<uint256,CDiskTxPos> >::const_iterator it=vect.begin(); it!=vect.end(); it++)
- batch.Write(make_pair('t', it->first), it->second);
+ batch.Write(make_pair(DB_TXINDEX, it->first), it->second);
return WriteBatch(batch);
}
bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
- return Write(std::make_pair('F', name), fValue ? '1' : '0');
+ return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0');
}
bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
char ch;
- if (!Read(std::make_pair('F', name), ch))
+ if (!Read(std::make_pair(DB_FLAG, name), ch))
return false;
fValue = ch == '1';
return true;
boost::scoped_ptr<leveldb::Iterator> pcursor(NewIterator());
CDataStream ssKeySet(SER_DISK, CLIENT_VERSION);
- ssKeySet << make_pair('b', uint256(0));
+ ssKeySet << make_pair(DB_BLOCK_INDEX, uint256());
pcursor->Seek(ssKeySet.str());
// Load mapBlockIndex
CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
char chType;
ssKey >> chType;
- if (chType == 'b') {
+ if (chType == DB_BLOCK_INDEX) {
leveldb::Slice slValue = pcursor->value();
CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
CDiskBlockIndex diskindex;
pindexNew->nTx = diskindex.nTx;
if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits))
- return error("LoadBlockIndex() : CheckProofOfWork failed: %s", pindexNew->ToString());
+ return error("LoadBlockIndex(): CheckProofOfWork failed: %s", pindexNew->ToString());
pcursor->Next();
} else {
break; // if shutdown requested or finished loading block index
}
- } catch (std::exception &e) {
- return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ } catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
}
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
CBlockTreeDB(const CBlockTreeDB&);
void operator=(const CBlockTreeDB&);
public:
- bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
+ bool WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo);
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo);
- bool WriteBlockFileInfo(int nFile, const CBlockFileInfo &fileinfo);
bool ReadLastBlockFile(int &nFile);
- bool WriteLastBlockFile(int nFile);
bool WriteReindexing(bool fReindex);
bool ReadReindexing(bool &fReindex);
bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos);
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "txmempool.h"
#include "clientversion.h"
+#include "main.h"
#include "streams.h"
#include "util.h"
#include "utilmoneystr.h"
* Used as belt-and-suspenders check when reading to detect
* file corruption
*/
- bool AreSane(const std::vector<CFeeRate>& vecFee, const CFeeRate& minRelayFee)
+ static bool AreSane(const CFeeRate fee, const CFeeRate& minRelayFee)
+ {
+ if (fee < CFeeRate(0))
+ return false;
+ if (fee.GetFeePerK() > minRelayFee.GetFeePerK() * 10000)
+ return false;
+ return true;
+ }
+ static bool AreSane(const std::vector<CFeeRate>& vecFee, const CFeeRate& minRelayFee)
{
BOOST_FOREACH(CFeeRate fee, vecFee)
{
- if (fee < CFeeRate(0))
- return false;
- if (fee.GetFeePerK() > minRelayFee.GetFeePerK() * 10000)
+ if (!AreSane(fee, minRelayFee))
return false;
}
return true;
}
- bool AreSane(const std::vector<double> vecPriority)
+ static bool AreSane(const double priority)
+ {
+ return priority >= 0;
+ }
+ static bool AreSane(const std::vector<double> vecPriority)
{
BOOST_FOREACH(double priority, vecPriority)
{
- if (priority < 0)
+ if (!AreSane(priority))
return false;
}
return true;
bool sufficientFee = (feeRate > minRelayFee);
bool sufficientPriority = AllowFree(dPriority);
const char* assignedTo = "unassigned";
- if (sufficientFee && !sufficientPriority)
+ if (sufficientFee && !sufficientPriority && CBlockAverage::AreSane(feeRate, minRelayFee))
{
history[nBlocksTruncated].RecordFee(feeRate);
assignedTo = "fee";
}
- else if (sufficientPriority && !sufficientFee)
+ else if (sufficientPriority && !sufficientFee && CBlockAverage::AreSane(dPriority))
{
history[nBlocksTruncated].RecordPriority(dPriority);
assignedTo = "priority";
// Neither or both fee and priority sufficient to get confirmed:
// don't know why they got confirmed.
}
- LogPrint("estimatefee", "Seen TX confirm: %s : %s fee/%g priority, took %d blocks\n",
+ LogPrint("estimatefee", "Seen TX confirm: %s: %s fee/%g priority, took %d blocks\n",
assignedTo, feeRate.ToString(), dPriority, nBlocksAgo);
}
}
}
- //After new samples are added, we have to clear the sorted lists,
- //so they'll be resorted the next time someone asks for an estimate
+ // After new samples are added, we have to clear the sorted lists,
+ // so they'll be resorted the next time someone asks for an estimate
sortedFeeSamples.clear();
sortedPrioritySamples.clear();
void Write(CAutoFile& fileout) const
{
fileout << nBestSeenHeight;
- fileout << history.size();
+ fileout << (uint32_t)history.size();
BOOST_FOREACH(const CBlockAverage& entry, history)
{
entry.Write(fileout);
{
int nFileBestSeenHeight;
filein >> nFileBestSeenHeight;
- size_t numEntries;
+ uint32_t numEntries;
filein >> numEntries;
if (numEntries <= 0 || numEntries > 10000)
throw runtime_error("Corrupt estimates file. Must have between 1 and 10k entries.");
}
-void CTxMemPool::remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive)
+void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& removed, bool fRecursive)
{
// Remove transaction from memory pool
{
LOCK(cs);
- uint256 hash = tx.GetHash();
- if (fRecursive) {
- for (unsigned int i = 0; i < tx.vout.size(); i++) {
- std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(hash, i));
- if (it == mapNextTx.end())
- continue;
- remove(*it->second.ptx, removed, true);
- }
- }
- if (mapTx.count(hash))
+ std::deque<uint256> txToRemove;
+ txToRemove.push_back(origTx.GetHash());
+ while (!txToRemove.empty())
{
- removed.push_front(tx);
+ uint256 hash = txToRemove.front();
+ txToRemove.pop_front();
+ if (!mapTx.count(hash))
+ continue;
+ const CTransaction& tx = mapTx[hash].GetTx();
+ if (fRecursive) {
+ for (unsigned int i = 0; i < tx.vout.size(); i++) {
+ std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(hash, i));
+ if (it == mapNextTx.end())
+ continue;
+ txToRemove.push_back(it->second.ptx->GetHash());
+ }
+ }
BOOST_FOREACH(const CTxIn& txin, tx.vin)
mapNextTx.erase(txin.prevout);
+ removed.push_back(tx);
totalTxSize -= mapTx[hash].GetTxSize();
mapTx.erase(hash);
nTransactionsUpdated++;
}
}
+void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight)
+{
+ // Remove transactions spending a coinbase which are now immature
+ LOCK(cs);
+ list<CTransaction> transactionsToRemove;
+ for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
+ const CTransaction& tx = it->second.GetTx();
+ BOOST_FOREACH(const CTxIn& txin, tx.vin) {
+ std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash);
+ if (it2 != mapTx.end())
+ continue;
+ const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
+ if (fSanityCheck) assert(coins);
+ if (!coins || (coins->IsCoinBase() && nMemPoolHeight - coins->nHeight < COINBASE_MATURITY)) {
+ transactionsToRemove.push_back(tx);
+ break;
+ }
+ }
+ }
+ BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) {
+ list<CTransaction> removed;
+ remove(tx, removed, true);
+ }
+}
+
void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed)
{
// Remove transactions which depend on inputs of tx, recursively
uint64_t checkTotal = 0;
+ CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(pcoins));
+
LOCK(cs);
+ list<const CTxMemPoolEntry*> waitingOnDependants;
for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
unsigned int i = 0;
checkTotal += it->second.GetTxSize();
const CTransaction& tx = it->second.GetTx();
+ bool fDependsWait = false;
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
// Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash);
if (it2 != mapTx.end()) {
const CTransaction& tx2 = it2->second.GetTx();
assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
+ fDependsWait = true;
} else {
const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash);
assert(coins && coins->IsAvailable(txin.prevout.n));
assert(it3->second.n == i);
i++;
}
+ if (fDependsWait)
+ waitingOnDependants.push_back(&it->second);
+ else {
+ CValidationState state;
+ assert(CheckInputs(tx, state, mempoolDuplicate, false, 0, false, NULL));
+ UpdateCoins(tx, state, mempoolDuplicate, 1000000);
+ }
+ }
+ unsigned int stepsSinceLastRemove = 0;
+ while (!waitingOnDependants.empty()) {
+ const CTxMemPoolEntry* entry = waitingOnDependants.front();
+ waitingOnDependants.pop_front();
+ CValidationState state;
+ if (!mempoolDuplicate.HaveInputs(entry->GetTx())) {
+ waitingOnDependants.push_back(entry);
+ stepsSinceLastRemove++;
+ assert(stepsSinceLastRemove < waitingOnDependants.size());
+ } else {
+ assert(CheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, NULL));
+ UpdateCoins(entry->GetTx(), state, mempoolDuplicate, 1000000);
+ stepsSinceLastRemove = 0;
+ }
}
for (std::map<COutPoint, CInPoint>::const_iterator it = mapNextTx.begin(); it != mapNextTx.end(); it++) {
uint256 hash = it->second.ptx->GetHash();
fileout << CLIENT_VERSION; // version that wrote the file
minerPolicyEstimator->Write(fileout);
}
- catch (const std::exception &) {
- LogPrintf("CTxMemPool::WriteFeeEstimates() : unable to write policy estimator data (non-fatal)");
+ catch (const std::exception&) {
+ LogPrintf("CTxMemPool::WriteFeeEstimates(): unable to write policy estimator data (non-fatal)");
return false;
}
return true;
int nVersionRequired, nVersionThatWrote;
filein >> nVersionRequired >> nVersionThatWrote;
if (nVersionRequired > CLIENT_VERSION)
- return error("CTxMemPool::ReadFeeEstimates() : up-version (%d) fee estimate file", nVersionRequired);
+ return error("CTxMemPool::ReadFeeEstimates(): up-version (%d) fee estimate file", nVersionRequired);
LOCK(cs);
minerPolicyEstimator->Read(filein, minRelayFee);
}
- catch (const std::exception &) {
- LogPrintf("CTxMemPool::ReadFeeEstimates() : unable to read policy estimator data (non-fatal)");
+ catch (const std::exception&) {
+ LogPrintf("CTxMemPool::ReadFeeEstimates(): unable to read policy estimator data (non-fatal)");
return false;
}
return true;
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "amount.h"
#include "coins.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "sync.h"
class CAutoFile;
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry);
void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false);
+ void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight);
void removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed);
void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
std::list<CTransaction>& conflicts);
// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2012 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2012 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_UI_INTERFACE_H
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "uint256.h"
#include <string.h>
template <unsigned int BITS>
-base_uint<BITS>::base_uint(const std::string& str)
+base_blob<BITS>::base_blob(const std::vector<unsigned char>& vch)
{
- SetHex(str);
+ assert(vch.size() == sizeof(data));
+ memcpy(data, &vch[0], sizeof(data));
}
template <unsigned int BITS>
-base_uint<BITS>::base_uint(const std::vector<unsigned char>& vch)
+std::string base_blob<BITS>::GetHex() const
{
- if (vch.size() != sizeof(pn))
- throw uint_error("Converting vector of wrong size to base_uint");
- memcpy(pn, &vch[0], sizeof(pn));
+ char psz[sizeof(data) * 2 + 1];
+ for (unsigned int i = 0; i < sizeof(data); i++)
+ sprintf(psz + i * 2, "%02x", data[sizeof(data) - i - 1]);
+ return std::string(psz, psz + sizeof(data) * 2);
}
template <unsigned int BITS>
-base_uint<BITS>& base_uint<BITS>::operator<<=(unsigned int shift)
+void base_blob<BITS>::SetHex(const char* psz)
{
- base_uint<BITS> a(*this);
- for (int i = 0; i < WIDTH; i++)
- pn[i] = 0;
- int k = shift / 32;
- shift = shift % 32;
- for (int i = 0; i < WIDTH; i++) {
- if (i + k + 1 < WIDTH && shift != 0)
- pn[i + k + 1] |= (a.pn[i] >> (32 - shift));
- if (i + k < WIDTH)
- pn[i + k] |= (a.pn[i] << shift);
- }
- return *this;
-}
-
-template <unsigned int BITS>
-base_uint<BITS>& base_uint<BITS>::operator>>=(unsigned int shift)
-{
- base_uint<BITS> a(*this);
- for (int i = 0; i < WIDTH; i++)
- pn[i] = 0;
- int k = shift / 32;
- shift = shift % 32;
- for (int i = 0; i < WIDTH; i++) {
- if (i - k - 1 >= 0 && shift != 0)
- pn[i - k - 1] |= (a.pn[i] << (32 - shift));
- if (i - k >= 0)
- pn[i - k] |= (a.pn[i] >> shift);
- }
- return *this;
-}
-
-template <unsigned int BITS>
-base_uint<BITS>& base_uint<BITS>::operator*=(uint32_t b32)
-{
- uint64_t carry = 0;
- for (int i = 0; i < WIDTH; i++) {
- uint64_t n = carry + (uint64_t)b32 * pn[i];
- pn[i] = n & 0xffffffff;
- carry = n >> 32;
- }
- return *this;
-}
-
-template <unsigned int BITS>
-base_uint<BITS>& base_uint<BITS>::operator*=(const base_uint& b)
-{
- base_uint<BITS> a = *this;
- *this = 0;
- for (int j = 0; j < WIDTH; j++) {
- uint64_t carry = 0;
- for (int i = 0; i + j < WIDTH; i++) {
- uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i];
- pn[i + j] = n & 0xffffffff;
- carry = n >> 32;
- }
- }
- return *this;
-}
-
-template <unsigned int BITS>
-base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b)
-{
- base_uint<BITS> div = b; // make a copy, so we can shift.
- base_uint<BITS> num = *this; // make a copy, so we can subtract.
- *this = 0; // the quotient.
- int num_bits = num.bits();
- int div_bits = div.bits();
- if (div_bits == 0)
- throw uint_error("Division by zero");
- if (div_bits > num_bits) // the result is certainly 0.
- return *this;
- int shift = num_bits - div_bits;
- div <<= shift; // shift so that div and nun align.
- while (shift >= 0) {
- if (num >= div) {
- num -= div;
- pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result.
- }
- div >>= 1; // shift back.
- shift--;
- }
- // num now contains the remainder of the division.
- return *this;
-}
-
-template <unsigned int BITS>
-int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const
-{
- for (int i = WIDTH - 1; i >= 0; i--) {
- if (pn[i] < b.pn[i])
- return -1;
- if (pn[i] > b.pn[i])
- return 1;
- }
- return 0;
-}
-
-template <unsigned int BITS>
-bool base_uint<BITS>::EqualTo(uint64_t b) const
-{
- for (int i = WIDTH - 1; i >= 2; i--) {
- if (pn[i])
- return false;
- }
- if (pn[1] != (b >> 32))
- return false;
- if (pn[0] != (b & 0xfffffffful))
- return false;
- return true;
-}
-
-template <unsigned int BITS>
-double base_uint<BITS>::getdouble() const
-{
- double ret = 0.0;
- double fact = 1.0;
- for (int i = 0; i < WIDTH; i++) {
- ret += fact * pn[i];
- fact *= 4294967296.0;
- }
- return ret;
-}
-
-template <unsigned int BITS>
-std::string base_uint<BITS>::GetHex() const
-{
- char psz[sizeof(pn) * 2 + 1];
- for (unsigned int i = 0; i < sizeof(pn); i++)
- sprintf(psz + i * 2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]);
- return std::string(psz, psz + sizeof(pn) * 2);
-}
-
-template <unsigned int BITS>
-void base_uint<BITS>::SetHex(const char* psz)
-{
- memset(pn, 0, sizeof(pn));
+ memset(data, 0, sizeof(data));
// skip leading spaces
while (isspace(*psz))
while (::HexDigit(*psz) != -1)
psz++;
psz--;
- unsigned char* p1 = (unsigned char*)pn;
- unsigned char* pend = p1 + WIDTH * 4;
+ unsigned char* p1 = (unsigned char*)data;
+ unsigned char* pend = p1 + WIDTH;
while (psz >= pbegin && p1 < pend) {
*p1 = ::HexDigit(*psz--);
if (psz >= pbegin) {
}
template <unsigned int BITS>
-void base_uint<BITS>::SetHex(const std::string& str)
+void base_blob<BITS>::SetHex(const std::string& str)
{
SetHex(str.c_str());
}
template <unsigned int BITS>
-std::string base_uint<BITS>::ToString() const
+std::string base_blob<BITS>::ToString() const
{
return (GetHex());
}
-template <unsigned int BITS>
-unsigned int base_uint<BITS>::bits() const
-{
- for (int pos = WIDTH - 1; pos >= 0; pos--) {
- if (pn[pos]) {
- for (int bits = 31; bits > 0; bits--) {
- if (pn[pos] & 1 << bits)
- return 32 * pos + bits + 1;
- }
- return 32 * pos + 1;
- }
- }
- return 0;
-}
-
-// Explicit instantiations for base_uint<160>
-template base_uint<160>::base_uint(const std::string&);
-template base_uint<160>::base_uint(const std::vector<unsigned char>&);
-template base_uint<160>& base_uint<160>::operator<<=(unsigned int);
-template base_uint<160>& base_uint<160>::operator>>=(unsigned int);
-template base_uint<160>& base_uint<160>::operator*=(uint32_t b32);
-template base_uint<160>& base_uint<160>::operator*=(const base_uint<160>& b);
-template base_uint<160>& base_uint<160>::operator/=(const base_uint<160>& b);
-template int base_uint<160>::CompareTo(const base_uint<160>&) const;
-template bool base_uint<160>::EqualTo(uint64_t) const;
-template double base_uint<160>::getdouble() const;
-template std::string base_uint<160>::GetHex() const;
-template std::string base_uint<160>::ToString() const;
-template void base_uint<160>::SetHex(const char*);
-template void base_uint<160>::SetHex(const std::string&);
-template unsigned int base_uint<160>::bits() const;
+// Explicit instantiations for base_blob<160>
+template base_blob<160>::base_blob(const std::vector<unsigned char>&);
+template std::string base_blob<160>::GetHex() const;
+template std::string base_blob<160>::ToString() const;
+template void base_blob<160>::SetHex(const char*);
+template void base_blob<160>::SetHex(const std::string&);
-// Explicit instantiations for base_uint<256>
-template base_uint<256>::base_uint(const std::string&);
-template base_uint<256>::base_uint(const std::vector<unsigned char>&);
-template base_uint<256>& base_uint<256>::operator<<=(unsigned int);
-template base_uint<256>& base_uint<256>::operator>>=(unsigned int);
-template base_uint<256>& base_uint<256>::operator*=(uint32_t b32);
-template base_uint<256>& base_uint<256>::operator*=(const base_uint<256>& b);
-template base_uint<256>& base_uint<256>::operator/=(const base_uint<256>& b);
-template int base_uint<256>::CompareTo(const base_uint<256>&) const;
-template bool base_uint<256>::EqualTo(uint64_t) const;
-template double base_uint<256>::getdouble() const;
-template std::string base_uint<256>::GetHex() const;
-template std::string base_uint<256>::ToString() const;
-template void base_uint<256>::SetHex(const char*);
-template void base_uint<256>::SetHex(const std::string&);
-template unsigned int base_uint<256>::bits() const;
-
-// This implementation directly uses shifts instead of going
-// through an intermediate MPI representation.
-uint256& uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow)
-{
- int nSize = nCompact >> 24;
- uint32_t nWord = nCompact & 0x007fffff;
- if (nSize <= 3) {
- nWord >>= 8 * (3 - nSize);
- *this = nWord;
- } else {
- *this = nWord;
- *this <<= 8 * (nSize - 3);
- }
- if (pfNegative)
- *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
- if (pfOverflow)
- *pfOverflow = nWord != 0 && ((nSize > 34) ||
- (nWord > 0xff && nSize > 33) ||
- (nWord > 0xffff && nSize > 32));
- return *this;
-}
-
-uint32_t uint256::GetCompact(bool fNegative) const
-{
- int nSize = (bits() + 7) / 8;
- uint32_t nCompact = 0;
- if (nSize <= 3) {
- nCompact = GetLow64() << 8 * (3 - nSize);
- } else {
- uint256 bn = *this >> 8 * (nSize - 3);
- nCompact = bn.GetLow64();
- }
- // The 0x00800000 bit denotes the sign.
- // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
- if (nCompact & 0x00800000) {
- nCompact >>= 8;
- nSize++;
- }
- assert((nCompact & ~0x007fffff) == 0);
- assert(nSize < 256);
- nCompact |= nSize << 24;
- nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
- return nCompact;
-}
+// Explicit instantiations for base_blob<256>
+template base_blob<256>::base_blob(const std::vector<unsigned char>&);
+template std::string base_blob<256>::GetHex() const;
+template std::string base_blob<256>::ToString() const;
+template void base_blob<256>::SetHex(const char*);
+template void base_blob<256>::SetHex(const std::string&);
static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c)
{
uint64_t uint256::GetHash(const uint256& salt) const
{
uint32_t a, b, c;
- a = b = c = 0xdeadbeef + (WIDTH << 2);
+ const uint32_t *pn = (const uint32_t*)data;
+ const uint32_t *salt_pn = (const uint32_t*)salt.data;
+ a = b = c = 0xdeadbeef + WIDTH;
- a += pn[0] ^ salt.pn[0];
- b += pn[1] ^ salt.pn[1];
- c += pn[2] ^ salt.pn[2];
+ a += pn[0] ^ salt_pn[0];
+ b += pn[1] ^ salt_pn[1];
+ c += pn[2] ^ salt_pn[2];
HashMix(a, b, c);
- a += pn[3] ^ salt.pn[3];
- b += pn[4] ^ salt.pn[4];
- c += pn[5] ^ salt.pn[5];
+ a += pn[3] ^ salt_pn[3];
+ b += pn[4] ^ salt_pn[4];
+ c += pn[5] ^ salt_pn[5];
HashMix(a, b, c);
- a += pn[6] ^ salt.pn[6];
- b += pn[7] ^ salt.pn[7];
+ a += pn[6] ^ salt_pn[6];
+ b += pn[7] ^ salt_pn[7];
HashFinal(a, b, c);
return ((((uint64_t)b) << 32) | c);
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>
#include <vector>
-class uint_error : public std::runtime_error {
-public:
- explicit uint_error(const std::string& str) : std::runtime_error(str) {}
-};
-
-/** Template base class for unsigned big integers. */
+/** Template base class for fixed-sized opaque blobs. */
template<unsigned int BITS>
-class base_uint
+class base_blob
{
protected:
- enum { WIDTH=BITS/32 };
- uint32_t pn[WIDTH];
+ enum { WIDTH=BITS/8 };
+ uint8_t data[WIDTH];
public:
-
- base_uint()
+ base_blob()
{
- for (int i = 0; i < WIDTH; i++)
- pn[i] = 0;
+ memset(data, 0, sizeof(data));
}
- base_uint(const base_uint& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] = b.pn[i];
- }
+ explicit base_blob(const std::vector<unsigned char>& vch);
- base_uint& operator=(const base_uint& b)
+ bool IsNull() const
{
for (int i = 0; i < WIDTH; i++)
- pn[i] = b.pn[i];
- return *this;
- }
-
- base_uint(uint64_t b)
- {
- pn[0] = (unsigned int)b;
- pn[1] = (unsigned int)(b >> 32);
- for (int i = 2; i < WIDTH; i++)
- pn[i] = 0;
- }
-
- explicit base_uint(const std::string& str);
- explicit base_uint(const std::vector<unsigned char>& vch);
-
- bool operator!() const
- {
- for (int i = 0; i < WIDTH; i++)
- if (pn[i] != 0)
+ if (data[i] != 0)
return false;
return true;
}
- const base_uint operator~() const
- {
- base_uint ret;
- for (int i = 0; i < WIDTH; i++)
- ret.pn[i] = ~pn[i];
- return ret;
- }
-
- const base_uint operator-() const
- {
- base_uint ret;
- for (int i = 0; i < WIDTH; i++)
- ret.pn[i] = ~pn[i];
- ret++;
- return ret;
- }
-
- double getdouble() const;
-
- base_uint& operator=(uint64_t b)
- {
- pn[0] = (unsigned int)b;
- pn[1] = (unsigned int)(b >> 32);
- for (int i = 2; i < WIDTH; i++)
- pn[i] = 0;
- return *this;
- }
-
- base_uint& operator^=(const base_uint& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] ^= b.pn[i];
- return *this;
- }
-
- base_uint& operator&=(const base_uint& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] &= b.pn[i];
- return *this;
- }
-
- base_uint& operator|=(const base_uint& b)
- {
- for (int i = 0; i < WIDTH; i++)
- pn[i] |= b.pn[i];
- return *this;
- }
-
- base_uint& operator^=(uint64_t b)
- {
- pn[0] ^= (unsigned int)b;
- pn[1] ^= (unsigned int)(b >> 32);
- return *this;
- }
-
- base_uint& operator|=(uint64_t b)
+ void SetNull()
{
- pn[0] |= (unsigned int)b;
- pn[1] |= (unsigned int)(b >> 32);
- return *this;
+ memset(data, 0, sizeof(data));
}
- base_uint& operator<<=(unsigned int shift);
- base_uint& operator>>=(unsigned int shift);
-
- base_uint& operator+=(const base_uint& b)
- {
- uint64_t carry = 0;
- for (int i = 0; i < WIDTH; i++)
- {
- uint64_t n = carry + pn[i] + b.pn[i];
- pn[i] = n & 0xffffffff;
- carry = n >> 32;
- }
- return *this;
- }
-
- base_uint& operator-=(const base_uint& b)
- {
- *this += -b;
- return *this;
- }
-
- base_uint& operator+=(uint64_t b64)
- {
- base_uint b;
- b = b64;
- *this += b;
- return *this;
- }
-
- base_uint& operator-=(uint64_t b64)
- {
- base_uint b;
- b = b64;
- *this += -b;
- return *this;
- }
-
- base_uint& operator*=(uint32_t b32);
- base_uint& operator*=(const base_uint& b);
- base_uint& operator/=(const base_uint& b);
-
- base_uint& operator++()
- {
- // prefix operator
- int i = 0;
- while (++pn[i] == 0 && i < WIDTH-1)
- i++;
- return *this;
- }
-
- const base_uint operator++(int)
- {
- // postfix operator
- const base_uint ret = *this;
- ++(*this);
- return ret;
- }
-
- base_uint& operator--()
- {
- // prefix operator
- int i = 0;
- while (--pn[i] == (uint32_t)-1 && i < WIDTH-1)
- i++;
- return *this;
- }
-
- const base_uint operator--(int)
- {
- // postfix operator
- const base_uint ret = *this;
- --(*this);
- return ret;
- }
-
- int CompareTo(const base_uint& b) const;
- bool EqualTo(uint64_t b) const;
-
- friend inline const base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; }
- friend inline const base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; }
- friend inline const base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; }
- friend inline const base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; }
- friend inline const base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; }
- friend inline const base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; }
- friend inline const base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; }
- friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; }
- friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; }
- friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; }
- friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; }
- friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; }
- friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; }
- friend inline bool operator<(const base_uint& a, const base_uint& b) { return a.CompareTo(b) < 0; }
- friend inline bool operator>=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) >= 0; }
- friend inline bool operator<=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) <= 0; }
- friend inline bool operator==(const base_uint& a, uint64_t b) { return a.EqualTo(b); }
- friend inline bool operator!=(const base_uint& a, uint64_t b) { return !a.EqualTo(b); }
+ friend inline bool operator==(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) == 0; }
+ friend inline bool operator!=(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) != 0; }
+ friend inline bool operator<(const base_blob& a, const base_blob& b) { return memcmp(a.data, b.data, sizeof(a.data)) < 0; }
std::string GetHex() const;
void SetHex(const char* psz);
unsigned char* begin()
{
- return (unsigned char*)&pn[0];
+ return &data[0];
}
unsigned char* end()
{
- return (unsigned char*)&pn[WIDTH];
+ return &data[WIDTH];
}
const unsigned char* begin() const
{
- return (unsigned char*)&pn[0];
+ return &data[0];
}
const unsigned char* end() const
{
- return (unsigned char*)&pn[WIDTH];
+ return &data[WIDTH];
}
unsigned int size() const
{
- return sizeof(pn);
- }
-
- /**
- * 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
- {
- assert(WIDTH >= 2);
- return pn[0] | (uint64_t)pn[1] << 32;
+ return sizeof(data);
}
unsigned int GetSerializeSize(int nType, int nVersion) const
{
- return sizeof(pn);
+ return sizeof(data);
}
template<typename Stream>
void Serialize(Stream& s, int nType, int nVersion) const
{
- s.write((char*)pn, sizeof(pn));
+ s.write((char*)data, sizeof(data));
}
template<typename Stream>
void Unserialize(Stream& s, int nType, int nVersion)
{
- s.read((char*)pn, sizeof(pn));
+ s.read((char*)data, sizeof(data));
}
};
-/** 160-bit unsigned big integer. */
-class uint160 : public base_uint<160> {
+/** 160-bit opaque blob.
+ * @note This type is called uint160 for historical reasons only. It is an opaque
+ * blob of 160 bits and has no integer operations.
+ */
+class uint160 : public base_blob<160> {
public:
uint160() {}
- uint160(const base_uint<160>& b) : base_uint<160>(b) {}
- uint160(uint64_t b) : base_uint<160>(b) {}
- explicit uint160(const std::string& str) : base_uint<160>(str) {}
- explicit uint160(const std::vector<unsigned char>& vch) : base_uint<160>(vch) {}
+ uint160(const base_blob<160>& b) : base_blob<160>(b) {}
+ explicit uint160(const std::vector<unsigned char>& vch) : base_blob<160>(vch) {}
};
-/** 256-bit unsigned big integer. */
-class uint256 : public base_uint<256> {
+/** 256-bit opaque blob.
+ * @note This type is called uint256 for historical reasons only. It is an
+ * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if
+ * those are required.
+ */
+class uint256 : public base_blob<256> {
public:
uint256() {}
- uint256(const base_uint<256>& b) : base_uint<256>(b) {}
- 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)
- *
- * 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(const base_blob<256>& b) : base_blob<256>(b) {}
+ explicit uint256(const std::vector<unsigned char>& vch) : base_blob<256>(vch) {}
+
+ /** A cheap hash function that just returns 64 bits from the result, it can be
+ * used when the contents are considered uniformly random. It is not appropriate
+ * when the value can easily be influenced from outside as e.g. a network adversary could
+ * provide values to trigger worst-case behavior.
+ * @note The result of this function is not stable between little and big endian.
*/
- uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL);
- uint32_t GetCompact(bool fNegative = false) const;
+ uint64_t GetCheapHash() const
+ {
+ uint64_t result;
+ memcpy((void*)&result, (void*)data, 8);
+ return result;
+ }
+ /** A more secure, salted hash function.
+ * @note This hash is not stable between little and big endian.
+ */
uint64_t GetHash(const uint256& salt) const;
};
+/* uint256 from const char *.
+ * This is a separate function because the constructor uint256(const char*) can result
+ * in dangerously catching uint256(0).
+ */
+inline uint256 uint256S(const char *str)
+{
+ uint256 rv;
+ rv.SetHex(str);
+ return rv;
+}
+/* uint256 from std::string.
+ * This is a separate function because the constructor uint256(const std::string &str) can result
+ * in dangerously catching uint256(0) via std::string(const char*).
+ */
+inline uint256 uint256S(const std::string& str)
+{
+ uint256 rv;
+ rv.SetHex(str);
+ return rv;
+}
+
#endif // BITCOIN_UINT256_H
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2013 The Bitcoin developers
+// Copyright (c) 2009-2013 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#define BITCOIN_UNDO_H
#include "compressor.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "serialize.h"
/** Undo information for a CTxIn
}
};
+/** Undo information for a CBlock */
+class CBlockUndo
+{
+public:
+ std::vector<CTxUndo> vtxundo; // for all but the coinbase
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(vtxundo);
+ }
+};
+
#endif // BITCOIN_UNDO_H
// Copyright 2014 BitPay Inc.
-// 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.
//
// Copyright 2014 BitPay Inc.
-// 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 <stdint.h>
// Copyright 2014 BitPay Inc.
-// 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_UNIVALUE_UNIVALUE_H
// Copyright 2014 BitPay Inc.
-// 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 <string.h>
// Copyright 2014 BitPay Inc.
-// 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 <ctype.h>
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
return SoftSetArg(strArg, std::string("0"));
}
-static std::string FormatException(std::exception* pex, const char* pszThread)
+static const int screenWidth = 79;
+static const int optIndent = 2;
+static const int msgIndent = 7;
+
+std::string HelpMessageGroup(const std::string &message) {
+ return std::string(message) + std::string("\n\n");
+}
+
+std::string HelpMessageOpt(const std::string &option, const std::string &message) {
+ return std::string(optIndent,' ') + std::string(option) +
+ std::string("\n") + std::string(msgIndent,' ') +
+ FormatParagraph(message, screenWidth - msgIndent, msgIndent) +
+ std::string("\n\n");
+}
+
+static std::string FormatException(const std::exception* pex, const char* pszThread)
{
#ifdef WIN32
char pszModule[MAX_PATH] = "";
"UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread);
}
-void PrintExceptionContinue(std::exception* pex, const char* pszThread)
+void PrintExceptionContinue(const std::exception* pex, const char* pszThread)
{
std::string message = FormatException(pex, pszThread);
LogPrintf("\n\n************************\n%s\n", message);
try
{
return boost::filesystem::create_directory(p);
- } catch (boost::filesystem::filesystem_error) {
+ } catch (const boost::filesystem::filesystem_error&) {
if (!boost::filesystem::exists(p) || !boost::filesystem::is_directory(p))
throw;
}
// removed.
pthread_set_name_np(pthread_self(), name);
-#elif defined(MAC_OSX) && defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
-
-// pthread_setname_np is XCode 10.6-and-later
-#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
+#elif defined(MAC_OSX)
pthread_setname_np(name);
-#endif
-
#else
// Prevent warnings for unused parameters...
(void)name;
#else // boost filesystem v2
std::locale(); // Raises runtime error if current locale is invalid
#endif
- } catch(std::runtime_error &e)
- {
+ } catch (const std::runtime_error&) {
setenv("LC_ALL", "C", 1); // Force C locale
}
#endif
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
return false;
}
-void PrintExceptionContinue(std::exception* pex, const char* pszThread);
+void PrintExceptionContinue(const std::exception *pex, const char* pszThread);
void ParseParameters(int argc, const char*const argv[]);
void FileCommit(FILE *fileout);
bool TruncateFile(FILE *file, unsigned int length);
bool TryCreateDirectory(const boost::filesystem::path& p);
boost::filesystem::path GetDefaultDataDir();
const boost::filesystem::path &GetDataDir(bool fNetSpecific = true);
+void ClearDatadirCache();
boost::filesystem::path GetConfigFile();
#ifndef WIN32
boost::filesystem::path GetPidFile();
*/
bool SoftSetBoolArg(const std::string& strArg, bool fValue);
+/**
+ * Format a string to be used as group of options in help messages
+ *
+ * @param message Group name (e.g. "RPC server options:")
+ * @return the formatted string
+ */
+std::string HelpMessageGroup(const std::string& message);
+
+/**
+ * Format a string to be used as option description in help messages
+ *
+ * @param option Option message (e.g. "-rpcuser=<user>")
+ * @param message Option description (e.g. "Username for JSON-RPC connections")
+ * @return the formatted string
+ */
+std::string HelpMessageOpt(const std::string& option, const std::string& message);
+
void SetThreadPriority(int nPriority);
void RenameThread(const char* name);
func();
}
}
- catch (boost::thread_interrupted)
+ catch (const boost::thread_interrupted&)
{
LogPrintf("%s thread stop\n", name);
throw;
}
- catch (std::exception& e) {
+ catch (const std::exception& e) {
PrintExceptionContinue(&e, name);
throw;
}
func();
LogPrintf("%s thread exit\n", name);
}
- catch (boost::thread_interrupted)
+ catch (const boost::thread_interrupted&)
{
LogPrintf("%s thread interrupt\n", name);
throw;
}
- catch (std::exception& e) {
+ catch (const std::exception& e) {
PrintExceptionContinue(&e, name);
throw;
}
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "utilmoneystr.h"
-#include "core/transaction.h"
+#include "primitives/transaction.h"
#include "tinyformat.h"
#include "utilstrencodings.h"
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
using namespace std;
-/**
- * safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything
- * even possibly remotely dangerous like & or >
- */
-static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@()");
string SanitizeString(const string& str)
{
+ /**
+ * safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything
+ * even possibly remotely dangerous like & or >
+ */
+ static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@()");
string strResult;
for (std::string::size_type i = 0; i < str.size(); i++)
{
}
// Append word
out << in.substr(ptr, endword - ptr);
- col += endword - ptr;
+ col += endword - ptr + 1;
ptr = endword;
}
return out.str();
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-// Copyright (c) 2012-2014 The Bitcoin developers
+// Copyright (c) 2012-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.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
* Settings
*/
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
+CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
unsigned int nTxConfirmTarget = 1;
bool bSpendZeroConfChange = true;
bool fSendFreeTransactions = false;
* Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)
* Override with -mintxfee
*/
-CFeeRate CWallet::minTxFee = CFeeRate(10000);
+CFeeRate CWallet::minTxFee = CFeeRate(1000);
/** @defgroup mapWallet
*
AssertLockHeld(cs_wallet); // mapKeyMetadata
bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
- RandAddSeedPerfmon();
CKey secret;
secret.MakeNewKey(fCompressed);
nTimeFirstKey = nCreationTime;
if (!AddKeyPubKey(secret, pubkey))
- throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed");
+ throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed");
return pubkey;
}
}
}
-bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
+bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb)
{
uint256 hash = wtxIn.GetHash();
if (fInsertedNew)
{
wtx.nTimeReceived = GetAdjustedTime();
- wtx.nOrderPos = IncOrderPosNext();
+ wtx.nOrderPos = IncOrderPosNext(pwalletdb);
wtx.nTimeSmart = wtx.nTimeReceived;
- if (wtxIn.hashBlock != 0)
+ if (!wtxIn.hashBlock.IsNull())
{
if (mapBlockIndex.count(wtxIn.hashBlock))
{
wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
}
else
- LogPrintf("AddToWallet() : found %s in block %s not in index\n",
+ LogPrintf("AddToWallet(): found %s in block %s not in index\n",
wtxIn.GetHash().ToString(),
wtxIn.hashBlock.ToString());
}
if (!fInsertedNew)
{
// Merge
- if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
+ if (!wtxIn.hashBlock.IsNull() && wtxIn.hashBlock != wtx.hashBlock)
{
wtx.hashBlock = wtxIn.hashBlock;
fUpdated = true;
// Write to disk
if (fInsertedNew || fUpdated)
- if (!wtx.WriteToDisk())
+ if (!wtx.WriteToDisk(pwalletdb))
return false;
// Break debit/credit balance caches:
if (fExisted || IsMine(tx) || IsFromMe(tx))
{
CWalletTx wtx(this,tx);
+
// Get merkle branch if transaction was found in a block
if (pblock)
wtx.SetMerkleBranch(*pblock);
- return AddToWallet(wtx);
+
+ // Do not flush the wallet here for performance reasons
+ // this is safe, as in case of a crash, we rescan the necessary blocks on startup through our SetBestChain-mechanism
+ CWalletDB walletdb(strWalletFile, "r+", false);
+
+ return AddToWallet(wtx, false, &walletdb);
}
}
return false;
if (IsCoinBase())
{
// Generated block
- if (hashBlock != 0)
+ if (!hashBlock.IsNull())
{
map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
if (mi != pwallet->mapRequestCount.end())
nRequests = (*mi).second;
// How about the block it's in?
- if (nRequests == 0 && hashBlock != 0)
+ if (nRequests == 0 && !hashBlock.IsNull())
{
map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
if (mi != pwallet->mapRequestCount.end())
}
-bool CWalletTx::WriteToDisk()
+bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb)
{
- return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this);
+ return pwalletdb->WriteTx(GetHash(), *this);
}
/**
return result;
}
+CAmount CWalletTx::GetDebit(const isminefilter& filter) const
+{
+ if (vin.empty())
+ return 0;
+
+ CAmount debit = 0;
+ if(filter & ISMINE_SPENDABLE)
+ {
+ if (fDebitCached)
+ debit += nDebitCached;
+ else
+ {
+ nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
+ fDebitCached = true;
+ debit += nDebitCached;
+ }
+ }
+ if(filter & ISMINE_WATCH_ONLY)
+ {
+ if(fWatchDebitCached)
+ debit += nWatchDebitCached;
+ else
+ {
+ nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
+ fWatchDebitCached = true;
+ debit += nWatchDebitCached;
+ }
+ }
+ return debit;
+}
+
+CAmount CWalletTx::GetCredit(const isminefilter& filter) const
+{
+ // Must wait until coinbase is safely deep enough in the chain before valuing it
+ if (IsCoinBase() && GetBlocksToMaturity() > 0)
+ return 0;
+
+ int64_t credit = 0;
+ if (filter & ISMINE_SPENDABLE)
+ {
+ // GetBalance can assume transactions in mapWallet won't change
+ if (fCreditCached)
+ credit += nCreditCached;
+ else
+ {
+ nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
+ fCreditCached = true;
+ credit += nCreditCached;
+ }
+ }
+ if (filter & ISMINE_WATCH_ONLY)
+ {
+ if (fWatchCreditCached)
+ credit += nWatchCreditCached;
+ else
+ {
+ nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
+ fWatchCreditCached = true;
+ credit += nWatchCreditCached;
+ }
+ }
+ return credit;
+}
+
+CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const
+{
+ if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
+ {
+ if (fUseCache && fImmatureCreditCached)
+ return nImmatureCreditCached;
+ nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
+ fImmatureCreditCached = true;
+ return nImmatureCreditCached;
+ }
+
+ return 0;
+}
+
+CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const
+{
+ if (pwallet == 0)
+ return 0;
+
+ // Must wait until coinbase is safely deep enough in the chain before valuing it
+ if (IsCoinBase() && GetBlocksToMaturity() > 0)
+ return 0;
+
+ if (fUseCache && fAvailableCreditCached)
+ return nAvailableCreditCached;
+
+ CAmount nCredit = 0;
+ uint256 hashTx = GetHash();
+ for (unsigned int i = 0; i < vout.size(); i++)
+ {
+ if (!pwallet->IsSpent(hashTx, i))
+ {
+ const CTxOut &txout = vout[i];
+ nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE);
+ if (!MoneyRange(nCredit))
+ throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
+ }
+ }
+
+ nAvailableCreditCached = nCredit;
+ fAvailableCreditCached = true;
+ return nCredit;
+}
+
+CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool& fUseCache) const
+{
+ if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
+ {
+ if (fUseCache && fImmatureWatchCreditCached)
+ return nImmatureWatchCreditCached;
+ nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
+ fImmatureWatchCreditCached = true;
+ return nImmatureWatchCreditCached;
+ }
+
+ return 0;
+}
+
+CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool& fUseCache) const
+{
+ if (pwallet == 0)
+ return 0;
+
+ // Must wait until coinbase is safely deep enough in the chain before valuing it
+ if (IsCoinBase() && GetBlocksToMaturity() > 0)
+ return 0;
+
+ if (fUseCache && fAvailableWatchCreditCached)
+ return nAvailableWatchCreditCached;
+
+ CAmount nCredit = 0;
+ for (unsigned int i = 0; i < vout.size(); i++)
+ {
+ if (!pwallet->IsSpent(GetHash(), i))
+ {
+ const CTxOut &txout = vout[i];
+ nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY);
+ if (!MoneyRange(nCredit))
+ throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
+ }
+ }
+
+ nAvailableWatchCreditCached = nCredit;
+ fAvailableWatchCreditCached = true;
+ return nCredit;
+}
+
+CAmount CWalletTx::GetChange() const
+{
+ if (fChangeCached)
+ return nChangeCached;
+ nChangeCached = pwallet->GetChange(*this);
+ fChangeCached = true;
+ return nChangeCached;
+}
+
+bool CWalletTx::IsTrusted() const
+{
+ // Quick answer in most cases
+ if (!IsFinalTx(*this))
+ return false;
+ int nDepth = GetDepthInMainChain();
+ if (nDepth >= 1)
+ return true;
+ if (nDepth < 0)
+ return false;
+ if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
+ return false;
+
+ // Trusted if all inputs are from us and are in the mempool:
+ BOOST_FOREACH(const CTxIn& txin, vin)
+ {
+ // Transactions not sent by us: not trusted
+ const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
+ if (parent == NULL)
+ return false;
+ const CTxOut& parentOut = parent->vout[txin.prevout.n];
+ if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
+ return false;
+ }
+ return true;
+}
+
void CWallet::ResendWalletTransactions()
{
// Do this infrequently and randomly to avoid giving away
(bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet)));
}
-
-
-
-bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
- CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl)
+bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend,
+ CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl)
{
CAmount nValue = 0;
- BOOST_FOREACH (const PAIRTYPE(CScript, CAmount)& s, vecSend)
+ unsigned int nSubtractFeeFromAmount = 0;
+ BOOST_FOREACH (const CRecipient& recipient, vecSend)
{
- if (nValue < 0)
+ if (nValue < 0 || recipient.nAmount < 0)
{
strFailReason = _("Transaction amounts must be positive");
return false;
}
- nValue += s.second;
+ nValue += recipient.nAmount;
+
+ if (recipient.fSubtractFeeFromAmount)
+ nSubtractFeeFromAmount++;
}
if (vecSend.empty() || nValue < 0)
{
wtxNew.BindWallet(this);
CMutableTransaction txNew;
+ // Discourage fee sniping.
+ //
+ // However because of a off-by-one-error in previous versions we need to
+ // neuter it by setting nLockTime to at least one less than nBestHeight.
+ // Secondly currently propagation of transactions created for block heights
+ // corresponding to blocks that were just mined may be iffy - transactions
+ // aren't re-accepted into the mempool - we additionally neuter the code by
+ // going ten blocks back. Doesn't yet do anything for sniping, but does act
+ // to shake out wallet bugs like not showing nLockTime'd transactions at
+ // all.
+ txNew.nLockTime = std::max(0, chainActive.Height() - 10);
+
+ // Secondly occasionally randomly pick a nLockTime even further back, so
+ // that transactions that are delayed after signing for whatever reason,
+ // e.g. high-latency mix networks and some CoinJoin implementations, have
+ // better privacy.
+ if (GetRandInt(10) == 0)
+ txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));
+
+ assert(txNew.nLockTime <= (unsigned int)chainActive.Height());
+ assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
+
{
LOCK2(cs_main, cs_wallet);
{
txNew.vin.clear();
txNew.vout.clear();
wtxNew.fFromMe = true;
+ nChangePosRet = -1;
+ bool fFirst = true;
- CAmount nTotalValue = nValue + nFeeRet;
+ CAmount nTotalValue = nValue;
+ if (nSubtractFeeFromAmount == 0)
+ nTotalValue += nFeeRet;
double dPriority = 0;
// vouts to the payees
- BOOST_FOREACH (const PAIRTYPE(CScript, CAmount)& s, vecSend)
+ BOOST_FOREACH (const CRecipient& recipient, vecSend)
{
- CTxOut txout(s.second, s.first);
+ CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
+
+ if (recipient.fSubtractFeeFromAmount)
+ {
+ txout.nValue -= nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
+
+ if (fFirst) // first receiver pays the remainder not divisible by output count
+ {
+ fFirst = false;
+ txout.nValue -= nFeeRet % nSubtractFeeFromAmount;
+ }
+ }
+
if (txout.IsDust(::minRelayTxFee))
{
- strFailReason = _("Transaction amount too small");
+ if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
+ {
+ if (txout.nValue < 0)
+ strFailReason = _("The transaction amount is too small to pay the fee");
+ else
+ strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
+ }
+ else
+ strFailReason = _("Transaction amount too small");
return false;
}
txNew.vout.push_back(txout);
BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
{
CAmount nCredit = pcoin.first->vout[pcoin.second].nValue;
- //The priority after the next block (depth+1) is used instead of the current,
+ //The coin age after the next block (depth+1) is used instead of the current,
//reflecting an assumption the user would accept a bit more delay for
//a chance at a free transaction.
- dPriority += (double)nCredit * (pcoin.first->GetDepthInMainChain()+1);
+ //But mempool inputs might still be in the mempool, so their age stays 0
+ int age = pcoin.first->GetDepthInMainChain();
+ if (age != 0)
+ age += 1;
+ dPriority += (double)nCredit * age;
}
- CAmount nChange = nValueIn - nValue - nFeeRet;
+ CAmount nChange = nValueIn - nValue;
+ if (nSubtractFeeFromAmount == 0)
+ nChange -= nFeeRet;
if (nChange > 0)
{
CTxOut newTxOut(nChange, scriptChange);
+ // We do not move dust-change to fees, because the sender would end up paying more than requested.
+ // This would be against the purpose of the all-inclusive feature.
+ // So instead we raise the change and deduct from the recipient.
+ if (nSubtractFeeFromAmount > 0 && newTxOut.IsDust(::minRelayTxFee))
+ {
+ CAmount nDust = newTxOut.GetDustThreshold(::minRelayTxFee) - newTxOut.nValue;
+ newTxOut.nValue += nDust; // raise change until no more dust
+ for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient
+ {
+ if (vecSend[i].fSubtractFeeFromAmount)
+ {
+ txNew.vout[i].nValue -= nDust;
+ if (txNew.vout[i].IsDust(::minRelayTxFee))
+ {
+ strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
+ return false;
+ }
+ break;
+ }
+ }
+ }
+
// Never create dust outputs; if we would, just
// add the dust to the fee.
if (newTxOut.IsDust(::minRelayTxFee))
else
{
// Insert change txn at random position:
- vector<CTxOut>::iterator position = txNew.vout.begin()+GetRandInt(txNew.vout.size()+1);
+ nChangePosRet = GetRandInt(txNew.vout.size()+1);
+ vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet;
txNew.vout.insert(position, newTxOut);
}
}
reservekey.ReturnKey();
// Fill vin
+ //
+ // Note how the sequence number is set to max()-1 so that the
+ // nLockTime set above actually works.
BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
- txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
+ txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
+ std::numeric_limits<unsigned int>::max()-1));
// Sign
int nIn = 0;
}
dPriority = wtxNew.ComputePriority(dPriority, nBytes);
- CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
+ // Can we complete this as a free transaction?
+ if (fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE)
+ {
+ // Not enough fee: enough priority?
+ double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
+ // Not enough mempool history to estimate: use hard-coded AllowFree.
+ if (dPriorityNeeded <= 0 && AllowFree(dPriority))
+ break;
+
+ // Small enough, and priority high enough, to send for free
+ if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded)
+ break;
+ }
- if (nFeeRet >= nFeeNeeded)
- break; // Done, enough fee included.
+ CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
- // Too big to send for free? Include more fee and try again:
- if (!fSendFreeTransactions || nBytes > MAX_FREE_TRANSACTION_CREATE_SIZE)
+ // If we made it here and we aren't even able to meet the relay fee on the next pass, give up
+ // because we must be at the maximum allowed fee.
+ if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes))
{
- nFeeRet = nFeeNeeded;
- continue;
+ strFailReason = _("Transaction too large for fee policy");
+ return false;
}
- // Not enough fee: enough priority?
- double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
- // Not enough mempool history to estimate: use hard-coded AllowFree.
- if (dPriorityNeeded <= 0 && AllowFree(dPriority))
- break;
-
- // Small enough, and priority high enough, to send for free
- if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded)
- break;
+ if (nFeeRet >= nFeeNeeded)
+ break; // Done, enough fee included.
// Include more fee and try again.
nFeeRet = nFeeNeeded;
}
}
}
- return true;
-}
-bool CWallet::CreateTransaction(CScript scriptPubKey, const CAmount& nValue,
- CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl)
-{
- vector< pair<CScript, CAmount> > vecSend;
- vecSend.push_back(make_pair(scriptPubKey, nValue));
- return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, strFailReason, coinControl);
+ return true;
}
/**
// This is only to keep the database open to defeat the auto-flush for the
// duration of this scope. This is the only place where this optimization
// maybe makes sense; please don't do it anywhere else.
- CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL;
+ CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r+") : NULL;
// Take key pair from key pool so it won't be used again
reservekey.KeepKey();
// Add tx to wallet, because if it has change it's also ours,
// otherwise just for transaction history.
- AddToWallet(wtxNew);
+ AddToWallet(wtxNew, false, pwalletdb);
// Notify that old coins are spent
set<CWalletTx*> setCoins;
if (!wtxNew.AcceptToMemoryPool(false))
{
// This must not fail. The transaction has already been signed and recorded.
- LogPrintf("CommitTransaction() : Error: Transaction not valid");
+ LogPrintf("CommitTransaction(): Error: Transaction not valid");
return false;
}
wtxNew.RelayWalletTransaction();
return true;
}
-
-
-
-string CWallet::SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew)
-{
- // Check amount
- if (nValue <= 0)
- return _("Invalid amount");
- if (nValue > GetBalance())
- return _("Insufficient funds");
-
- string strError;
- if (IsLocked())
- {
- strError = _("Error: Wallet locked, unable to create transaction!");
- LogPrintf("SendMoney() : %s", strError);
- return strError;
- }
-
- // Parse Bitcoin address
- CScript scriptPubKey = GetScriptForDestination(address);
-
- // Create and send the transaction
- CReserveKey reservekey(this);
- CAmount nFeeRequired;
- if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError))
- {
- if (nValue + nFeeRequired > GetBalance())
- strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!"), FormatMoney(nFeeRequired));
- LogPrintf("SendMoney() : %s\n", strError);
- return strError;
- }
- if (!CommitTransaction(wtxNew, reservekey))
- return _("Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
-
- return "";
-}
-
-
-
CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool)
{
// payTxFee is user-set "I want to pay this much"
CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
- // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee
- if (nFeeNeeded > 0 && nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes))
- nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes);
// user selected total at least (default=true)
if (fPayAtLeastCustomFee && nFeeNeeded > 0 && nFeeNeeded < payTxFee.GetFeePerK())
nFeeNeeded = payTxFee.GetFeePerK();
// back to a hard-coded fee
if (nFeeNeeded == 0)
nFeeNeeded = minTxFee.GetFee(nTxBytes);
+ // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee
+ if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes))
+ nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes);
+ // But always obey the maximum
+ if (nFeeNeeded > maxTxFee)
+ nFeeNeeded = maxTxFee;
return nFeeNeeded;
}
if (!setKeyPool.empty())
nEnd = *(--setKeyPool.end()) + 1;
if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
- throw runtime_error("TopUpKeyPool() : writing generated key failed");
+ throw runtime_error("TopUpKeyPool(): writing generated key failed");
setKeyPool.insert(nEnd);
LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size());
}
nIndex = *(setKeyPool.begin());
setKeyPool.erase(setKeyPool.begin());
if (!walletdb.ReadPool(nIndex, keypool))
- throw runtime_error("ReserveKeyFromKeyPool() : read failed");
+ throw runtime_error("ReserveKeyFromKeyPool(): read failed");
if (!HaveKey(keypool.vchPubKey.GetID()))
- throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
+ throw runtime_error("ReserveKeyFromKeyPool(): unknown key in key pool");
assert(keypool.vchPubKey.IsValid());
LogPrintf("keypool reserve %d\n", nIndex);
}
set<CTxDestination> CWallet::GetAccountAddresses(string strAccount) const
{
- AssertLockHeld(cs_wallet); // mapWallet
+ LOCK(cs_wallet);
set<CTxDestination> result;
BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
{
{
CKeyPool keypool;
if (!walletdb.ReadPool(id, keypool))
- throw runtime_error("GetAllReserveKeyHashes() : read failed");
+ throw runtime_error("GetAllReserveKeyHashes(): read failed");
assert(keypool.vchPubKey.IsValid());
CKeyID keyID = keypool.vchPubKey.GetID();
if (!HaveKey(keyID))
- throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
+ throw runtime_error("GetAllReserveKeyHashes(): unknown key in key pool");
setAddress.insert(keyID);
}
}
{
vMerkleBranch.clear();
nIndex = -1;
- LogPrintf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
+ LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n");
return 0;
}
int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
{
- if (hashBlock == 0 || nIndex == -1)
+ if (hashBlock.IsNull() || nIndex == -1)
return 0;
AssertLockHeld(cs_main);
}
-bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectInsaneFee)
+bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee)
{
CValidationState state;
- return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectInsaneFee);
+ return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee);
}
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#define BITCOIN_WALLET_H
#include "amount.h"
-#include "core/block.h"
-#include "core/transaction.h"
+#include "primitives/block.h"
+#include "primitives/transaction.h"
#include "crypter.h"
#include "key.h"
#include "keystore.h"
* Settings
*/
extern CFeeRate payTxFee;
+extern CAmount maxTxFee;
extern unsigned int nTxConfirmTarget;
extern bool bSpendZeroConfChange;
extern bool fSendFreeTransactions;
static const CAmount DEFAULT_TRANSACTION_FEE = 0;
//! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB
static const CAmount nHighTransactionFeeWarning = 0.01 * COIN;
+//! -maxtxfee default
+static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN;
+//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis)
+static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWarning;
//! Largest (in bytes) free transaction we're willing to create
static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000;
StringMap destdata;
};
-/**
- * A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
- * and provides the ability to create new transactions.
- */
-class CWallet : public CCryptoKeyStore, public CValidationInterface
+struct CRecipient
{
-private:
- bool SelectCoins(const CAmount& nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const;
+ CScript scriptPubKey;
+ CAmount nAmount;
+ bool fSubtractFeeFromAmount;
+};
- CWalletDB *pwalletdbEncryption;
+typedef std::map<std::string, std::string> mapValue_t;
- //! the current wallet version: clients below this version are not able to load the wallet
- int nWalletVersion;
- //! the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded
- int nWalletMaxVersion;
+static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)
+{
+ if (!mapValue.count("n"))
+ {
+ nOrderPos = -1; // TODO: calculate elsewhere
+ return;
+ }
+ nOrderPos = atoi64(mapValue["n"].c_str());
+}
- int64_t nNextResend;
- int64_t nLastResend;
- /**
- * Used to keep track of spent outpoints, and
- * detect and report conflicts (double-spends or
- * mutated transactions where the mutant gets mined).
- */
- typedef std::multimap<COutPoint, uint256> TxSpends;
- TxSpends mapTxSpends;
- void AddToSpends(const COutPoint& outpoint, const uint256& wtxid);
- void AddToSpends(const uint256& wtxid);
+static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue)
+{
+ if (nOrderPos == -1)
+ return;
+ mapValue["n"] = i64tostr(nOrderPos);
+}
- void SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator>);
+struct COutputEntry
+{
+ CTxDestination destination;
+ CAmount amount;
+ int vout;
+};
-public:
- /*
- * Main wallet lock.
- * This lock protects all the fields added by CWallet
- * except for:
- * fFileBacked (immutable after instantiation)
- * strWalletFile (immutable after instantiation)
- */
- mutable CCriticalSection cs_wallet;
+/** A transaction with a merkle branch linking it to the block chain. */
+class CMerkleTx : public CTransaction
+{
+private:
+ int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const;
- bool fFileBacked;
- std::string strWalletFile;
+public:
+ uint256 hashBlock;
+ std::vector<uint256> vMerkleBranch;
+ int nIndex;
- std::set<int64_t> setKeyPool;
- std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
+ // memory only
+ mutable bool fMerkleVerified;
- typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
- MasterKeyMap mapMasterKeys;
- unsigned int nMasterKeyMaxID;
- CWallet()
+ CMerkleTx()
{
- SetNull();
+ Init();
}
- CWallet(std::string strWalletFileIn)
+ CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
{
- SetNull();
-
- strWalletFile = strWalletFileIn;
- fFileBacked = true;
+ Init();
}
- ~CWallet()
+ void Init()
{
- delete pwalletdbEncryption;
- pwalletdbEncryption = NULL;
+ hashBlock = uint256();
+ nIndex = -1;
+ fMerkleVerified = false;
}
- void SetNull()
- {
- nWalletVersion = FEATURE_BASE;
- nWalletMaxVersion = FEATURE_BASE;
- fFileBacked = false;
- nMasterKeyMaxID = 0;
- pwalletdbEncryption = NULL;
- nOrderPosNext = 0;
- nNextResend = 0;
- nLastResend = 0;
- nTimeFirstKey = 0;
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(*(CTransaction*)this);
+ nVersion = this->nVersion;
+ READWRITE(hashBlock);
+ READWRITE(vMerkleBranch);
+ READWRITE(nIndex);
}
- std::map<uint256, CWalletTx> mapWallet;
+ int SetMerkleBranch(const CBlock& block);
- int64_t nOrderPosNext;
- std::map<uint256, int> mapRequestCount;
- std::map<CTxDestination, CAddressBookData> mapAddressBook;
+ /**
+ * Return depth of transaction in blockchain:
+ * -1 : not in blockchain, and not in memory pool (conflicted transaction)
+ * 0 : in memory pool, waiting to be included in a block
+ * >=1 : this many blocks deep in the main chain
+ */
+ int GetDepthInMainChain(const CBlockIndex* &pindexRet) const;
+ int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
+ bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; }
+ int GetBlocksToMaturity() const;
+ bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true);
+};
- CPubKey vchDefaultKey;
+/**
+ * A transaction with a bunch of additional info that only the owner cares about.
+ * It includes any unrecorded transactions needed to link it back to the block chain.
+ */
+class CWalletTx : public CMerkleTx
+{
+private:
+ const CWallet* pwallet;
- std::set<COutPoint> setLockedCoins;
+public:
+ mapValue_t mapValue;
+ std::vector<std::pair<std::string, std::string> > vOrderForm;
+ unsigned int fTimeReceivedIsTxTime;
+ unsigned int nTimeReceived; //! time received by this node
+ unsigned int nTimeSmart;
+ char fFromMe;
+ std::string strFromAccount;
+ int64_t nOrderPos; //! position in ordered transaction list
- int64_t nTimeFirstKey;
+ // memory only
+ mutable bool fDebitCached;
+ mutable bool fCreditCached;
+ mutable bool fImmatureCreditCached;
+ mutable bool fAvailableCreditCached;
+ mutable bool fWatchDebitCached;
+ mutable bool fWatchCreditCached;
+ mutable bool fImmatureWatchCreditCached;
+ mutable bool fAvailableWatchCreditCached;
+ mutable bool fChangeCached;
+ mutable CAmount nDebitCached;
+ mutable CAmount nCreditCached;
+ mutable CAmount nImmatureCreditCached;
+ mutable CAmount nAvailableCreditCached;
+ mutable CAmount nWatchDebitCached;
+ mutable CAmount nWatchCreditCached;
+ mutable CAmount nImmatureWatchCreditCached;
+ mutable CAmount nAvailableWatchCreditCached;
+ mutable CAmount nChangeCached;
- const CWalletTx* GetWalletTx(const uint256& hash) const;
+ CWalletTx()
+ {
+ Init(NULL);
+ }
- //! check whether we are allowed to upgrade (or already support) to the named feature
- bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; }
+ CWalletTx(const CWallet* pwalletIn)
+ {
+ Init(pwalletIn);
+ }
- void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL) const;
- bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const;
+ CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
+ {
+ Init(pwalletIn);
+ }
- bool IsSpent(const uint256& hash, unsigned int n) const;
+ CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
+ {
+ Init(pwalletIn);
+ }
- bool IsLockedCoin(uint256 hash, unsigned int n) const;
- void LockCoin(COutPoint& output);
- void UnlockCoin(COutPoint& output);
- void UnlockAllCoins();
- void ListLockedCoins(std::vector<COutPoint>& vOutpts);
+ void Init(const CWallet* pwalletIn)
+ {
+ pwallet = pwalletIn;
+ mapValue.clear();
+ vOrderForm.clear();
+ fTimeReceivedIsTxTime = false;
+ nTimeReceived = 0;
+ nTimeSmart = 0;
+ fFromMe = false;
+ strFromAccount.clear();
+ fDebitCached = false;
+ fCreditCached = false;
+ fImmatureCreditCached = false;
+ fAvailableCreditCached = false;
+ fWatchDebitCached = false;
+ fWatchCreditCached = false;
+ fImmatureWatchCreditCached = false;
+ fAvailableWatchCreditCached = false;
+ fChangeCached = false;
+ nDebitCached = 0;
+ nCreditCached = 0;
+ nImmatureCreditCached = 0;
+ nAvailableCreditCached = 0;
+ nWatchDebitCached = 0;
+ nWatchCreditCached = 0;
+ nAvailableWatchCreditCached = 0;
+ nImmatureWatchCreditCached = 0;
+ nChangeCached = 0;
+ nOrderPos = -1;
+ }
- /**
- * keystore implementation
- * Generate a new key
- */
- CPubKey GenerateNewKey();
- //! Adds a key to the store, and saves it to disk.
- bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
- //! Adds a key to the store, without saving it to disk (used by LoadWallet)
- bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
- //! Load metadata (used by LoadWallet)
- bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata);
+ ADD_SERIALIZE_METHODS;
- bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (ser_action.ForRead())
+ Init(NULL);
+ char fSpent = false;
- //! Adds an encrypted key to the store, and saves it to disk.
- bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
- //! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
- bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
- bool AddCScript(const CScript& redeemScript);
- bool LoadCScript(const CScript& redeemScript);
+ if (!ser_action.ForRead())
+ {
+ mapValue["fromaccount"] = strFromAccount;
- //! Adds a destination data tuple to the store, and saves it to disk
- bool AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value);
- //! Erases a destination data tuple in the store and on disk
- bool EraseDestData(const CTxDestination &dest, const std::string &key);
- //! Adds a destination data tuple to the store, without saving it to disk
- bool LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value);
- //! Look up a destination data tuple in the store, return true if found false otherwise
- bool GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const;
-
- //! Adds a watch-only address to the store, and saves it to disk.
- bool AddWatchOnly(const CScript &dest);
- bool RemoveWatchOnly(const CScript &dest);
- //! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
- bool LoadWatchOnly(const CScript &dest);
-
- bool Unlock(const SecureString& strWalletPassphrase);
- bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
- bool EncryptWallet(const SecureString& strWalletPassphrase);
-
- void GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const;
-
- /**
- * Increment the next transaction order id
- * @return next transaction order id
- */
- int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL);
-
- typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair;
- typedef std::multimap<int64_t, TxPair > TxItems;
-
- /**
- * Get the wallet's activity log
- * @return multimap of ordered transactions and accounting entries
- * @warning Returned pointers are *only* valid within the scope of passed acentries
- */
- TxItems OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount = "");
-
- void MarkDirty();
- bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet=false);
- void SyncTransaction(const CTransaction& tx, const CBlock* pblock);
- bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate);
- void EraseFromWallet(const uint256 &hash);
- int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
- void ReacceptWalletTransactions();
- void ResendWalletTransactions();
- CAmount GetBalance() const;
- CAmount GetUnconfirmedBalance() const;
- CAmount GetImmatureBalance() const;
- CAmount GetWatchOnlyBalance() const;
- CAmount GetUnconfirmedWatchOnlyBalance() const;
- CAmount GetImmatureWatchOnlyBalance() const;
- bool CreateTransaction(const std::vector<std::pair<CScript, CAmount> >& vecSend,
- CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL);
- bool CreateTransaction(CScript scriptPubKey, const CAmount& nValue,
- CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL);
- bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
- std::string SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew);
+ WriteOrderPos(nOrderPos, mapValue);
- static CFeeRate minTxFee;
- static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool);
+ if (nTimeSmart)
+ mapValue["timesmart"] = strprintf("%u", nTimeSmart);
+ }
- bool NewKeyPool();
- bool TopUpKeyPool(unsigned int kpSize = 0);
- void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool);
- void KeepKey(int64_t nIndex);
- void ReturnKey(int64_t nIndex);
- bool GetKeyFromPool(CPubKey &key);
- int64_t GetOldestKeyPoolTime();
- void GetAllReserveKeys(std::set<CKeyID>& setAddress) const;
+ READWRITE(*(CMerkleTx*)this);
+ std::vector<CMerkleTx> vUnused; //! Used to be vtxPrev
+ READWRITE(vUnused);
+ READWRITE(mapValue);
+ READWRITE(vOrderForm);
+ READWRITE(fTimeReceivedIsTxTime);
+ READWRITE(nTimeReceived);
+ READWRITE(fFromMe);
+ READWRITE(fSpent);
- std::set< std::set<CTxDestination> > GetAddressGroupings();
- std::map<CTxDestination, CAmount> GetAddressBalances();
+ if (ser_action.ForRead())
+ {
+ strFromAccount = mapValue["fromaccount"];
- std::set<CTxDestination> GetAccountAddresses(std::string strAccount) const;
+ ReadOrderPos(nOrderPos, mapValue);
- isminetype IsMine(const CTxIn& txin) const;
- CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const;
- isminetype IsMine(const CTxOut& txout) const
- {
- return ::IsMine(*this, txout.scriptPubKey);
- }
- CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const
- {
- if (!MoneyRange(txout.nValue))
- throw std::runtime_error("CWallet::GetCredit() : value out of range");
- return ((IsMine(txout) & filter) ? txout.nValue : 0);
- }
- bool IsChange(const CTxOut& txout) const;
- CAmount GetChange(const CTxOut& txout) const
- {
- if (!MoneyRange(txout.nValue))
- throw std::runtime_error("CWallet::GetChange() : value out of range");
- return (IsChange(txout) ? txout.nValue : 0);
- }
- bool IsMine(const CTransaction& tx) const
- {
- BOOST_FOREACH(const CTxOut& txout, tx.vout)
- if (IsMine(txout))
- return true;
- return false;
- }
- /** should probably be renamed to IsRelevantToMe */
- bool IsFromMe(const CTransaction& tx) const
- {
- return (GetDebit(tx, ISMINE_ALL) > 0);
- }
- CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const
- {
- CAmount nDebit = 0;
- BOOST_FOREACH(const CTxIn& txin, tx.vin)
- {
- nDebit += GetDebit(txin, filter);
- if (!MoneyRange(nDebit))
- throw std::runtime_error("CWallet::GetDebit() : value out of range");
+ nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0;
}
- return nDebit;
+
+ mapValue.erase("fromaccount");
+ mapValue.erase("version");
+ mapValue.erase("spent");
+ mapValue.erase("n");
+ mapValue.erase("timesmart");
}
- CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const
+
+ //! make sure balances are recalculated
+ void MarkDirty()
{
- CAmount nCredit = 0;
- BOOST_FOREACH(const CTxOut& txout, tx.vout)
- {
- nCredit += GetCredit(txout, filter);
- if (!MoneyRange(nCredit))
- throw std::runtime_error("CWallet::GetCredit() : value out of range");
- }
- return nCredit;
+ fCreditCached = false;
+ fAvailableCreditCached = false;
+ fWatchDebitCached = false;
+ fWatchCreditCached = false;
+ fAvailableWatchCreditCached = false;
+ fImmatureWatchCreditCached = false;
+ fDebitCached = false;
+ fChangeCached = false;
}
- CAmount GetChange(const CTransaction& tx) const
+
+ void BindWallet(CWallet *pwalletIn)
{
- CAmount nChange = 0;
- BOOST_FOREACH(const CTxOut& txout, tx.vout)
- {
- nChange += GetChange(txout);
- if (!MoneyRange(nChange))
- throw std::runtime_error("CWallet::GetChange() : value out of range");
- }
- return nChange;
+ pwallet = pwalletIn;
+ MarkDirty();
}
- void SetBestChain(const CBlockLocator& loc);
-
- DBErrors LoadWallet(bool& fFirstRunRet);
- DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx);
-
- bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose);
- bool DelAddressBook(const CTxDestination& address);
+ //! filter decides which addresses will count towards the debit
+ CAmount GetDebit(const isminefilter& filter) const;
+ CAmount GetCredit(const isminefilter& filter) const;
+ CAmount GetImmatureCredit(bool fUseCache=true) const;
+ CAmount GetAvailableCredit(bool fUseCache=true) const;
+ CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const;
+ CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const;
+ CAmount GetChange() const;
- void UpdatedTransaction(const uint256 &hashTx);
+ void GetAmounts(std::list<COutputEntry>& listReceived,
+ std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const;
- void Inventory(const uint256 &hash)
- {
- {
- LOCK(cs_wallet);
- std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
- if (mi != mapRequestCount.end())
- (*mi).second++;
- }
- }
+ void GetAccountAmounts(const std::string& strAccount, CAmount& nReceived,
+ CAmount& nSent, CAmount& nFee, const isminefilter& filter) const;
- unsigned int GetKeyPoolSize()
+ bool IsFromMe(const isminefilter& filter) const
{
- AssertLockHeld(cs_wallet); // setKeyPool
- return setKeyPool.size();
+ return (GetDebit(filter) > 0);
}
- bool SetDefaultKey(const CPubKey &vchPubKey);
-
- //! signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
- bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false);
+ bool IsTrusted() const;
- //! change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format)
- bool SetMaxVersion(int nVersion);
+ bool WriteToDisk(CWalletDB *pwalletdb);
- //! get the current wallet format (the oldest client version guaranteed to understand this wallet)
- int GetVersion() { LOCK(cs_wallet); return nWalletVersion; }
+ int64_t GetTxTime() const;
+ int GetRequestCount() const;
- //! Get wallet transactions that conflict with given transaction (spend same outputs)
- std::set<uint256> GetConflicts(const uint256& txid) const;
+ void RelayWalletTransaction();
- /**
- * Address book entry changed.
- * @note called with lock cs_wallet held.
- */
- boost::signals2::signal<void (CWallet *wallet, const CTxDestination
- &address, const std::string &label, bool isMine,
- const std::string &purpose,
- ChangeType status)> NotifyAddressBookChanged;
+ std::set<uint256> GetConflicts() const;
+};
- /**
- * Wallet transaction added, removed or updated.
- * @note called with lock cs_wallet held.
- */
- boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx,
- ChangeType status)> NotifyTransactionChanged;
- /** Show progress e.g. for rescan */
- boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
- /** Watch-only address added */
- boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged;
-};
-/** A key allocated from the key pool. */
-class CReserveKey
+class COutput
{
-protected:
- CWallet* pwallet;
- int64_t nIndex;
- CPubKey vchPubKey;
public:
- CReserveKey(CWallet* pwalletIn)
- {
- nIndex = -1;
- pwallet = pwalletIn;
- }
+ const CWalletTx *tx;
+ int i;
+ int nDepth;
+ bool fSpendable;
- ~CReserveKey()
+ COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn)
{
- ReturnKey();
+ tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn;
}
- void ReturnKey();
- bool GetReservedKey(CPubKey &pubkey);
- void KeepKey();
+ std::string ToString() const;
};
-typedef std::map<std::string, std::string> mapValue_t;
-static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)
+/** Private key that includes an expiration date in case it never gets used. */
+class CWalletKey
{
- if (!mapValue.count("n"))
- {
- nOrderPos = -1; // TODO: calculate elsewhere
- return;
- }
- nOrderPos = atoi64(mapValue["n"].c_str());
-}
+public:
+ CPrivKey vchPrivKey;
+ int64_t nTimeCreated;
+ int64_t nTimeExpires;
+ std::string strComment;
+ //! todo: add something to note what created it (user, getnewaddress, change)
+ //! maybe should have a map<string, string> property map
+ CWalletKey(int64_t nExpires=0);
-static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue)
-{
- if (nOrderPos == -1)
- return;
- mapValue["n"] = i64tostr(nOrderPos);
-}
+ ADD_SERIALIZE_METHODS;
-struct COutputEntry
-{
- CTxDestination destination;
- CAmount amount;
- int vout;
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ if (!(nType & SER_GETHASH))
+ READWRITE(nVersion);
+ READWRITE(vchPrivKey);
+ READWRITE(nTimeCreated);
+ READWRITE(nTimeExpires);
+ READWRITE(LIMITED_STRING(strComment, 65536));
+ }
};
-/** A transaction with a merkle branch linking it to the block chain. */
-class CMerkleTx : public CTransaction
+
+
+/**
+ * A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
+ * and provides the ability to create new transactions.
+ */
+class CWallet : public CCryptoKeyStore, public CValidationInterface
{
private:
- int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const;
+ bool SelectCoins(const CAmount& nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const;
+
+ CWalletDB *pwalletdbEncryption;
+
+ //! the current wallet version: clients below this version are not able to load the wallet
+ int nWalletVersion;
+
+ //! the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded
+ int nWalletMaxVersion;
+
+ int64_t nNextResend;
+ int64_t nLastResend;
+
+ /**
+ * Used to keep track of spent outpoints, and
+ * detect and report conflicts (double-spends or
+ * mutated transactions where the mutant gets mined).
+ */
+ typedef std::multimap<COutPoint, uint256> TxSpends;
+ TxSpends mapTxSpends;
+ void AddToSpends(const COutPoint& outpoint, const uint256& wtxid);
+ void AddToSpends(const uint256& wtxid);
+
+ void SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator>);
public:
- uint256 hashBlock;
- std::vector<uint256> vMerkleBranch;
- int nIndex;
+ /*
+ * Main wallet lock.
+ * This lock protects all the fields added by CWallet
+ * except for:
+ * fFileBacked (immutable after instantiation)
+ * strWalletFile (immutable after instantiation)
+ */
+ mutable CCriticalSection cs_wallet;
- // memory only
- mutable bool fMerkleVerified;
+ bool fFileBacked;
+ std::string strWalletFile;
+ std::set<int64_t> setKeyPool;
+ std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
- CMerkleTx()
+ typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
+ MasterKeyMap mapMasterKeys;
+ unsigned int nMasterKeyMaxID;
+
+ CWallet()
{
- Init();
+ SetNull();
}
- CMerkleTx(const CTransaction& txIn) : CTransaction(txIn)
+ CWallet(std::string strWalletFileIn)
{
- Init();
+ SetNull();
+
+ strWalletFile = strWalletFileIn;
+ fFileBacked = true;
}
- void Init()
+ ~CWallet()
{
- hashBlock = 0;
- nIndex = -1;
- fMerkleVerified = false;
+ delete pwalletdbEncryption;
+ pwalletdbEncryption = NULL;
}
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(*(CTransaction*)this);
- nVersion = this->nVersion;
- READWRITE(hashBlock);
- READWRITE(vMerkleBranch);
- READWRITE(nIndex);
+ void SetNull()
+ {
+ nWalletVersion = FEATURE_BASE;
+ nWalletMaxVersion = FEATURE_BASE;
+ fFileBacked = false;
+ nMasterKeyMaxID = 0;
+ pwalletdbEncryption = NULL;
+ nOrderPosNext = 0;
+ nNextResend = 0;
+ nLastResend = 0;
+ nTimeFirstKey = 0;
}
- int SetMerkleBranch(const CBlock& block);
+ std::map<uint256, CWalletTx> mapWallet;
+ int64_t nOrderPosNext;
+ std::map<uint256, int> mapRequestCount;
- /**
- * Return depth of transaction in blockchain:
- * -1 : not in blockchain, and not in memory pool (conflicted transaction)
- * 0 : in memory pool, waiting to be included in a block
- * >=1 : this many blocks deep in the main chain
- */
- int GetDepthInMainChain(const CBlockIndex* &pindexRet) const;
- int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); }
- bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; }
- int GetBlocksToMaturity() const;
- bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectInsaneFee=true);
-};
+ std::map<CTxDestination, CAddressBookData> mapAddressBook;
-/**
- * A transaction with a bunch of additional info that only the owner cares about.
- * It includes any unrecorded transactions needed to link it back to the block chain.
- */
-class CWalletTx : public CMerkleTx
-{
-private:
- const CWallet* pwallet;
+ CPubKey vchDefaultKey;
-public:
- mapValue_t mapValue;
- std::vector<std::pair<std::string, std::string> > vOrderForm;
- unsigned int fTimeReceivedIsTxTime;
- unsigned int nTimeReceived; //! time received by this node
- unsigned int nTimeSmart;
- char fFromMe;
- std::string strFromAccount;
- int64_t nOrderPos; //! position in ordered transaction list
+ std::set<COutPoint> setLockedCoins;
- // memory only
- mutable bool fDebitCached;
- mutable bool fCreditCached;
- mutable bool fImmatureCreditCached;
- mutable bool fAvailableCreditCached;
- mutable bool fWatchDebitCached;
- mutable bool fWatchCreditCached;
- mutable bool fImmatureWatchCreditCached;
- mutable bool fAvailableWatchCreditCached;
- mutable bool fChangeCached;
- mutable CAmount nDebitCached;
- mutable CAmount nCreditCached;
- mutable CAmount nImmatureCreditCached;
- mutable CAmount nAvailableCreditCached;
- mutable CAmount nWatchDebitCached;
- mutable CAmount nWatchCreditCached;
- mutable CAmount nImmatureWatchCreditCached;
- mutable CAmount nAvailableWatchCreditCached;
- mutable CAmount nChangeCached;
+ int64_t nTimeFirstKey;
- CWalletTx()
- {
- Init(NULL);
- }
+ const CWalletTx* GetWalletTx(const uint256& hash) const;
- CWalletTx(const CWallet* pwalletIn)
- {
- Init(pwalletIn);
- }
+ //! check whether we are allowed to upgrade (or already support) to the named feature
+ bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; }
- CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
- {
- Init(pwalletIn);
- }
+ void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL) const;
+ bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const;
- CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
- {
- Init(pwalletIn);
- }
+ bool IsSpent(const uint256& hash, unsigned int n) const;
- void Init(const CWallet* pwalletIn)
- {
- pwallet = pwalletIn;
- mapValue.clear();
- vOrderForm.clear();
- fTimeReceivedIsTxTime = false;
- nTimeReceived = 0;
- nTimeSmart = 0;
- fFromMe = false;
- strFromAccount.clear();
- fDebitCached = false;
- fCreditCached = false;
- fImmatureCreditCached = false;
- fAvailableCreditCached = false;
- fWatchDebitCached = false;
- fWatchCreditCached = false;
- fImmatureWatchCreditCached = false;
- fAvailableWatchCreditCached = false;
- fChangeCached = false;
- nDebitCached = 0;
- nCreditCached = 0;
- nImmatureCreditCached = 0;
- nAvailableCreditCached = 0;
- nWatchDebitCached = 0;
- nWatchCreditCached = 0;
- nAvailableWatchCreditCached = 0;
- nImmatureWatchCreditCached = 0;
- nChangeCached = 0;
- nOrderPos = -1;
- }
+ bool IsLockedCoin(uint256 hash, unsigned int n) const;
+ void LockCoin(COutPoint& output);
+ void UnlockCoin(COutPoint& output);
+ void UnlockAllCoins();
+ void ListLockedCoins(std::vector<COutPoint>& vOutpts);
- ADD_SERIALIZE_METHODS;
+ /**
+ * keystore implementation
+ * Generate a new key
+ */
+ CPubKey GenerateNewKey();
+ //! Adds a key to the store, and saves it to disk.
+ bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
+ //! Adds a key to the store, without saving it to disk (used by LoadWallet)
+ bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
+ //! Load metadata (used by LoadWallet)
+ bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata);
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- if (ser_action.ForRead())
- Init(NULL);
- char fSpent = false;
+ bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
- if (!ser_action.ForRead())
- {
- mapValue["fromaccount"] = strFromAccount;
+ //! Adds an encrypted key to the store, and saves it to disk.
+ bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
+ //! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
+ bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
+ bool AddCScript(const CScript& redeemScript);
+ bool LoadCScript(const CScript& redeemScript);
- WriteOrderPos(nOrderPos, mapValue);
+ //! Adds a destination data tuple to the store, and saves it to disk
+ bool AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value);
+ //! Erases a destination data tuple in the store and on disk
+ bool EraseDestData(const CTxDestination &dest, const std::string &key);
+ //! Adds a destination data tuple to the store, without saving it to disk
+ bool LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value);
+ //! Look up a destination data tuple in the store, return true if found false otherwise
+ bool GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const;
- if (nTimeSmart)
- mapValue["timesmart"] = strprintf("%u", nTimeSmart);
- }
+ //! Adds a watch-only address to the store, and saves it to disk.
+ bool AddWatchOnly(const CScript &dest);
+ bool RemoveWatchOnly(const CScript &dest);
+ //! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
+ bool LoadWatchOnly(const CScript &dest);
+
+ bool Unlock(const SecureString& strWalletPassphrase);
+ bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
+ bool EncryptWallet(const SecureString& strWalletPassphrase);
+
+ void GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const;
+
+ /**
+ * Increment the next transaction order id
+ * @return next transaction order id
+ */
+ int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL);
+
+ typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair;
+ typedef std::multimap<int64_t, TxPair > TxItems;
+
+ /**
+ * Get the wallet's activity log
+ * @return multimap of ordered transactions and accounting entries
+ * @warning Returned pointers are *only* valid within the scope of passed acentries
+ */
+ TxItems OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount = "");
+
+ void MarkDirty();
+ bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb);
+ void SyncTransaction(const CTransaction& tx, const CBlock* pblock);
+ bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate);
+ void EraseFromWallet(const uint256 &hash);
+ int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
+ void ReacceptWalletTransactions();
+ void ResendWalletTransactions();
+ CAmount GetBalance() const;
+ CAmount GetUnconfirmedBalance() const;
+ CAmount GetImmatureBalance() const;
+ CAmount GetWatchOnlyBalance() const;
+ CAmount GetUnconfirmedWatchOnlyBalance() const;
+ CAmount GetImmatureWatchOnlyBalance() const;
+ bool CreateTransaction(const std::vector<CRecipient>& vecSend,
+ CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, const CCoinControl *coinControl = NULL);
+ bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
- READWRITE(*(CMerkleTx*)this);
- std::vector<CMerkleTx> vUnused; //! Used to be vtxPrev
- READWRITE(vUnused);
- READWRITE(mapValue);
- READWRITE(vOrderForm);
- READWRITE(fTimeReceivedIsTxTime);
- READWRITE(nTimeReceived);
- READWRITE(fFromMe);
- READWRITE(fSpent);
+ static CFeeRate minTxFee;
+ static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool);
- if (ser_action.ForRead())
- {
- strFromAccount = mapValue["fromaccount"];
+ bool NewKeyPool();
+ bool TopUpKeyPool(unsigned int kpSize = 0);
+ void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool);
+ void KeepKey(int64_t nIndex);
+ void ReturnKey(int64_t nIndex);
+ bool GetKeyFromPool(CPubKey &key);
+ int64_t GetOldestKeyPoolTime();
+ void GetAllReserveKeys(std::set<CKeyID>& setAddress) const;
- ReadOrderPos(nOrderPos, mapValue);
+ std::set< std::set<CTxDestination> > GetAddressGroupings();
+ std::map<CTxDestination, CAmount> GetAddressBalances();
- nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0;
- }
+ std::set<CTxDestination> GetAccountAddresses(std::string strAccount) const;
- mapValue.erase("fromaccount");
- mapValue.erase("version");
- mapValue.erase("spent");
- mapValue.erase("n");
- mapValue.erase("timesmart");
+ isminetype IsMine(const CTxIn& txin) const;
+ CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const;
+ isminetype IsMine(const CTxOut& txout) const
+ {
+ return ::IsMine(*this, txout.scriptPubKey);
}
-
- //! make sure balances are recalculated
- void MarkDirty()
+ CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const
{
- fCreditCached = false;
- fAvailableCreditCached = false;
- fWatchDebitCached = false;
- fWatchCreditCached = false;
- fAvailableWatchCreditCached = false;
- fImmatureWatchCreditCached = false;
- fDebitCached = false;
- fChangeCached = false;
+ if (!MoneyRange(txout.nValue))
+ throw std::runtime_error("CWallet::GetCredit(): value out of range");
+ return ((IsMine(txout) & filter) ? txout.nValue : 0);
}
-
- void BindWallet(CWallet *pwalletIn)
+ bool IsChange(const CTxOut& txout) const;
+ CAmount GetChange(const CTxOut& txout) const
{
- pwallet = pwalletIn;
- MarkDirty();
+ if (!MoneyRange(txout.nValue))
+ throw std::runtime_error("CWallet::GetChange(): value out of range");
+ return (IsChange(txout) ? txout.nValue : 0);
}
-
- //! filter decides which addresses will count towards the debit
- CAmount GetDebit(const isminefilter& filter) const
+ bool IsMine(const CTransaction& tx) const
{
- if (vin.empty())
- return 0;
-
- CAmount debit = 0;
- if(filter & ISMINE_SPENDABLE)
- {
- if (fDebitCached)
- debit += nDebitCached;
- else
- {
- nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
- fDebitCached = true;
- debit += nDebitCached;
- }
- }
- if(filter & ISMINE_WATCH_ONLY)
- {
- if(fWatchDebitCached)
- debit += nWatchDebitCached;
- else
- {
- nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
- fWatchDebitCached = true;
- debit += nWatchDebitCached;
- }
- }
- return debit;
+ BOOST_FOREACH(const CTxOut& txout, tx.vout)
+ if (IsMine(txout))
+ return true;
+ return false;
}
-
- CAmount GetCredit(const isminefilter& filter) const
+ /** should probably be renamed to IsRelevantToMe */
+ bool IsFromMe(const CTransaction& tx) const
{
- // Must wait until coinbase is safely deep enough in the chain before valuing it
- if (IsCoinBase() && GetBlocksToMaturity() > 0)
- return 0;
-
- int64_t credit = 0;
- if (filter & ISMINE_SPENDABLE)
- {
- // GetBalance can assume transactions in mapWallet won't change
- if (fCreditCached)
- credit += nCreditCached;
- else
- {
- nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
- fCreditCached = true;
- credit += nCreditCached;
- }
- }
- if (filter & ISMINE_WATCH_ONLY)
- {
- if (fWatchCreditCached)
- credit += nWatchCreditCached;
- else
- {
- nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
- fWatchCreditCached = true;
- credit += nWatchCreditCached;
- }
- }
- return credit;
+ return (GetDebit(tx, ISMINE_ALL) > 0);
}
-
- CAmount GetImmatureCredit(bool fUseCache=true) const
+ CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const
{
- if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
+ CAmount nDebit = 0;
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
- if (fUseCache && fImmatureCreditCached)
- return nImmatureCreditCached;
- nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
- fImmatureCreditCached = true;
- return nImmatureCreditCached;
+ nDebit += GetDebit(txin, filter);
+ if (!MoneyRange(nDebit))
+ throw std::runtime_error("CWallet::GetDebit(): value out of range");
}
-
- return 0;
+ return nDebit;
}
-
- CAmount GetAvailableCredit(bool fUseCache=true) const
+ CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const
{
- if (pwallet == 0)
- return 0;
-
- // Must wait until coinbase is safely deep enough in the chain before valuing it
- if (IsCoinBase() && GetBlocksToMaturity() > 0)
- return 0;
-
- if (fUseCache && fAvailableCreditCached)
- return nAvailableCreditCached;
-
CAmount nCredit = 0;
- uint256 hashTx = GetHash();
- for (unsigned int i = 0; i < vout.size(); i++)
+ BOOST_FOREACH(const CTxOut& txout, tx.vout)
{
- if (!pwallet->IsSpent(hashTx, i))
- {
- const CTxOut &txout = vout[i];
- nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE);
- if (!MoneyRange(nCredit))
- throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
- }
+ nCredit += GetCredit(txout, filter);
+ if (!MoneyRange(nCredit))
+ throw std::runtime_error("CWallet::GetCredit(): value out of range");
}
-
- nAvailableCreditCached = nCredit;
- fAvailableCreditCached = true;
return nCredit;
}
-
- CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const
+ CAmount GetChange(const CTransaction& tx) const
{
- if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
+ CAmount nChange = 0;
+ BOOST_FOREACH(const CTxOut& txout, tx.vout)
{
- if (fUseCache && fImmatureWatchCreditCached)
- return nImmatureWatchCreditCached;
- nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
- fImmatureWatchCreditCached = true;
- return nImmatureWatchCreditCached;
+ nChange += GetChange(txout);
+ if (!MoneyRange(nChange))
+ throw std::runtime_error("CWallet::GetChange(): value out of range");
}
-
- return 0;
+ return nChange;
}
+ void SetBestChain(const CBlockLocator& loc);
- CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const
- {
- if (pwallet == 0)
- return 0;
+ DBErrors LoadWallet(bool& fFirstRunRet);
+ DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx);
+
+ bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose);
- // Must wait until coinbase is safely deep enough in the chain before valuing it
- if (IsCoinBase() && GetBlocksToMaturity() > 0)
- return 0;
+ bool DelAddressBook(const CTxDestination& address);
- if (fUseCache && fAvailableWatchCreditCached)
- return nAvailableWatchCreditCached;
+ void UpdatedTransaction(const uint256 &hashTx);
- CAmount nCredit = 0;
- for (unsigned int i = 0; i < vout.size(); i++)
+ void Inventory(const uint256 &hash)
+ {
{
- if (!pwallet->IsSpent(GetHash(), i))
- {
- const CTxOut &txout = vout[i];
- nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY);
- if (!MoneyRange(nCredit))
- throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
- }
+ LOCK(cs_wallet);
+ std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
+ if (mi != mapRequestCount.end())
+ (*mi).second++;
}
-
- nAvailableWatchCreditCached = nCredit;
- fAvailableWatchCreditCached = true;
- return nCredit;
}
- CAmount GetChange() const
+ unsigned int GetKeyPoolSize()
{
- if (fChangeCached)
- return nChangeCached;
- nChangeCached = pwallet->GetChange(*this);
- fChangeCached = true;
- return nChangeCached;
+ AssertLockHeld(cs_wallet); // setKeyPool
+ return setKeyPool.size();
}
- void GetAmounts(std::list<COutputEntry>& listReceived,
- std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const;
-
- void GetAccountAmounts(const std::string& strAccount, CAmount& nReceived,
- CAmount& nSent, CAmount& nFee, const isminefilter& filter) const;
-
- bool IsFromMe(const isminefilter& filter) const
- {
- return (GetDebit(filter) > 0);
- }
+ bool SetDefaultKey(const CPubKey &vchPubKey);
- bool IsTrusted() const
- {
- // Quick answer in most cases
- if (!IsFinalTx(*this))
- return false;
- int nDepth = GetDepthInMainChain();
- if (nDepth >= 1)
- return true;
- if (nDepth < 0)
- return false;
- if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
- return false;
-
- // Trusted if all inputs are from us and are in the mempool:
- BOOST_FOREACH(const CTxIn& txin, vin)
- {
- // Transactions not sent by us: not trusted
- const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
- if (parent == NULL)
- return false;
- const CTxOut& parentOut = parent->vout[txin.prevout.n];
- if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
- return false;
- }
- return true;
- }
+ //! signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
+ bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false);
- bool WriteToDisk();
+ //! change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format)
+ bool SetMaxVersion(int nVersion);
- int64_t GetTxTime() const;
- int GetRequestCount() const;
+ //! get the current wallet format (the oldest client version guaranteed to understand this wallet)
+ int GetVersion() { LOCK(cs_wallet); return nWalletVersion; }
- void RelayWalletTransaction();
+ //! Get wallet transactions that conflict with given transaction (spend same outputs)
+ std::set<uint256> GetConflicts(const uint256& txid) const;
- std::set<uint256> GetConflicts() const;
-};
+ /**
+ * Address book entry changed.
+ * @note called with lock cs_wallet held.
+ */
+ boost::signals2::signal<void (CWallet *wallet, const CTxDestination
+ &address, const std::string &label, bool isMine,
+ const std::string &purpose,
+ ChangeType status)> NotifyAddressBookChanged;
+ /**
+ * Wallet transaction added, removed or updated.
+ * @note called with lock cs_wallet held.
+ */
+ boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx,
+ ChangeType status)> NotifyTransactionChanged;
+ /** Show progress e.g. for rescan */
+ boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress;
+ /** Watch-only address added */
+ boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged;
+};
-class COutput
+/** A key allocated from the key pool. */
+class CReserveKey
{
+protected:
+ CWallet* pwallet;
+ int64_t nIndex;
+ CPubKey vchPubKey;
public:
- const CWalletTx *tx;
- int i;
- int nDepth;
- bool fSpendable;
-
- COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn)
+ CReserveKey(CWallet* pwalletIn)
{
- tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn;
+ nIndex = -1;
+ pwallet = pwalletIn;
}
- std::string ToString() const;
-};
-
-
-
-
-/** Private key that includes an expiration date in case it never gets used. */
-class CWalletKey
-{
-public:
- CPrivKey vchPrivKey;
- int64_t nTimeCreated;
- int64_t nTimeExpires;
- std::string strComment;
- //! todo: add something to note what created it (user, getnewaddress, change)
- //! maybe should have a map<string, string> property map
-
- CWalletKey(int64_t nExpires=0);
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- if (!(nType & SER_GETHASH))
- READWRITE(nVersion);
- READWRITE(vchPrivKey);
- READWRITE(nTimeCreated);
- READWRITE(nTimeExpires);
- READWRITE(LIMITED_STRING(strComment, 65536));
+ ~CReserveKey()
+ {
+ ReturnKey();
}
-};
-
-
-
+ void ReturnKey();
+ bool GetReservedKey(CPubKey &pubkey);
+ void KeepKey();
+};
/**
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
case TX_MULTISIG:
{
// Only consider transactions "mine" if we own ALL the
- // keys involved. multi-signature transactions that are
+ // keys involved. Multi-signature transactions that are
// partially owned (somebody else has a key that can spend
// them) enable spend-out-from-under-you attacks, especially
// in shared-wallet situations.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
+// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "walletdb.h"
#include <boost/scoped_ptr.hpp>
#include <boost/thread.hpp>
-using namespace boost;
using namespace std;
static uint64_t nAccountingEntryNumber = 0;
Dbc* pcursor = GetCursor();
if (!pcursor)
- throw runtime_error("CWalletDB::ListAccountCreditDebit() : cannot create DB cursor");
+ throw runtime_error("CWalletDB::ListAccountCreditDebit(): cannot create DB cursor");
unsigned int fFlags = DB_SET_RANGE;
while (true)
{
else if (ret != 0)
{
pcursor->close();
- throw runtime_error("CWalletDB::ListAccountCreditDebit() : error scanning DB");
+ throw runtime_error("CWalletDB::ListAccountCreditDebit(): error scanning DB");
}
// Unserialize
if (wtx.nOrderPos == -1)
wss.fAnyUnordered = true;
- pwallet->AddToWallet(wtx, true);
+ pwallet->AddToWallet(wtx, true, NULL);
}
else if (strType == "acentry")
{
}
CKey key;
CPrivKey pkey;
- uint256 hash = 0;
+ uint256 hash;
if (strType == "key")
{
{
ssValue >> hash;
}
- catch(...){}
+ catch (...) {}
bool fSkipCheck = false;
- if (hash != 0)
+ if (!hash.IsNull())
{
// hash pubkey/privkey to accelerate wallet load
std::vector<unsigned char> vchKey;
}
pcursor->close();
}
- catch (boost::thread_interrupted) {
+ catch (const boost::thread_interrupted&) {
throw;
}
catch (...) {
}
pcursor->close();
}
- catch (boost::thread_interrupted) {
+ catch (const boost::thread_interrupted&) {
throw;
}
catch (...) {
bitdb.mapFileUseCount.erase(wallet.strWalletFile);
// Copy wallet.dat
- filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile;
- filesystem::path pathDest(strDest);
- if (filesystem::is_directory(pathDest))
+ boost::filesystem::path pathSrc = GetDataDir() / wallet.strWalletFile;
+ boost::filesystem::path pathDest(strDest);
+ if (boost::filesystem::is_directory(pathDest))
pathDest /= wallet.strWalletFile;
try {
#if BOOST_VERSION >= 104000
- filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists);
+ boost::filesystem::copy_file(pathSrc, pathDest, boost::filesystem::copy_option::overwrite_if_exists);
#else
- filesystem::copy_file(pathSrc, pathDest);
+ boost::filesystem::copy_file(pathSrc, pathDest);
#endif
LogPrintf("copied wallet.dat to %s\n", pathDest.string());
return true;
- } catch(const filesystem::filesystem_error &e) {
+ } catch (const boost::filesystem::filesystem_error& e) {
LogPrintf("error copying wallet.dat to %s - %s\n", pathDest.string(), e.what());
return false;
}
int64_t now = GetTime();
std::string newFilename = strprintf("wallet.%d.bak", now);
- int result = dbenv.dbenv.dbrename(NULL, filename.c_str(), NULL,
- newFilename.c_str(), DB_AUTO_COMMIT);
+ int result = dbenv.dbenv->dbrename(NULL, filename.c_str(), NULL,
+ newFilename.c_str(), DB_AUTO_COMMIT);
if (result == 0)
LogPrintf("Renamed %s to %s\n", filename, newFilename);
else
LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size());
bool fSuccess = allOK;
- boost::scoped_ptr<Db> pdbCopy(new Db(&dbenv.dbenv, 0));
+ boost::scoped_ptr<Db> pdbCopy(new Db(dbenv.dbenv, 0));
int ret = pdbCopy->open(NULL, // Txn pointer
filename.c_str(), // Filename
"main", // Logical db name
// 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-2013 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_WALLETDB_H
class CWalletDB : public CDB
{
public:
- CWalletDB(const std::string& strFilename, const char* pszMode = "r+") : CDB(strFilename, pszMode)
+ CWalletDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnClose = true) : CDB(strFilename, pszMode, fFlushOnClose)
{
}