aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--depends/Makefile14
-rw-r--r--depends/README.packages12
-rw-r--r--depends/README.usage1
-rw-r--r--depends/config.site.in13
-rw-r--r--depends/funcs.mk71
-rw-r--r--depends/hosts/darwin.mk10
-rw-r--r--depends/hosts/default.mk5
-rw-r--r--depends/hosts/linux.mk10
-rw-r--r--depends/hosts/mingw32.mk10
-rw-r--r--depends/packages/boost.mk6
-rw-r--r--depends/packages/miniupnpc.mk2
-rw-r--r--depends/packages/openssl.mk2
-rw-r--r--depends/packages/qt.mk13
-rw-r--r--doc/release-process.md3
-rw-r--r--src/core_io.h1
-rw-r--r--src/core_write.cpp35
-rw-r--r--src/key.cpp8
-rw-r--r--src/key.h2
-rw-r--r--src/script/interpreter.cpp3
-rw-r--r--src/serialize.h2
-rw-r--r--src/test/data/script_invalid.json24
-rw-r--r--src/test/data/script_valid.json25
-rw-r--r--src/test/getarg_tests.cpp3
-rw-r--r--src/test/script_tests.cpp325
-rw-r--r--src/test/transaction_tests.cpp42
26 files changed, 544 insertions, 102 deletions
diff --git a/.travis.yml b/.travis.yml
index 54799362a2..155ac012d8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -27,9 +27,9 @@ matrix:
- compiler: "true 1"
env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
- compiler: "true 2"
- env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_QT=1 NO_WALLET=1 NO_UPNP=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat CPPFLAGS=-DDEBUG_LOCKORDER"
+ env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat CPPFLAGS=-DDEBUG_LOCKORDER"
- compiler: "true 3"
- env: HOST=x86_64-unknown-linux-gnu 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"
- compiler: "true 4"
env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
- compiler: "true 5"
diff --git a/depends/Makefile b/depends/Makefile
index f5fb5b865f..fc763bedeb 100644
--- a/depends/Makefile
+++ b/depends/Makefile
@@ -22,6 +22,12 @@ host:=$(HOST)
host_toolchain:=$(HOST)-
endif
+ifneq ($(DEBUG),)
+release_type=debug
+else
+release_type=release
+endif
+
base_build_dir=$(BASEDIR)/work/build
base_staging_dir=$(BASEDIR)/work/staging
canonical_host:=$(shell ./config.sub $(HOST))
@@ -103,12 +109,14 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_
-e 's|@STRIP@|$(toolchain_path)$(host_STRIP)|' \
-e 's|@build_os@|$(build_os)|' \
-e 's|@host_os@|$(host_os)|' \
- -e 's|@CFLAGS@|$(host_CFLAGS)|' \
- -e 's|@CXXFLAGS@|$(host_CXXFLAGS)|' \
- -e 's|@LDFLAGS@|$(host_LDFLAGS)|' \
+ -e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \
+ -e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS) $(host_$(release_type)_CXXFLAGS))|' \
+ -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \
+ -e 's|@LDFLAGS@|$(strip $(host_LDFLAGS) $(host_$(release_type)_LDFLAGS))|' \
-e 's|@no_qt@|$(NO_QT)|' \
-e 's|@no_wallet@|$(NO_WALLET)|' \
-e 's|@no_upnp@|$(NO_UPNP)|' \
+ -e 's|@debug@|$(DEBUG)|' \
$< > $@
$(AT)touch $@
diff --git a/depends/README.packages b/depends/README.packages
index c35abfbdc1..5ab7ed7dee 100644
--- a/depends/README.packages
+++ b/depends/README.packages
@@ -65,10 +65,22 @@ These variables may be set to override or append their default values.
$(package)_config_env
$(package)_build_env
$(package)_stage_env
+ $(package)_build_opts
+ $(package)_config_opts
The *_env variables are used to add environment variables to the respective
commands.
+Many variables respect a debug/release suffix as well, in order to use them for
+only the appropriate build config. For example:
+ $(package)_cflags_release = -O3
+ $(package)_cflags_i686_debug = -g
+ $(package)_config_opts_release = --disable-debug
+
+These will be used in addition to the options that do not specify
+debug/release. All builds are considered to be release unless DEBUG=1 is set by
+the user.
+
Other variables may be defined as needed.
Build commands:
diff --git a/depends/README.usage b/depends/README.usage
index 0aacefbf94..d3c57956f1 100644
--- a/depends/README.usage
+++ b/depends/README.usage
@@ -22,6 +22,7 @@ FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before givin
NO_QT: Don't download/build/cache qt and its dependencies
NO_WALLET: Don't download/build/cache libs needed to enable the wallet
NO_UPNP: Don't download/build/cache packages needed for enabling upnp
+DEBUG: disable some optimizations and enable more runtime checking
If some packages are not built, for example 'make NO_WALLET=1', the appropriate
options will be passed to bitcoin's configure. In this case, --disable-wallet.
diff --git a/depends/config.site.in b/depends/config.site.in
index 1df04eec3f..3426050cd3 100644
--- a/depends/config.site.in
+++ b/depends/config.site.in
@@ -52,7 +52,9 @@ export PATH=$prefix/native/bin:$PATH
export PKG_CONFIG="`which pkg-config` --static"
export PKG_CONFIG_LIBDIR=$prefix/lib/pkgconfig
export PKG_CONFIG_PATH=$prefix/share/pkgconfig
+
export CPPFLAGS="-I$prefix/include/ $CPPFLAGS"
+export LDFLAGS="-L$prefix/lib $LDFLAGS"
export CC="@CC@"
export CXX="@CXX@"
@@ -75,10 +77,19 @@ if test -n "@NM@"; then
ac_cv_path_ac_pt_NM=${NM}
fi
+if test -n "@debug@"; then
+ enable_reduce_exports=no
+fi
+
if test -n "@CFLAGS@"; then
export CFLAGS="@CFLAGS@ $CFLAGS"
fi
if test -n "@CXXFLAGS@"; then
export CXXFLAGS="@CXXFLAGS@ $CXXFLAGS"
fi
-export LDFLAGS="-L$prefix/lib @LDFLAGS@ $LDFLAGS"
+if test -n "@CPPFLAGS@"; then
+ export CPPFLAGS="@CPPFLAGS@ $CPPFLAGS"
+fi
+if test -n "@LDFLAGS@"; then
+ export LDFLAGS="@LDFLAGS@ $LDFLAGS"
+fi
diff --git a/depends/funcs.mk b/depends/funcs.mk
index 28bfb85492..c1fc0a0e33 100644
--- a/depends/funcs.mk
+++ b/depends/funcs.mk
@@ -8,10 +8,10 @@ $(1)_ar=$($($(1)_type)_AR)
$(1)_ranlib=$($($(1)_type)_RANLIB)
$(1)_libtool=$($($(1)_type)_LIBTOOL)
$(1)_nm=$($($(1)_type)_NM)
-$(1)_cflags=$($($(1)_type)_CFLAGS)
-$(1)_cxxflags=$($($(1)_type)_CXXFLAGS)
-$(1)_ldflags=$($($(1)_type)_LDFLAGS) -L$($($(1)_type)_prefix)/lib
-$(1)_cppflags:=-I$($($(1)_type)_prefix)/include
+$(1)_cflags=$($($(1)_type)_CFLAGS) $($($(1)_type)_$(release_type)_CFLAGS)
+$(1)_cxxflags=$($($(1)_type)_CXXFLAGS) $($($(1)_type)_$(release_type)_CXXFLAGS)
+$(1)_ldflags=$($($(1)_type)_LDFLAGS) $($($(1)_type)_$(release_type)_LDFLAGS) -L$($($(1)_type)_prefix)/lib
+$(1)_cppflags=$($($(1)_type)_CPPFLAGS) $($($(1)_type)_$(release_type)_CPPFLAGS) -I$($($(1)_type)_prefix)/include
$(1)_recipe_hash:=
endef
@@ -38,7 +38,7 @@ define int_get_build_id
$(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies))
$(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($(1)_dependencies)))
$(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash)))
-$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash) $($(1)_build_id_deps))
+$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps))
$(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)))
final_build_id_long+=$($(package)_build_id_long)
@@ -83,33 +83,40 @@ endef
define int_config_attach_build_config
$(eval $(call $(1)_set_vars,$(1)))
-$(1)_cflags+=$($(1)_cflags_$(host_arch))
-$(1)_cflags+=$($(1)_cflags_$(host_os))
-$(1)_cflags+=$($(1)_cflags_$(host_arch)_$(host_os))
-
-$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch))
-$(1)_cxxflags+=$($(1)_cxxflags_$(host_os))
-$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch)_$(host_os))
-
-$(1)_cppflags+=$($(1)_cppflags_$(host_arch))
-$(1)_cppflags+=$($(1)_cppflags_$(host_os))
-$(1)_cppflags+=$($(1)_cppflags_$(host_arch)_$(host_os))
-
-$(1)_ldflags+=$($(1)_ldflags_$(host_arch))
-$(1)_ldflags+=$($(1)_ldflags_$(host_os))
-$(1)_ldflags+=$($(1)_ldflags_$(host_arch)_$(host_os))
-
-$(1)_build_opts+=$$($(1)_build_opts_$(host_arch))
-$(1)_build_opts+=$$($(1)_build_opts_$(host_os))
-$(1)_build_opts+=$$($(1)_build_opts_$(host_arch)_$(host_os))
-
-$(1)_config_opts+=$$($(1)_config_opts_$(host_arch))
-$(1)_config_opts+=$$($(1)_config_opts_$(host_os))
-$(1)_config_opts+=$$($(1)_config_opts_$(host_arch)_$(host_os))
-
-$(1)_config_env+=$($(1)_config_env_$(host_arch))
-$(1)_config_env+=$($(1)_config_env_$(host_os))
-$(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os))
+$(1)_cflags+=$($(1)_cflags_$(release_type))
+$(1)_cflags+=$($(1)_cflags_$(host_arch)) $($(1)_cflags_$(host_arch)_$(release_type))
+$(1)_cflags+=$($(1)_cflags_$(host_os)) $($(1)_cflags_$(host_os)_$(release_type))
+$(1)_cflags+=$($(1)_cflags_$(host_arch)_$(host_os)) $($(1)_cflags_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_cxxflags+=$($(1)_cxxflags_$(release_type))
+$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch)) $($(1)_cxxflags_$(host_arch)_$(release_type))
+$(1)_cxxflags+=$($(1)_cxxflags_$(host_os)) $($(1)_cxxflags_$(host_os)_$(release_type))
+$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch)_$(host_os)) $($(1)_cxxflags_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_cppflags+=$($(1)_cppflags_$(release_type))
+$(1)_cppflags+=$($(1)_cppflags_$(host_arch)) $($(1)_cppflags_$(host_arch)_$(release_type))
+$(1)_cppflags+=$($(1)_cppflags_$(host_os)) $($(1)_cppflags_$(host_os)_$(release_type))
+$(1)_cppflags+=$($(1)_cppflags_$(host_arch)_$(host_os)) $($(1)_cppflags_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_ldflags+=$($(1)_ldflags_$(release_type))
+$(1)_ldflags+=$($(1)_ldflags_$(host_arch)) $($(1)_ldflags_$(host_arch)_$(release_type))
+$(1)_ldflags+=$($(1)_ldflags_$(host_os)) $($(1)_ldflags_$(host_os)_$(release_type))
+$(1)_ldflags+=$($(1)_ldflags_$(host_arch)_$(host_os)) $($(1)_ldflags_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_build_opts+=$$($(1)_build_opts_$(release_type))
+$(1)_build_opts+=$$($(1)_build_opts_$(host_arch)) $$($(1)_build_opts_$(host_arch)_$(release_type))
+$(1)_build_opts+=$$($(1)_build_opts_$(host_os)) $$($(1)_build_opts_$(host_os)_$(release_type))
+$(1)_build_opts+=$$($(1)_build_opts_$(host_arch)_$(host_os)) $$($(1)_build_opts_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_config_opts+=$$($(1)_config_opts_$(release_type))
+$(1)_config_opts+=$$($(1)_config_opts_$(host_arch)) $$($(1)_config_opts_$(host_arch)_$(release_type))
+$(1)_config_opts+=$$($(1)_config_opts_$(host_os)) $$($(1)_config_opts_$(host_os)_$(release_type))
+$(1)_config_opts+=$$($(1)_config_opts_$(host_arch)_$(host_os)) $$($(1)_config_opts_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_config_env+=$$($(1)_config_env_$(release_type))
+$(1)_config_env+=$($(1)_config_env_$(host_arch)) $($(1)_config_env_$(host_arch)_$(release_type))
+$(1)_config_env+=$($(1)_config_env_$(host_os)) $($(1)_config_env_$(host_os)_$(release_type))
+$(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os)) $($(1)_config_env_$(host_arch)_$(host_os)_$(release_type))
$(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig
$(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig
diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk
index 9e2415655e..8d718eba17 100644
--- a/depends/hosts/darwin.mk
+++ b/depends/hosts/darwin.mk
@@ -3,6 +3,14 @@ OSX_SDK_VERSION=10.7
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)
-darwin_CFLAGS=-pipe -O2
+
+darwin_CFLAGS=-pipe
darwin_CXXFLAGS=$(darwin_CFLAGS)
+
+darwin_release_CFLAGS=-O2
+darwin_release_CXXFLAGS=$(darwin_release_CFLAGS)
+
+darwin_debug_CFLAGS=-O1
+darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS)
+
darwin_native_toolchain=native_cctools
diff --git a/depends/hosts/default.mk b/depends/hosts/default.mk
index b9fe5d858a..6f60d6b3fd 100644
--- a/depends/hosts/default.mk
+++ b/depends/hosts/default.mk
@@ -11,13 +11,16 @@ default_host_NM = $(host_toolchain)nm
define add_host_tool_func
$(host_os)_$1?=$$(default_host_$1)
$(host_arch)_$(host_os)_$1?=$$($(host_os)_$1)
+$(host_arch)_$(host_os)_$(release_type)_$1?=$$($(host_os)_$1)
host_$1=$$($(host_arch)_$(host_os)_$1)
endef
define add_host_flags_func
$(host_arch)_$(host_os)_$1 += $($(host_os)_$1)
+$(host_arch)_$(host_os)_$(release_type)_$1 += $($(host_os)_$(release_type)_$1)
host_$1 = $$($(host_arch)_$(host_os)_$1)
+host_$(release_type)_$1 = $$($(host_arch)_$(host_os)_$(release_type)_$1)
endef
$(foreach tool,CC CXX AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL,$(eval $(call add_host_tool_func,$(tool))))
-$(foreach flags,CFLAGS CXXFLAGS LDFLAGS, $(eval $(call add_host_flags_func,$(flags))))
+$(foreach flags,CFLAGS CXXFLAGS CPPFLAGS LDFLAGS, $(eval $(call add_host_flags_func,$(flags))))
diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk
index 194d71d557..b13a0f1ad7 100644
--- a/depends/hosts/linux.mk
+++ b/depends/hosts/linux.mk
@@ -1,6 +1,14 @@
-linux_CFLAGS=-pipe -O2
+linux_CFLAGS=-pipe
linux_CXXFLAGS=$(linux_CFLAGS)
+linux_release_CFLAGS=-O2
+linux_release_CXXFLAGS=$(linux_release_CFLAGS)
+
+linux_debug_CFLAGS=-O1
+linux_debug_CXXFLAGS=$(linux_debug_CFLAGS)
+
+linux_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
+
ifeq (86,$(findstring 86,$(build_arch)))
i686_linux_CC=gcc -m32
i686_linux_CXX=g++ -m32
diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk
index ffe4a55842..dbfb62fdcf 100644
--- a/depends/hosts/mingw32.mk
+++ b/depends/hosts/mingw32.mk
@@ -1,2 +1,10 @@
-mingw32_CFLAGS=-pipe -O2
+mingw32_CFLAGS=-pipe
mingw32_CXXFLAGS=$(mingw32_CFLAGS)
+
+mingw32_release_CFLAGS=-O2
+mingw32_release_CXXFLAGS=$(mingw32_release_CFLAGS)
+
+mingw32_debug_CFLAGS=-O1
+mingw32_debug_CXXFLAGS=$(mingw32_debug_CFLAGS)
+
+mingw32_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk
index a3cacbcbb6..98ed3de772 100644
--- a/depends/packages/boost.mk
+++ b/depends/packages/boost.mk
@@ -6,8 +6,10 @@ $(package)_sha256_hash=fff00023dd79486d444c8e29922f4072e1d451fc5a4d2b6075852ead7
$(package)_patches=darwin_boost_atomic-1.patch darwin_boost_atomic-2.patch
define $(package)_set_vars
+$(package)_config_opts_release=variant=release
+$(package)_config_opts_debug=variant=debug
$(package)_config_opts=--layout=tagged --build-type=complete --user-config=user-config.jam
-$(package)_config_opts+=variant=release threading=multi link=static -sNO_BZIP2=1 -sNO_ZLIB=1
+$(package)_config_opts+=threading=multi link=static -sNO_BZIP2=1 -sNO_ZLIB=1
$(package)_config_opts_linux=threadapi=pthread runtime-link=shared
$(package)_config_opts_darwin=--toolset=darwin-4.2.1 runtime-link=shared
$(package)_config_opts_mingw32=binary-format=pe target-os=windows threadapi=win32 runtime-link=static
@@ -26,7 +28,7 @@ endef
define $(package)_preprocess_cmds
patch -p2 < $($(package)_patch_dir)/darwin_boost_atomic-1.patch && \
patch -p2 < $($(package)_patch_dir)/darwin_boost_atomic-2.patch && \
- echo "using $(boost_toolset_$(host_os)) : : $($(package)_cxx) : <cxxflags>\"$($(package)_cxxflags)\" <linkflags>\"$($(package)_ldflags)\" <archiver>\"$(boost_archiver_$(host_os))\" <striper>\"$(host_STRIP)\" <ranlib>\"$(host_RANLIB)\" <rc>\"$(host_WINDRES)\" : ;" > user-config.jam
+ echo "using $(boost_toolset_$(host_os)) : : $($(package)_cxx) : <cxxflags>\"$($(package)_cxxflags) $($(package)_cppflags)\" <linkflags>\"$($(package)_ldflags)\" <archiver>\"$(boost_archiver_$(host_os))\" <striper>\"$(host_STRIP)\" <ranlib>\"$(host_RANLIB)\" <rc>\"$(host_WINDRES)\" : ;" > user-config.jam
endef
define $(package)_config_cmds
diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk
index 30f2d3f315..00101f1b91 100644
--- a/depends/packages/miniupnpc.mk
+++ b/depends/packages/miniupnpc.mk
@@ -8,7 +8,7 @@ define $(package)_set_vars
$(package)_build_opts=CC="$($(package)_cc)"
$(package)_build_opts_darwin=OS=Darwin
$(package)_build_opts_mingw32=-f Makefile.mingw
-$(package)_build_env+=CFLAGS="$($(package)_cflags)" AR="$($(package)_ar)"
+$(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$($(package)_ar)"
endef
define $(package)_preprocess_cmds
diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk
index b1dcc6f81f..3ccdaf6f2f 100644
--- a/depends/packages/openssl.mk
+++ b/depends/packages/openssl.mk
@@ -9,7 +9,7 @@ $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$(
$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl no-zlib no-shared no-dso
$(package)_config_opts+=no-krb5 no-camellia no-capieng no-cast no-cms no-dtls1 no-gost no-gmp no-heartbeats no-idea no-jpake no-md2
$(package)_config_opts+=no-mdc2 no-rc5 no-rdrand no-rfc3779 no-rsax no-sctp no-seed no-sha0 no-static_engine no-whirlpool no-rc2 no-rc4 no-ssl3
-$(package)_config_opts+=$($(package)_cflags)
+$(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags)
$(package)_config_opts_x86_64_linux=-fPIC linux-x86_64
$(package)_config_opts_arm_linux=-fPIC linux-generic32
$(package)_config_opts_x86_64_darwin=darwin64-x86_64-cc
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
index e719e2e506..5fbab57dd4 100644
--- a/depends/packages/qt.mk
+++ b/depends/packages/qt.mk
@@ -10,8 +10,9 @@ $(package)_qt_libs=corelib network widgets gui plugins testlib
$(package)_patches=mac-qmake.conf fix-xcb-include-order.patch qt5-tablet-osx.patch
define $(package)_set_vars
-$(package)_config_opts = -release -opensource -confirm-license
-$(package)_config_opts += -no-audio-backend -no-sql-tds -no-glib -no-icu
+$(package)_config_opts_release = -release
+$(package)_config_opts_debug = -debug
+$(package)_config_opts += -opensource -confirm-license -no-audio-backend -no-sql-tds -no-glib -no-icu
$(package)_config_opts += -no-cups -no-iconv -no-gif -no-audio-backend -no-freetype
$(package)_config_opts += -no-sql-sqlite -no-nis -no-cups -no-iconv -no-pch
$(package)_config_opts += -no-gif -no-feature-style-plastique
@@ -53,7 +54,13 @@ define $(package)_preprocess_cmds
cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h 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 -p1 < $($(package)_patch_dir)/qt5-tablet-osx.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 && \
+ sed -i.old "s|QMAKE_CFLAGS = |QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
+ sed -i.old "s|QMAKE_LFLAGS = |QMAKE_LFLAGS = $($(package)_ldflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
+ sed -i.old "s|QMAKE_CXXFLAGS = |QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf
endef
define $(package)_config_cmds
diff --git a/doc/release-process.md b/doc/release-process.md
index 5b8029955d..940f934baf 100644
--- a/doc/release-process.md
+++ b/doc/release-process.md
@@ -181,9 +181,10 @@ Commit your signature to gitian.sigs:
- Create `SHA256SUMS.asc` for the builds, and GPG-sign it:
```bash
sha256sum * > SHA256SUMS
-gpg --clearsign SHA256SUMS # outputs SHA256SUMS.asc
+gpg --digest-algo sha256 --clearsign SHA256SUMS # outputs SHA256SUMS.asc
rm SHA256SUMS
```
+(the digest algorithm is forced to sha256 to avoid confusion of the `Hash:` header that GPG adds with the SHA256 used for the files)
- Upload zips and installers, as well as `SHA256SUMS.asc` from last step, to the bitcoin.org server
diff --git a/src/core_io.h b/src/core_io.h
index 6268a3bf58..94848f1c3d 100644
--- a/src/core_io.h
+++ b/src/core_io.h
@@ -20,6 +20,7 @@ extern uint256 ParseHashUV(const UniValue& v, const std::string& strName);
extern std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
// core_write.cpp
+extern std::string FormatScript(const CScript& script);
extern std::string EncodeHexTx(const CTransaction& tx);
extern void ScriptPubKeyToUniv(const CScript& scriptPubKey,
UniValue& out, bool fIncludeHex);
diff --git a/src/core_write.cpp b/src/core_write.cpp
index cd64aabf63..40d547fb33 100644
--- a/src/core_write.cpp
+++ b/src/core_write.cpp
@@ -17,6 +17,41 @@
using namespace std;
+string FormatScript(const CScript& script)
+{
+ string ret;
+ CScript::const_iterator it = script.begin();
+ opcodetype op;
+ while (it != script.end()) {
+ CScript::const_iterator it2 = it;
+ vector<unsigned char> vch;
+ if (script.GetOp2(it, op, &vch)) {
+ if (op == OP_0) {
+ ret += "0 ";
+ continue;
+ } else if ((op >= OP_1 && op <= OP_16) || op == OP_1NEGATE) {
+ ret += strprintf("%i ", op - OP_1NEGATE - 1);
+ continue;
+ } else if (op >= OP_NOP && op <= OP_CHECKMULTISIGVERIFY) {
+ string str(GetOpName(op));
+ if (str.substr(0, 3) == string("OP_")) {
+ ret += str.substr(3, string::npos) + " ";
+ continue;
+ }
+ }
+ if (vch.size() > 0) {
+ ret += strprintf("0x%x 0x%x ", HexStr(it2, it - vch.size()), HexStr(it - vch.size(), it));
+ } else {
+ ret += strprintf("0x%x", HexStr(it2, it));
+ }
+ continue;
+ }
+ ret += strprintf("0x%x ", HexStr(it2, script.end()));
+ break;
+ }
+ return ret.substr(0, ret.size() - 1);
+}
+
string EncodeHexTx(const CTransaction& tx)
{
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
diff --git a/src/key.cpp b/src/key.cpp
index 8ed787654a..c2251b4f2a 100644
--- a/src/key.cpp
+++ b/src/key.cpp
@@ -220,7 +220,7 @@ public:
return o2i_ECPublicKey(&pkey, &pbegin, pubkey.size()) != NULL;
}
- bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) {
+ bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool lowS) {
vchSig.clear();
ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
if (sig == NULL)
@@ -232,7 +232,7 @@ public:
BIGNUM *halforder = BN_CTX_get(ctx);
EC_GROUP_get_order(group, order, ctx);
BN_rshift1(halforder, order);
- if (BN_cmp(sig->s, halforder) > 0) {
+ if (lowS && BN_cmp(sig->s, halforder) > 0) {
// enforce low S values, by negating the value (modulo the order) if above order/2.
BN_sub(sig->s, order, sig->s);
}
@@ -467,7 +467,7 @@ CPubKey CKey::GetPubKey() const {
return pubkey;
}
-bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const {
+bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool lowS) const {
if (!fValid)
return false;
#ifdef USE_SECP256K1
@@ -484,7 +484,7 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const {
#else
CECKey key;
key.SetSecretBytes(vch);
- return key.Sign(hash, vchSig);
+ return key.Sign(hash, vchSig, lowS);
#endif
}
diff --git a/src/key.h b/src/key.h
index 3863e95cff..f6f6d35d34 100644
--- a/src/key.h
+++ b/src/key.h
@@ -276,7 +276,7 @@ public:
CPubKey GetPubKey() const;
// Create a DER-serialized signature.
- bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig) const;
+ bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, bool lowS = true) const;
// Create a compact signature (65 bytes), which allows reconstructing the used public key.
// The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index d742fb9eb9..a71f55dd26 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -839,7 +839,8 @@ public:
itBegin = it;
}
}
- s.write((char*)&itBegin[0], it-itBegin);
+ if (itBegin != scriptCode.end())
+ s.write((char*)&itBegin[0], it-itBegin);
}
/** Serialize an input of txTo */
diff --git a/src/serialize.h b/src/serialize.h
index 7f8f933284..68501facf2 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -245,7 +245,7 @@ uint64_t ReadCompactSize(Stream& is)
uint64_t xSize;
READDATA(is, xSize);
nSizeRet = xSize;
- if (nSizeRet < 0x100000000LLu)
+ if (nSizeRet < 0x100000000ULL)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
if (nSizeRet > (uint64_t)MAX_SIZE)
diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json
index 401031ad12..35a6794b01 100644
--- a/src/test/data/script_invalid.json
+++ b/src/test/data/script_invalid.json
@@ -384,18 +384,18 @@ nSequences are max.
["0x00", "'00' EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"],
-["0x48 0x3045022100ea4d62e1fb351ad977596457bb01dfce58e050541784277bd825c33bd98c2a9502203003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkeyhash with wrong signature"],
-["0x47 0x304402207d09de5e34968c3f8b27d8217f173629f1106ee5216aa11d6b1f9813b3a214060220610a6ed25c704f901c6278f4f57fb11eadefdf0b22df298cfb6ce7ea84c86bf401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkeyhash using an anyonecanpay sighash"],
-["0x47 0x3044022028686fb3c8d3e5068cc9924c494fb5026df201d23340896da62fe9bb73fd9d5f02202a239609524959c4ca3651fd0cc48245b0b240862146fc579f3a962a4f46942b01", "0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkey with wrong signature"],
-["0x47 0x3044022054cb0a3fca8694a0c231848ed9f965078148fd653e49dd4b6981fadac0f5ba0702204085be5af427d4561f13a07fd5a1c5ab0ff02126e9ba191448f5a9dae0da585301 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x19 0x76a914751e76e8199196d454941c45d1b3a323f1433bd688ac", "HASH160 0x14 0xcd7b44d0b03f2d026d1e586d7ae18903b0d385f6 EQUAL", "P2SH,STRICTENC", "P2SH with a pay to pubkeyhash inside with wrong signature"],
-["0 0x48 0x3045022100e1c4e8800bd00c9ec3cd3df0e53e63bc5e8c018d0b68099a652f0b121f1a7e020220108dab275be7d1358530d3451d48aed747af77cc54e0423cbae5c572b2e1abb801", "1 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 1 CHECKMULTISIG", "P2SH,STRICTENC", "Raw multisig with one pubkey with wrong signature"],
-["0x49 0x304602220000ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a9502203003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkeyhash with non-DER signature (too much R padding)"],
-["0x47 0x30440220ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a9502203003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkeyhash with non-DER signature (too little R padding)"],
-["0x49 0x3046022100ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a950221003003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkeyhash with non-DER signature (too much S padding)"],
-["0x48 0x3045022100e6eda3fd34862078233463cae19f0b47995e3f892102e5b175175e92a9163cc402204bf58445819093638481084322b61a2d49b68c96fd6fea17ed494722d0d67b4f01", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "P2SH,STRICTENC", "Pay to pubkey with hybrid pubkey encoding"],
-["0x48 0x304502203b56d65863e0cdb89313043c2402f46f518c31658648151b01ec6b5b6c89206a022100d71efefb4c24fab36abb44ade106963d8114c5af1bda033faa1923f54ec4ea6a01", "0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 CHECKSIG", "P2SH,STRICTENC,LOW_S", "Pay to pubkey with high S"],
-["0x47 0x3044022054cb0a3fca8694a0c231848fd9f965078148fd653e49dd4b6980fadac0f5ba0702204085be5af427d4561f13a07fd5a1c5ab0ff02126e9ba191448f5a9dae0da585301 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x19 0x76a914751e76e8199196d454941c45d1b3a323f1433bd688ac", "HASH160 0x14 0xcd7b44d0b03f2d026d1e586d7ae18903b0d385f6 EQUAL", "P2SH,STRICTENC", "P2SH with a pay to pubkeyhash inside with invalid signature"],
-["1 0x48 0x3045022100e1c4e8800bd00c9ec3cd3de0e53e63bc5e8c018d0b68099a652f0b121f1a7e020220108dab275be7d1358530d3451d48aed747af77cc54e0423cbae5c572b2e1abb801", "1 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 1 CHECKMULTISIG", "P2SH,STRICTENC,NULLDUMMY", "Raw multisig with one pubkey with non-zero dummy"],
+["0x47 0x30440220304eff7556bba9560df47873275e64db45f3cd735998ce3f00d2e57b1bb5f31302205c0c9d14b8b80d43e2ac9b87532f1af6d8a3271262bc694ec4e14068392bb0a001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "", "P2PK, bad sig"],
+["0x47 0x3044022037fcdb8e08f41e27588de8bc036d2c4b16eb3d09c1ba53b8f47a0a9c27722a39022058664b7a53b507e71dfafb77193e3786c3f0c119d78ce9104480ee7ece04f09301 0x21 0x03363d90d446b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640", "DUP HASH160 0x14 0xc0834c0c158f53be706d234c38fd52de7eece656 EQUALVERIFY CHECKSIG", "", "P2PKH, bad pubkey"],
+["0x47 0x3044022035e5b6742d299861c84cebaf2ea64145ee427a95facab39e2594d6deebb0c1d602200acb16778faa2e467a59006f342f2535b1418d55ba63a8605b387b7f9ac86d9a01", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", "", "P2PK anyonecanpay marked with normal hashtype"],
+["0x47 0x3044022029b2b8765ca950cf75a69e80b73b7ddfcaa8b27080c2db4c23b36aae60688e790220598ff368e17872ee065aa54d7d3a590682ca5204325b23b31d7da3c4a21ae67901 0x23 0x210279be667ef9dcbbac54a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", "P2SH", "P2SH(P2PK), bad redeemscript"],
+["0x47 0x30440220647f906e63890df5ef1d3fed47ba892b31976c634281079e2bd38504fb54a1fb022021e8811f38fbe90efb6b74cb78da01d9badbac3bafdf70a861d7538a220d0b2601 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", "P2SH", "P2SH(P2PKH), bad sig"],
+["0 0x47 0x304402203ef170402f8887f2ac183f31b1f503b0bc60bfc968dd469b097ea6124aefac5002200612febadc4e4cacc086982cb85830a17af3680c1b6a3cf77c1708af7621cf1301 0 0x47 0x304402207821838251a24a2234844f68e7169e6d11945cdf052ea12bd3e4e37457aceb4402200b6b46c81361e314c740ae5133c072af5fa5c209d65d2db1679e1716f19a538101", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", "3-of-3, 2 sigs"],
+["0 0 0x47 0x304402204661f7795e8db7be3132e8974e9a76d1d24b31f23df94c6fbcea07d1c205789102203f5e45a1c0b085279b58d11b36d5fea5449c3cf16f844ad10124e9b65e8777d201 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL", "P2SH", "P2SH(2-of-3), 1 sig"],
+["0x47 0x304402200052bc1600ca45c71f3538720fe62a5e8548dffd137af04467598c98466e9c0a0220789318ddbc9991ee477974089220a2feb6a6298a7c93d5ff6c25a92a2f4b48d501", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "STRICTENC", "P2PK with too much R padding"],
+["0x48 0x304502206eb7b92628bfb3c4d2a04b65b986987bcbb1af4fceedb144d5a0437b7ee410590221005f57a52df4aa26366742eed0db182fce51fbcd7159011b0644a7c05943eb228901", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "STRICTENC", "P2PK with too much S padding"],
+["0x47 0x30440220d8ad1efd55a3d2b8896495c38aba72056e1b3ca4a6ca15760e843eb1a9b9907602203eb0e8f3d6bec998262dfd03eaeb0f31c4e5105965436dec77550724b3771f3201", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "STRICTENC", "P2PK with too little R padding"],
+["0x48 0x304502206c43e065c8a8db3bbe69015afb86a51fb2fc8870defd41d436da2a197d9d6c12022100fcec35816ee2d84ec271ad159fcabf5dd712157051169e48ac328a7818cdb51e01", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "LOW_S,STRICTENC", "P2PK with high S"],
+["0x01 0x01 0x47 0x304402200e48ba1cf4d7182db94ffb57bd72ea31b5545dc0d1c512e665779b4fb2badc52022054b8388dfc074c708a75b62359b7be46402751ee40c0a111aef38a837b6ed09801 0x47 0x304402201c9820f59c49107bb30e6175cfc9ec95f897b03beb628b4bc854d2b80392aa0602200235d986ae418bcd111b8814f4c26a0ab5f475fb542a44884fc14912a97a252301 0x47 0x304402204cd7894c6f10a871f5b0c1f9c13228f8cdd4050248f0d0f498ee86be69ee3080022051bd2932c7d585eb600c7194235c74da820935f0d67972fd9545673aa1fd023301", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "NULLDUMMY", "3-of-3 with nonzero dummy"],
["The End"]
diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json
index e0b527996c..653f60d982 100644
--- a/src/test/data/script_valid.json
+++ b/src/test/data/script_valid.json
@@ -529,18 +529,19 @@ nSequences are max.
["0x00", "SIZE 0 EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"],
-["0x48 0x3045022100ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a9502203003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkeyhash"],
-["0x47 0x304402207d09de5e34968c3f8b27d8217f173629f1106ee5216aa11d6b1f9813b3a214060220610a6ed25c704f901c6278f4f57fb11eadefdf0b22df298cfb6ce7ea84c86bf481 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Anyonecanpay pay to pubkeyhash"],
-["0x47 0x3044022028686fb3c8d3e5069cc9924c494fb5026df201d23340896da62fe9bb73fd9d5f02202a239609524959c4ca3651fd0cc48245b0b240862146fc579f3a962a4f46942b01", "0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkey"],
-["0x47 0x3044022054cb0a3fca8694a0c231848ed9f965078148fd653e49dd4b6980fadac0f5ba0702204085be5af427d4561f13a07fd5a1c5ab0ff02126e9ba191448f5a9dae0da585301 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x19 0x76a914751e76e8199196d454941c45d1b3a323f1433bd688ac", "HASH160 0x14 0xcd7b44d0b03f2d026d1e586d7ae18903b0d385f6 EQUAL", "P2SH,STRICTENC", "P2SH with a pay to pubkeyhash inside"],
-["0 0x48 0x3045022100e1c4e8800bd00c9ec3cd3de0e53e63bc5e8c018d0b68099a652f0b121f1a7e020220108dab275be7d1358530d3451d48aed747af77cc54e0423cbae5c572b2e1abb801", "1 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 1 CHECKMULTISIG", "P2SH,STRICTENC", "Raw multisig with one pubkey"],
-["0x49 0x304602220000ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a9502203003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH", "Normal pay to pubkeyhash with non-DER signature (too much R padding)"],
-["0x47 0x30440220ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a9502203003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH", "Normal pay to pubkeyhash with non-DER signature (too little R padding)"],
-["0x49 0x3046022100ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a950221003003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH", "Normal pay to pubkeyhash with non-DER signature (too much S padding)"],
-["0x48 0x3045022100e6eda3fd34862078233463cae19f0b47995e3f892102e5b175175e92a9163cc402204bf58445819093638481084322b61a2d49b68c96fd6fea17ed494722d0d67b4f01", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "P2SH", "Pay to pubkey with hybrid pubkey encoding"],
-["0x48 0x304502203b56d65863e0cdb89313043c2402f46f518c31658648151b01ec6b5b6c89206a022100d71efefb4c24fab36abb44ade106963d8114c5af1bda033faa1923f54ec4ea6a01", "0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 CHECKSIG", "P2SH,STRICTENC", "Pay to pubkey with high S"],
-["0x47 0x3044022054cb0a3fca8694a0c231848fd9f965078148fd653e49dd4b6980fadac0f5ba0702204085be5af427d4561f13a07fd5a1c5ab0ff02126e9ba191448f5a9dae0da585301 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x19 0x76a914751e76e8199196d454941c45d1b3a323f1433bd688ac", "HASH160 0x14 0xcd7b44d0b03f2d026d1e586d7ae18903b0d385f6 EQUAL", "STRICTENC", "P2SH with a pay to pubkeyhash inside with invalid signature"],
-["1 0x48 0x3045022100e1c4e8800bd00c9ec3cd3de0e53e63bc5e8c018d0b68099a652f0b121f1a7e020220108dab275be7d1358530d3451d48aed747af77cc54e0423cbae5c572b2e1abb801", "1 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 1 CHECKMULTISIG", "P2SH,STRICTENC", "Raw multisig with one pubkey with non-zero dummy"],
+["0x47 0x3044022007415aa37ce7eaa6146001ac8bdefca0ddcba0e37c5dc08c4ac99392124ebac802207d382307fd53f65778b07b9c63b6e196edeadf0be719130c5db21ff1e700d67501", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "", "P2PK"],
+["0x47 0x3044022069d40999786aeb2fd874f9eb2636461a062dc963471627ed8390a3a5f9556f640220350132a52415ce622f2aadd07f791c591500917ec1f8c5edbc5381ef7942534d01 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508", "DUP HASH160 0x14 0x1018853670f9f3b0582c5b9ee8ce93764ac32b93 EQUALVERIFY CHECKSIG", "", "P2PKH"],
+["0x47 0x30440220519f2a6632ffa134c7811ea2819e9dcc951f0c7baf461f2dffdd09133f3b080a02203ec6bab5eb6619ed7f41b8701d7c6d70cfc83bb26c5c97f54b2ca6e304fc2bb581", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", "", "P2PK anyonecanpay"],
+["0x47 0x30440220279dad2170ffb5639f0a1ea71fc462ee37d75d420d86f84c978bac523c09b7f20220683b2789f5c5528a9e0a0d78f6e40db3f616cf1adb5a5fdef117d5974795cfe201 0x23 0x210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", "P2SH", "P2SH(P2PK)"],
+["0x47 0x3044022066acbfb5ac96b7cbf3f05a2aaf358c32438c45d1d7359dee9fc1ee636940735f02205606a03fd8cbf6a6fcbcba60c8abb1e385c0b5753cb57a97538159106fd3684e01 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", "", "P2SH(P2PKH), bad sig but no VERIFY_P2SH"],
+["0 0x47 0x3044022004e791dd30a64c70e55e84e150c002af9feb3ce0ab1f20e86c53d1209003927502205a60453987fcd72aebaaacebc8ce4b15449cdd79e54cc82cefb83e69dbcfeabf01 0x47 0x304402201d021808ce93dd8574cc4f99ae4f11b44305528b0aecbd9f156f08315173643802200944a0ea5c884bd86180aef76d8b1e444860776b251e47d2d6c651a1c6f9930801 0x47 0x30440220446336d7b7de05ebb5683b82b05248ec7d78e88ae8d6125985f5776c887a4cf90220674ab2b2c2f954ba1cf35457d273c90d0c0c1c224d0ae128628740e81129486801", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", "3-of-3"],
+["0 0x47 0x30440220288b06d057cf0eac434ed0c3be9257cc0ca144dd99c11cc8f1a49467a37d8e8002203c496c72253c528e6bc81c42e683aba974d46041a96ef7b00915c863eb2a702901 0x47 0x304402207ffb4da33f40cac839a43000a187bd76a1ee5bf95e46dc1534b38bb7bd0321db022038c078f29d1831f8eb68ffdc2634c654fb01c3467b6457b98ad220653bb2478501 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL", "P2SH", "P2SH(2-of-3)"],
+["0x47 0x304402200001cae94b795baaafb05db38cf24cd75560cab2c36c91e29fac7d0fd2a723a3022058e2e56e568ce7c4b2b106210d114e1faa079407a6ed4154f230667c7d3583bc01", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", "P2PK with too much R padding but no STRICTENC"],
+["0x48 0x304502206d01de7c2a40ac2bb1231ed97f3890a1782f421d4c28b97166deff317990288f0221005e720213b089355be2cf785d81a82c59307d30e1624f450ed9ca1ebbc11cca6d01", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", "P2PK with too much S padding but no STRICTENC"],
+["0x47 0x30440220f3d8889602147d60d26c1d3b21b8db183eac02bf6d2fec1424c0ef377ca6fd7b02202bae8bfe39d00a432d4538a592e338b0ffc44c17d4b7056043d55063cf91f5ef01", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", "P2PK with too little R padding but no STRICTENC"],
+["0x48 0x3045022021bf9184d94f208ac9f4757ebca9b1cbebf008cfc244fe5be1360b1b9aba0e92022100e55074f72f3a1bfddf2ea4ea7ba984f78822e136fe04c8f9c1363238e0233bd801", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "STRICTENC", "P2PK with high S but no LOW_S"],
+["0x48 0x304502205c3e81aaf2aad0673f349035b180eba783eba7797af91c979920dea6b17a16d6022100d1d46825c68da1b325f320a3503dad27bb818227f64a38d153554bfd360c0e5301", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "LOW_S", "P2PK with high S but no STRICTENC"],
+["0x01 0x01 0x47 0x3044022046ce33d1771b0127dd4c4cef8fdc3218ebdfa60e3793ed700292d8ebd93fb1f402201029d47a414db83e96e31443c2d8b552f971469c4800f5eff7df2f0648521aed01 0x47 0x304402205c53911ad55b054920043962bbda98cf6e57e2db1cd5611138251490baabaa8702201dc80dfceae6007e7772dc13ff6e7ca66a983cb017fe5d46d30118462d83bcf801 0x47 0x304402201937e44a4ec12364f9d32f9d25e7ecbc68aee9ef90069af80efef4c05f6ace9602206c515101c00c75710b32ff7ff8dbaf7c9a0be6e86ed14a0755b47626604f31fd01", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", "3-of-3 with nonzero dummy but no NULLDUMMY"],
["The End"]
]
diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp
index 8cadcdd716..8a984304f4 100644
--- a/src/test/getarg_tests.cpp
+++ b/src/test/getarg_tests.cpp
@@ -16,7 +16,8 @@ BOOST_AUTO_TEST_SUITE(getarg_tests)
static void ResetArgs(const std::string& strArg)
{
std::vector<std::string> vecArg;
- boost::split(vecArg, strArg, boost::is_space(), boost::token_compress_on);
+ if (strArg.size())
+ boost::split(vecArg, strArg, boost::is_space(), boost::token_compress_on);
// Insert dummy executable name:
vecArg.insert(vecArg.begin(), "testbitcoin");
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 178b35fa2d..7f09b3daa1 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -5,12 +5,13 @@
#include "data/script_invalid.json.h"
#include "data/script_valid.json.h"
+#include "core_io.h"
#include "key.h"
#include "keystore.h"
#include "main.h"
#include "script/script.h"
#include "script/sign.h"
-#include "core_io.h"
+#include "util.h"
#include <fstream>
#include <stdint.h>
@@ -36,6 +37,7 @@ using namespace boost::algorithm;
static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
unsigned int ParseScriptFlags(string strFlags);
+string FormatScriptFlags(unsigned int flags);
Array
read_json(const std::string& jsondata)
@@ -68,10 +70,8 @@ CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
return txCredit;
}
-CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScript& scriptPubKey)
+CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CTransaction& txCredit)
{
- CMutableTransaction txCredit = BuildCreditingTransaction(scriptPubKey);
-
CMutableTransaction txSpend;
txSpend.nVersion = 1;
txSpend.nLockTime = 0;
@@ -87,6 +87,317 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CSc
return txSpend;
}
+void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message)
+{
+ BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)), 0, flags) == expect, message);
+}
+
+namespace
+{
+const unsigned char vchKey0[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,0,1};
+const unsigned char vchKey1[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,1,0};
+const unsigned char vchKey2[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,1,0,0};
+
+struct KeyData
+{
+ CKey key0, key0C, key1, key1C, key2, key2C;
+ CPubKey pubkey0, pubkey0C, pubkey0H;
+ CPubKey pubkey1, pubkey1C;
+ CPubKey pubkey2, pubkey2C;
+
+ KeyData()
+ {
+
+ key0.Set(vchKey0, vchKey0 + 32, false);
+ key0C.Set(vchKey0, vchKey0 + 32, true);
+ pubkey0 = key0.GetPubKey();
+ pubkey0H = key0.GetPubKey();
+ pubkey0C = key0C.GetPubKey();
+ *const_cast<unsigned char*>(&pubkey0H[0]) = 0x06 | (pubkey0H[64] & 1);
+
+ key1.Set(vchKey1, vchKey1 + 32, false);
+ key1C.Set(vchKey1, vchKey1 + 32, true);
+ pubkey1 = key1.GetPubKey();
+ pubkey1C = key1C.GetPubKey();
+
+ key2.Set(vchKey2, vchKey2 + 32, false);
+ key2C.Set(vchKey2, vchKey2 + 32, true);
+ pubkey2 = key2.GetPubKey();
+ pubkey2C = key2C.GetPubKey();
+ }
+};
+
+const KeyData keys;
+
+class TestBuilder
+{
+private:
+ CScript scriptPubKey;
+ CTransaction creditTx;
+ CMutableTransaction spendTx;
+ bool havePush;
+ std::vector<unsigned char> push;
+ std::string comment;
+ int flags;
+
+ void DoPush()
+ {
+ if (havePush) {
+ spendTx.vin[0].scriptSig << push;
+ havePush = false;
+ }
+ }
+
+ void DoPush(const std::vector<unsigned char>& data)
+ {
+ DoPush();
+ push = data;
+ havePush = true;
+ }
+
+public:
+ TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_)
+ {
+ if (P2SH) {
+ creditTx = BuildCreditingTransaction(CScript() << OP_HASH160 << redeemScript.GetID() << OP_EQUAL);
+ } else {
+ creditTx = BuildCreditingTransaction(redeemScript);
+ }
+ spendTx = BuildSpendingTransaction(CScript(), creditTx);
+ }
+
+ TestBuilder& Add(const CScript& script)
+ {
+ spendTx.vin[0].scriptSig += script;
+ return *this;
+ }
+
+ TestBuilder& Num(int num)
+ {
+ spendTx.vin[0].scriptSig << CScriptNum(num);
+ return *this;
+ }
+
+ TestBuilder& Push(const std::string& hex)
+ {
+ DoPush(ParseHex(hex));
+ return *this;
+ }
+
+ TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32)
+ {
+ uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType);
+ std::vector<unsigned char> vchSig, r, s;
+ do {
+ key.Sign(hash, vchSig, lenS <= 32);
+ 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]]);
+ } while (lenR != r.size() || lenS != s.size());
+ vchSig.push_back(static_cast<unsigned char>(nHashType));
+ DoPush(vchSig);
+ return *this;
+ }
+
+ TestBuilder& Push(const CPubKey& pubkey)
+ {
+ DoPush(std::vector<unsigned char>(pubkey.begin(), pubkey.end()));
+ return *this;
+ }
+
+ TestBuilder& PushRedeem()
+ {
+ DoPush(static_cast<std::vector<unsigned char> >(scriptPubKey));
+ return *this;
+ }
+
+ TestBuilder& EditPush(unsigned int pos, const std::string& hexin, const std::string& hexout)
+ {
+ assert(havePush);
+ std::vector<unsigned char> datain = ParseHex(hexin);
+ std::vector<unsigned char> dataout = ParseHex(hexout);
+ assert(pos + datain.size() <= push.size());
+ BOOST_CHECK_MESSAGE(std::vector<unsigned char>(push.begin() + pos, push.begin() + pos + datain.size()) == datain, comment);
+ push.erase(push.begin() + pos, push.begin() + pos + datain.size());
+ push.insert(push.begin() + pos, dataout.begin(), dataout.end());
+ return *this;
+ }
+
+ TestBuilder& DamagePush(unsigned int pos)
+ {
+ assert(havePush);
+ assert(pos < push.size());
+ push[pos] ^= 1;
+ return *this;
+ }
+
+ TestBuilder& Test(bool expect)
+ {
+ TestBuilder copy = *this; // Make a copy so we can rollback the push.
+ DoPush();
+ DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, expect, comment);
+ *this = copy;
+ return *this;
+ }
+
+ operator std::string()
+ {
+ DoPush();
+ return "[\"" +
+ FormatScript(spendTx.vin[0].scriptSig) + "\", \"" +
+ FormatScript(creditTx.vout[0].scriptPubKey) + "\", \"" +
+ FormatScriptFlags(flags) + "\", \"" +
+ comment + "\"],\n";
+ }
+
+ std::string GetComment()
+ {
+ return comment;
+ }
+
+ const CScript& GetScriptPubKey()
+ {
+ return creditTx.vout[0].scriptPubKey;
+ }
+};
+}
+
+BOOST_AUTO_TEST_CASE(script_build)
+{
+ std::vector<TestBuilder> good;
+ std::vector<TestBuilder> bad;
+
+ good.push_back(TestBuilder(CScript() << keys.pubkey0 << OP_CHECKSIG,
+ "P2PK", 0
+ ).PushSig(keys.key0));
+ bad.push_back(TestBuilder(CScript() << keys.pubkey0 << OP_CHECKSIG,
+ "P2PK, bad sig", 0
+ ).PushSig(keys.key0).DamagePush(10));
+
+ good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << keys.pubkey1C.GetID() << OP_EQUALVERIFY << OP_CHECKSIG,
+ "P2PKH", 0
+ ).PushSig(keys.key1).Push(keys.pubkey1C));
+ bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << keys.pubkey2C.GetID() << OP_EQUALVERIFY << OP_CHECKSIG,
+ "P2PKH, bad pubkey", 0
+ ).PushSig(keys.key2).Push(keys.pubkey2C).DamagePush(5));
+
+ good.push_back(TestBuilder(CScript() << keys.pubkey1 << OP_CHECKSIG,
+ "P2PK anyonecanpay", 0
+ ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY));
+ bad.push_back(TestBuilder(CScript() << keys.pubkey1 << OP_CHECKSIG,
+ "P2PK anyonecanpay marked with normal hashtype", 0
+ ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY).EditPush(70, "81", "01"));
+
+ good.push_back(TestBuilder(CScript() << keys.pubkey0C << OP_CHECKSIG,
+ "P2SH(P2PK)", SCRIPT_VERIFY_P2SH, true
+ ).PushSig(keys.key0).PushRedeem());
+ bad.push_back(TestBuilder(CScript() << keys.pubkey0C << OP_CHECKSIG,
+ "P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true
+ ).PushSig(keys.key0).PushRedeem().DamagePush(10));
+
+ good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << keys.pubkey1.GetID() << OP_EQUALVERIFY << OP_CHECKSIG,
+ "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0, true
+ ).PushSig(keys.key0).DamagePush(10).PushRedeem());
+ bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << keys.pubkey1.GetID() << OP_EQUALVERIFY << OP_CHECKSIG,
+ "P2SH(P2PKH), bad sig", SCRIPT_VERIFY_P2SH, true
+ ).PushSig(keys.key0).DamagePush(10).PushRedeem());
+
+ good.push_back(TestBuilder(CScript() << OP_3 << keys.pubkey0C << keys.pubkey1C << keys.pubkey2C << OP_3 << OP_CHECKMULTISIG,
+ "3-of-3", 0
+ ).Num(0).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_3 << keys.pubkey0C << keys.pubkey1C << keys.pubkey2C << OP_3 << OP_CHECKMULTISIG,
+ "3-of-3, 2 sigs", 0
+ ).Num(0).PushSig(keys.key0).PushSig(keys.key1).Num(0));
+
+ good.push_back(TestBuilder(CScript() << OP_2 << keys.pubkey0C << keys.pubkey1C << keys.pubkey2C << OP_3 << OP_CHECKMULTISIG,
+ "P2SH(2-of-3)", SCRIPT_VERIFY_P2SH, true
+ ).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem());
+ bad.push_back(TestBuilder(CScript() << OP_2 << keys.pubkey0C << keys.pubkey1C << keys.pubkey2C << OP_3 << OP_CHECKMULTISIG,
+ "P2SH(2-of-3), 1 sig", SCRIPT_VERIFY_P2SH, true
+ ).Num(0).PushSig(keys.key1).Num(0).PushRedeem());
+
+ good.push_back(TestBuilder(CScript() << keys.pubkey1C << OP_CHECKSIG,
+ "P2PK with too much R padding but no STRICTENC", 0
+ ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000"));
+ bad.push_back(TestBuilder(CScript() << keys.pubkey1C << OP_CHECKSIG,
+ "P2PK with too much R padding", SCRIPT_VERIFY_STRICTENC
+ ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000"));
+ good.push_back(TestBuilder(CScript() << keys.pubkey1C << OP_CHECKSIG,
+ "P2PK with too much S padding but no STRICTENC", 0
+ ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100"));
+ bad.push_back(TestBuilder(CScript() << keys.pubkey1C << OP_CHECKSIG,
+ "P2PK with too much S padding", SCRIPT_VERIFY_STRICTENC
+ ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100"));
+ good.push_back(TestBuilder(CScript() << keys.pubkey1C << OP_CHECKSIG,
+ "P2PK with too little R padding but no STRICTENC", 0
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+ bad.push_back(TestBuilder(CScript() << keys.pubkey1C << OP_CHECKSIG,
+ "P2PK with too little R padding", SCRIPT_VERIFY_STRICTENC
+ ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
+
+ good.push_back(TestBuilder(CScript() << keys.pubkey2C << OP_CHECKSIG,
+ "P2PK with high S but no LOW_S", SCRIPT_VERIFY_STRICTENC
+ ).PushSig(keys.key2, SIGHASH_ALL, 32, 33));
+ good.push_back(TestBuilder(CScript() << keys.pubkey2C << OP_CHECKSIG,
+ "P2PK with high S but no STRICTENC", SCRIPT_VERIFY_LOW_S
+ ).PushSig(keys.key2, SIGHASH_ALL, 32, 33));
+ bad.push_back(TestBuilder(CScript() << keys.pubkey2C << OP_CHECKSIG,
+ "P2PK with high S", SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC
+ ).PushSig(keys.key2, SIGHASH_ALL, 32, 33));
+
+ good.push_back(TestBuilder(CScript() << OP_3 << keys.pubkey0C << keys.pubkey1C << keys.pubkey2C << OP_3 << OP_CHECKMULTISIG,
+ "3-of-3 with nonzero dummy but no NULLDUMMY", 0
+ ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
+ bad.push_back(TestBuilder(CScript() << OP_3 << keys.pubkey0C << keys.pubkey1C << keys.pubkey2C << OP_3 << OP_CHECKMULTISIG,
+ "3-of-3 with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY
+ ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
+
+ std::map<std::string, Array> tests_good;
+ std::map<std::string, Array> 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;
+ }
+ }
+ BOOST_FOREACH(Value& tv, json_bad) {
+ Array test = tv.get_array();
+ if (test.size() >= 4) {
+ tests_bad[test[3].get_str()] = test;
+ }
+ }
+ }
+
+ std::string strGood;
+ std::string strBad;
+
+ BOOST_FOREACH(TestBuilder& test, good) {
+ test.Test(true);
+ BOOST_CHECK_MESSAGE(tests_good.count(test.GetComment()) > 0, "Missing auto script_valid test: " + test.GetComment());
+ BOOST_CHECK_MESSAGE(ParseScript(tests_good[test.GetComment()][1].get_str()) == test.GetScriptPubKey(), "ScriptPubKey mismatch in auto script_valid test: " + test.GetComment());
+ strGood += test;
+ }
+ BOOST_FOREACH(TestBuilder& test, bad) {
+ test.Test(false);
+ BOOST_CHECK_MESSAGE(tests_bad.count(test.GetComment()) > 0, "Missing auto script_invalid test: " + test.GetComment());
+ BOOST_CHECK_MESSAGE(ParseScript(tests_bad[test.GetComment()][1].get_str()) == test.GetScriptPubKey(), "ScriptPubKey mismatch in auto script_invalid test: " + test.GetComment());
+ strBad += test;
+ }
+
+#if 0
+ FILE* valid = fopen("script_valid.json.gen", "w");
+ fputs(strGood.c_str(), valid);
+ fclose(valid);
+ FILE* invalid = fopen("script_invalid.json.gen", "w");
+ fputs(strBad.c_str(), invalid);
+ fclose(invalid);
+#endif
+}
+
BOOST_AUTO_TEST_CASE(script_valid)
{
// Read tests from test/data/script_valid.json
@@ -113,8 +424,7 @@ BOOST_AUTO_TEST_CASE(script_valid)
CScript scriptPubKey = ParseScript(scriptPubKeyString);
unsigned int scriptflags = ParseScriptFlags(test[2].get_str());
- CTransaction tx;
- BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, BuildSpendingTransaction(scriptSig, scriptPubKey), 0, scriptflags), strTest);
+ DoTest(scriptPubKey, scriptSig, scriptflags, true, strTest);
}
}
@@ -140,8 +450,7 @@ BOOST_AUTO_TEST_CASE(script_invalid)
CScript scriptPubKey = ParseScript(scriptPubKeyString);
unsigned int scriptflags = ParseScriptFlags(test[2].get_str());
- CTransaction tx;
- BOOST_CHECK_MESSAGE(!VerifyScript(scriptSig, scriptPubKey, BuildSpendingTransaction(scriptSig, scriptPubKey), 0, scriptflags), strTest);
+ DoTest(scriptPubKey, scriptSig, scriptflags, false, strTest);
}
}
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 41d8ee9f19..83116b51e5 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -17,6 +17,7 @@
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/test/unit_test.hpp>
+#include <boost/assign/list_of.hpp>
#include "json/json_spirit_writer_template.h"
using namespace std;
@@ -26,22 +27,23 @@ using namespace boost::algorithm;
// In script_tests.cpp
extern Array read_json(const std::string& jsondata);
-unsigned int ParseScriptFlags(string strFlags){
+// Note how NOCACHE is not included as it is a runtime-only flag.
+static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of
+ (string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE)
+ (string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH)
+ (string("STRICTENC"), (unsigned int)SCRIPT_VERIFY_STRICTENC)
+ (string("LOW_S"), (unsigned int)SCRIPT_VERIFY_LOW_S)
+ (string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY);
+
+unsigned int ParseScriptFlags(string strFlags)
+{
+ if (strFlags.empty()) {
+ return 0;
+ }
unsigned int flags = 0;
vector<string> words;
split(words, strFlags, is_any_of(","));
- // Note how NOCACHE is not included as it is a runtime-only flag.
- static map<string, unsigned int> mapFlagNames;
- if (mapFlagNames.size() == 0)
- {
- mapFlagNames["NONE"] = SCRIPT_VERIFY_NONE;
- mapFlagNames["P2SH"] = SCRIPT_VERIFY_P2SH;
- mapFlagNames["STRICTENC"] = SCRIPT_VERIFY_STRICTENC;
- mapFlagNames["LOW_S"] = SCRIPT_VERIFY_LOW_S;
- mapFlagNames["NULLDUMMY"] = SCRIPT_VERIFY_NULLDUMMY;
- }
-
BOOST_FOREACH(string word, words)
{
if (!mapFlagNames.count(word))
@@ -52,6 +54,22 @@ unsigned int ParseScriptFlags(string strFlags){
return flags;
}
+string FormatScriptFlags(unsigned int flags)
+{
+ if (flags == 0) {
+ return "";
+ }
+ string ret;
+ std::map<string, unsigned int>::const_iterator it = mapFlagNames.begin();
+ while (it != mapFlagNames.end()) {
+ if (flags & it->second) {
+ ret += it->first + ",";
+ }
+ it++;
+ }
+ return ret.substr(0, ret.size() - 1);
+}
+
BOOST_AUTO_TEST_SUITE(transaction_tests)
BOOST_AUTO_TEST_CASE(tx_valid)