aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml6
-rw-r--r--configure.ac2
-rw-r--r--contrib/debian/changelog6
-rw-r--r--contrib/debian/control1
-rwxr-xr-xcontrib/macdeploy/macdeployqtplus9
-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/native_comparisontool.mk39
-rw-r--r--depends/packages/openssl.mk2
-rw-r--r--depends/packages/qt.mk13
-rw-r--r--doc/build-unix.md2
-rw-r--r--doc/init.md8
-rw-r--r--doc/release-process.md15
-rw-r--r--src/Makefile.am2
-rw-r--r--src/chain.cpp59
-rw-r--r--src/chain.h390
-rw-r--r--src/compat/glibc_compat.cpp3
-rw-r--r--src/compat/glibc_sanity.cpp3
-rw-r--r--src/compat/glibcxx_compat.cpp2
-rw-r--r--src/compat/glibcxx_sanity.cpp2
-rw-r--r--src/compat/sanity.h2
-rw-r--r--src/core_io.h1
-rw-r--r--src/core_write.cpp35
-rw-r--r--src/crypto/common.h6
-rw-r--r--src/crypto/ripemd160.cpp2
-rw-r--r--src/crypto/ripemd160.h4
-rw-r--r--src/crypto/sha1.cpp2
-rw-r--r--src/crypto/sha1.h4
-rw-r--r--src/crypto/sha2.cpp2
-rw-r--r--src/crypto/sha2.h4
-rw-r--r--src/init.cpp2
-rw-r--r--src/key.cpp8
-rw-r--r--src/key.h2
-rw-r--r--src/main.cpp65
-rw-r--r--src/main.h385
-rw-r--r--src/script/interpreter.cpp3
-rw-r--r--src/serialize.h2
-rw-r--r--src/test/bctest.py15
-rw-r--r--src/test/bignum.h6
-rwxr-xr-xsrc/test/bitcoin-util-test.py3
-rw-r--r--src/test/buildenv.py.in2
-rw-r--r--src/test/data/bitcoin-util-test.json29
-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
56 files changed, 1086 insertions, 635 deletions
diff --git a/.travis.yml b/.travis.yml
index 54799362a2..f7d94df646 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"
@@ -58,6 +58,6 @@ script:
- cd bitcoin-$HOST
- ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
- make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false )
- - if [ "$RUN_TESTS" = "true" ]; then travis_retry make check; fi
+ - if [ "$RUN_TESTS" = "true" ]; then make check; fi
after_script:
- if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then (echo "Upload goes here. Something like: scp -r $BASE_OUTDIR server" || echo "upload failed"); fi
diff --git a/configure.ac b/configure.ac
index 0f9e78b74f..7025249aba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -793,7 +793,7 @@ AC_SUBST(BUILD_TEST)
AC_SUBST(BUILD_QT)
AC_SUBST(BUILD_TEST_QT)
AC_SUBST(MINIUPNPC_CPPFLAGS)
-AC_CONFIG_FILES([Makefile src/Makefile share/setup.nsi share/qt/Info.plist])
+AC_CONFIG_FILES([Makefile src/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py])
AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh])
AC_CONFIG_FILES([qa/pull-tester/build-tests.sh],[chmod +x qa/pull-tester/build-tests.sh])
AC_OUTPUT
diff --git a/contrib/debian/changelog b/contrib/debian/changelog
index 4f22567f85..fe910b65a5 100644
--- a/contrib/debian/changelog
+++ b/contrib/debian/changelog
@@ -1,3 +1,9 @@
+bitcoin (0.9.3-precise1) precise; urgency=medium
+
+ * New upstream releases.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Fri, 26 Sep 2014 12:01:00 -0700
+
bitcoin (0.9.1-precise1) precise; urgency=medium
* New upstream release.
diff --git a/contrib/debian/control b/contrib/debian/control
index ac635f43e0..a653260ad3 100644
--- a/contrib/debian/control
+++ b/contrib/debian/control
@@ -39,7 +39,6 @@ Description: peer-to-peer network based digital currency - daemon
Full transaction history is stored locally at each client. This
requires 20+ GB of space, slowly growing.
.
-
This package provides the daemon, bitcoind, and the CLI tool
bitcoin-cli to interact with the daemon.
diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus
index 5ab6a222dd..1b50981f0a 100755
--- a/contrib/macdeploy/macdeployqtplus
+++ b/contrib/macdeploy/macdeployqtplus
@@ -283,8 +283,8 @@ def copyFramework(framework, path, verbose):
if not framework.isDylib(): # Copy resources for real frameworks
- linkfrom = os.path.join(path, "Contents/Frameworks/", framework.frameworkName, framework.binaryName)
- linkto = os.path.join(framework.binaryPath)
+ linkfrom = os.path.join(path, "Contents","Frameworks", framework.frameworkName, "Versions", "Current")
+ linkto = framework.version
if not os.path.exists(linkfrom):
os.symlink(linkto, linkfrom)
if verbose >= 2:
@@ -303,11 +303,6 @@ def copyFramework(framework, path, verbose):
toContentsDir = os.path.join(path, framework.destinationVersionContentsDirectory)
shutil.copytree(fromContentsDir, toContentsDir)
contentslinkfrom = os.path.join(path, framework.destinationContentsDirectory)
- if not os.path.exists(contentslinkfrom):
- contentslinkto = os.path.join("Versions/", framework.version, "Contents")
- os.symlink(contentslinkto, contentslinkfrom)
- if verbose >= 3:
- print "Linked:", contentslinkfrom, "->", contentslinkto
if verbose >= 3:
print "Copied Contents:", fromContentsDir
print " to:", toContentsDir
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/native_comparisontool.mk b/depends/packages/native_comparisontool.mk
index 003923d7dd..d9f7722190 100644
--- a/depends/packages/native_comparisontool.mk
+++ b/depends/packages/native_comparisontool.mk
@@ -1,30 +1,12 @@
package=native_comparisontool
-$(package)_version=1
-$(package)_download_path=https://github.com/TheBlueMatt/test-scripts/raw/master/BitcoindComparisonTool_jar
-$(package)_file_name=BitcoindComparisonTool.jar
-$(package)_sha256_hash=a08b1a55523e7f57768cb66c35f47a926710e5b6c82822e1ccfbe38fcce37db2
-$(package)_guava_file_name=guava-13.0.1.jar
-$(package)_guava_sha256_hash=feb4b5b2e79a63b72ec47a693b1cf35cf1cea1f60a2bb2615bf21f74c7a60bb0
-$(package)_h2_file_name=h2-1.3.167.jar
-$(package)_h2_sha256_hash=fa97521a2e72174485a96276bcf6f573d5e44ca6aba2f62de87b33b5bb0d4b91
-$(package)_sc-light-jdk15on_file_name=sc-light-jdk15on-1.47.0.2.jar
-$(package)_sc-light-jdk15on_sha256_hash=931f39d351429fb96c2f749e7ecb1a256a8ebbf5edca7995c9cc085b94d1841d
-$(package)_slf4j-api_file_name=slf4j-api-1.6.4.jar
-$(package)_slf4j-api_sha256_hash=367b909030f714ee1176ab096b681e06348f03385e98d1bce0ed801b5452357e
-$(package)_slf4j-jdk14_file_name=slf4j-jdk14-1.6.4.jar
-$(package)_slf4j-jdk14_sha256_hash=064bd81796710f713f9f4a2309c0e032309934c2d2b4f7d3b6958325e584e13f
-
-define $(package)_fetch_cmds
-$(call fetch_file,$(package),$($(package)_download_path),$($(package)_file_name),$($(package)_file_name),$($(package)_sha256_hash)) && \
-$(call fetch_file,$(package),$($(package)_download_path),$($(package)_guava_file_name),$($(package)_guava_file_name),$($(package)_guava_sha256_hash)) && \
-$(call fetch_file,$(package),$($(package)_download_path),$($(package)_h2_file_name),$($(package)_h2_file_name),$($(package)_h2_sha256_hash)) && \
-$(call fetch_file,$(package),$($(package)_download_path),$($(package)_sc-light-jdk15on_file_name),$($(package)_sc-light-jdk15on_file_name),$($(package)_sc-light-jdk15on_sha256_hash)) && \
-$(call fetch_file,$(package),$($(package)_download_path),$($(package)_slf4j-api_file_name),$($(package)_slf4j-api_file_name),$($(package)_slf4j-api_sha256_hash)) && \
-$(call fetch_file,$(package),$($(package)_download_path),$($(package)_slf4j-jdk14_file_name),$($(package)_slf4j-jdk14_file_name),$($(package)_slf4j-jdk14_sha256_hash))
-endef
+$(package)_version=adfd3de7
+$(package)_download_path=https://github.com/TheBlueMatt/test-scripts/raw/10222bfdace65a0c5f3bd4a766eeb6b3a8b869fb/
+$(package)_file_name=pull-tests-$($(package)_version).jar
+$(package)_sha256_hash=fd2282b112e35f339dbe3729b08a04834ad719f8c9c10eeec1178465e6d36a18
+$(package)_install_dirname=BitcoindComparisonTool_jar
+$(package)_install_filename=BitcoindComparisonTool.jar
define $(package)_extract_cmds
-echo none
endef
define $(package)_configure_cmds
@@ -34,11 +16,6 @@ define $(package)_build_cmds
endef
define $(package)_stage_cmds
- mkdir -p $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar && \
- cp $(SOURCES_PATH)/$($(package)_file_name) $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar/ && \
- cp $(SOURCES_PATH)/$($(package)_guava_file_name) $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar/ && \
- cp $(SOURCES_PATH)/$($(package)_h2_file_name) $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar/ && \
- cp $(SOURCES_PATH)/$($(package)_sc-light-jdk15on_file_name) $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar/ && \
- cp $(SOURCES_PATH)/$($(package)_slf4j-api_file_name) $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar/ && \
- cp $(SOURCES_PATH)/$($(package)_slf4j-jdk14_file_name) $($(package)_staging_prefix_dir)/share/BitcoindComparisonTool_jar/
+ 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)
endef
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/build-unix.md b/doc/build-unix.md
index 8a76a8b2cd..0c3376df4b 100644
--- a/doc/build-unix.md
+++ b/doc/build-unix.md
@@ -63,7 +63,7 @@ Build requirements:
sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev
-for Ubuntu 12.04 and later:
+for Ubuntu 12.04 and later or Debian 7 and later libboost-all-dev has to be installed:
sudo apt-get install libboost-all-dev
diff --git a/doc/init.md b/doc/init.md
index 3d14025ab4..1f0559d806 100644
--- a/doc/init.md
+++ b/doc/init.md
@@ -4,10 +4,10 @@ Sample init scripts and service configuration for bitcoind
Sample scripts and configuration files for systemd, Upstart and OpenRC
can be found in the contrib/init folder.
-contrib/init/bitcoind.service: systemd service unit configuration
-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.service: systemd service unit configuration
+ 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
1. Service User
---------------------------------
diff --git a/doc/release-process.md b/doc/release-process.md
index 8934be66c4..940f934baf 100644
--- a/doc/release-process.md
+++ b/doc/release-process.md
@@ -178,16 +178,13 @@ Commit your signature to gitian.sigs:
Note: only Gavin has the code-signing keys currently.
-- Create `SHA256SUMS.asc` for builds, and PGP-sign it. This is done manually.
- Include all the files to be uploaded. The file has `sha256sum` format with a
- simple header at the top:
-
-```
-Hash: SHA256
-
-0060f7d38b98113ab912d4c184000291d7f026eaf77ca5830deec15059678f54 bitcoin-x.y.z-linux.tar.gz
-...
+- Create `SHA256SUMS.asc` for the builds, and GPG-sign it:
+```bash
+sha256sum * > SHA256SUMS
+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/Makefile.am b/src/Makefile.am
index 48e4fc5d8f..bd6f1ba0d5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -68,6 +68,7 @@ BITCOIN_CORE_H = \
amount.h \
base58.h \
bloom.h \
+ chain.h \
chainparams.h \
chainparamsbase.h \
chainparamsseeds.h \
@@ -146,6 +147,7 @@ libbitcoin_server_a_SOURCES = \
addrman.cpp \
alert.cpp \
bloom.cpp \
+ chain.cpp \
checkpoints.cpp \
init.cpp \
leveldbwrapper.cpp \
diff --git a/src/chain.cpp b/src/chain.cpp
new file mode 100644
index 0000000000..05427a4569
--- /dev/null
+++ b/src/chain.cpp
@@ -0,0 +1,59 @@
+// 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 "chain.h"
+
+using namespace std;
+
+// CChain implementation
+
+CBlockIndex *CChain::SetTip(CBlockIndex *pindex) {
+ if (pindex == NULL) {
+ vChain.clear();
+ return NULL;
+ }
+ vChain.resize(pindex->nHeight + 1);
+ while (pindex && vChain[pindex->nHeight] != pindex) {
+ vChain[pindex->nHeight] = pindex;
+ pindex = pindex->pprev;
+ }
+ return pindex;
+}
+
+CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
+ int nStep = 1;
+ std::vector<uint256> vHave;
+ vHave.reserve(32);
+
+ if (!pindex)
+ pindex = Tip();
+ while (pindex) {
+ vHave.push_back(pindex->GetBlockHash());
+ // Stop when we have added the genesis block.
+ if (pindex->nHeight == 0)
+ break;
+ // Exponentially larger steps back, plus the genesis block.
+ int nHeight = std::max(pindex->nHeight - nStep, 0);
+ if (Contains(pindex)) {
+ // Use O(1) CChain index if possible.
+ pindex = (*this)[nHeight];
+ } else {
+ // Otherwise, use O(log n) skiplist.
+ pindex = pindex->GetAncestor(nHeight);
+ }
+ if (vHave.size() > 10)
+ nStep *= 2;
+ }
+
+ return CBlockLocator(vHave);
+}
+
+const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {
+ if (pindex->nHeight > Height())
+ pindex = pindex->GetAncestor(Height());
+ while (pindex && !Contains(pindex))
+ pindex = pindex->pprev;
+ return pindex;
+}
diff --git a/src/chain.h b/src/chain.h
new file mode 100644
index 0000000000..0aafb40b98
--- /dev/null
+++ b/src/chain.h
@@ -0,0 +1,390 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef H_BITCOIN_CHAIN
+#define H_BITCOIN_CHAIN
+
+#include "core.h"
+#include "pow.h"
+#include "uint256.h"
+
+#include <vector>
+
+#include <boost/foreach.hpp>
+
+struct CDiskBlockPos
+{
+ int nFile;
+ unsigned int nPos;
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(VARINT(nFile));
+ READWRITE(VARINT(nPos));
+ }
+
+ CDiskBlockPos() {
+ SetNull();
+ }
+
+ CDiskBlockPos(int nFileIn, unsigned int nPosIn) {
+ nFile = nFileIn;
+ nPos = nPosIn;
+ }
+
+ friend bool operator==(const CDiskBlockPos &a, const CDiskBlockPos &b) {
+ return (a.nFile == b.nFile && a.nPos == b.nPos);
+ }
+
+ friend bool operator!=(const CDiskBlockPos &a, const CDiskBlockPos &b) {
+ return !(a == b);
+ }
+
+ void SetNull() { nFile = -1; nPos = 0; }
+ bool IsNull() const { return (nFile == -1); }
+};
+
+enum BlockStatus {
+ BLOCK_VALID_UNKNOWN = 0,
+ BLOCK_VALID_HEADER = 1, // parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future
+ BLOCK_VALID_TREE = 2, // parent found, difficulty matches, timestamp >= median previous, checkpoint
+ BLOCK_VALID_TRANSACTIONS = 3, // only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids, sigops, size, merkle root
+ BLOCK_VALID_CHAIN = 4, // outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30
+ BLOCK_VALID_SCRIPTS = 5, // scripts/signatures ok
+ BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS |
+ BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS,
+
+ BLOCK_HAVE_DATA = 8, // full block available in blk*.dat
+ BLOCK_HAVE_UNDO = 16, // undo data available in rev*.dat
+ BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO,
+
+ BLOCK_FAILED_VALID = 32, // stage after last reached validness failed
+ BLOCK_FAILED_CHILD = 64, // descends from failed block
+ BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD,
+};
+
+/** The block chain is a tree shaped structure starting with the
+ * genesis block at the root, with each block potentially having multiple
+ * candidates to be the next block. A blockindex may have multiple pprev pointing
+ * to it, but at most one of them can be part of the currently active branch.
+ */
+class CBlockIndex
+{
+public:
+ // 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
+ CBlockIndex* pprev;
+
+ // pointer to the index of some further predecessor of this block
+ CBlockIndex* pskip;
+
+ // height of the entry in the chain. The genesis block has height 0
+ int nHeight;
+
+ // Which # file this block is stored in (blk?????.dat)
+ int nFile;
+
+ // Byte offset within blk?????.dat where this block's data is stored
+ unsigned int nDataPos;
+
+ // Byte offset within rev?????.dat where this block's undo data is stored
+ unsigned int nUndoPos;
+
+ // (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
+ uint256 nChainWork;
+
+ // Number of transactions in this block.
+ // Note: in a potential headers-first mode, this number cannot be relied upon
+ unsigned int nTx;
+
+ // (memory only) Number of transactions in the chain up to and including this block
+ unsigned int nChainTx; // change to 64-bit type when necessary; won't happen before 2030
+
+ // Verification status of this block. See enum BlockStatus
+ unsigned int nStatus;
+
+ // block header
+ int nVersion;
+ uint256 hashMerkleRoot;
+ unsigned int nTime;
+ unsigned int nBits;
+ unsigned int nNonce;
+
+ // (memory only) Sequencial id assigned to distinguish order in which blocks are received.
+ uint32_t nSequenceId;
+
+ void SetNull()
+ {
+ phashBlock = NULL;
+ pprev = NULL;
+ pskip = NULL;
+ nHeight = 0;
+ nFile = 0;
+ nDataPos = 0;
+ nUndoPos = 0;
+ nChainWork = 0;
+ nTx = 0;
+ nChainTx = 0;
+ nStatus = 0;
+ nSequenceId = 0;
+
+ nVersion = 0;
+ hashMerkleRoot = 0;
+ nTime = 0;
+ nBits = 0;
+ nNonce = 0;
+ }
+
+ CBlockIndex()
+ {
+ SetNull();
+ }
+
+ CBlockIndex(CBlockHeader& block)
+ {
+ SetNull();
+
+ nVersion = block.nVersion;
+ hashMerkleRoot = block.hashMerkleRoot;
+ nTime = block.nTime;
+ nBits = block.nBits;
+ nNonce = block.nNonce;
+ }
+
+ CDiskBlockPos GetBlockPos() const {
+ CDiskBlockPos ret;
+ if (nStatus & BLOCK_HAVE_DATA) {
+ ret.nFile = nFile;
+ ret.nPos = nDataPos;
+ }
+ return ret;
+ }
+
+ CDiskBlockPos GetUndoPos() const {
+ CDiskBlockPos ret;
+ if (nStatus & BLOCK_HAVE_UNDO) {
+ ret.nFile = nFile;
+ ret.nPos = nUndoPos;
+ }
+ return ret;
+ }
+
+ CBlockHeader GetBlockHeader() const
+ {
+ CBlockHeader block;
+ block.nVersion = nVersion;
+ if (pprev)
+ block.hashPrevBlock = pprev->GetBlockHash();
+ block.hashMerkleRoot = hashMerkleRoot;
+ block.nTime = nTime;
+ block.nBits = nBits;
+ block.nNonce = nNonce;
+ return block;
+ }
+
+ uint256 GetBlockHash() const
+ {
+ return *phashBlock;
+ }
+
+ int64_t GetBlockTime() const
+ {
+ return (int64_t)nTime;
+ }
+
+ uint256 GetBlockWork() const
+ {
+ return GetProofIncrement(nBits);
+ }
+
+ enum { nMedianTimeSpan=11 };
+
+ int64_t GetMedianTimePast() const
+ {
+ int64_t pmedian[nMedianTimeSpan];
+ int64_t* pbegin = &pmedian[nMedianTimeSpan];
+ int64_t* pend = &pmedian[nMedianTimeSpan];
+
+ const CBlockIndex* pindex = this;
+ for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
+ *(--pbegin) = pindex->GetBlockTime();
+
+ std::sort(pbegin, pend);
+ 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)",
+ pprev, nHeight,
+ hashMerkleRoot.ToString(),
+ GetBlockHash().ToString());
+ }
+
+ // Check whether this block index entry is valid up to the passed validity level.
+ bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const
+ {
+ assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
+ if (nStatus & BLOCK_FAILED_MASK)
+ return false;
+ return ((nStatus & BLOCK_VALID_MASK) >= nUpTo);
+ }
+
+ // Raise the validity level of this block index entry.
+ // Returns true if the validity was changed.
+ bool RaiseValidity(enum BlockStatus nUpTo)
+ {
+ assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
+ if (nStatus & BLOCK_FAILED_MASK)
+ return false;
+ if ((nStatus & BLOCK_VALID_MASK) < nUpTo) {
+ nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo;
+ return true;
+ }
+ return false;
+ }
+
+ // Build the skiplist pointer for this entry.
+ void BuildSkip();
+
+ // Efficiently find an ancestor of this block.
+ CBlockIndex* GetAncestor(int height);
+ const CBlockIndex* GetAncestor(int height) const;
+};
+
+/** Used to marshal pointers into hashes for db storage. */
+class CDiskBlockIndex : public CBlockIndex
+{
+public:
+ uint256 hashPrev;
+
+ CDiskBlockIndex() {
+ hashPrev = 0;
+ }
+
+ explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) {
+ hashPrev = (pprev ? pprev->GetBlockHash() : 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(VARINT(nVersion));
+
+ READWRITE(VARINT(nHeight));
+ READWRITE(VARINT(nStatus));
+ READWRITE(VARINT(nTx));
+ if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO))
+ READWRITE(VARINT(nFile));
+ if (nStatus & BLOCK_HAVE_DATA)
+ READWRITE(VARINT(nDataPos));
+ if (nStatus & BLOCK_HAVE_UNDO)
+ READWRITE(VARINT(nUndoPos));
+
+ // block header
+ READWRITE(this->nVersion);
+ READWRITE(hashPrev);
+ READWRITE(hashMerkleRoot);
+ READWRITE(nTime);
+ READWRITE(nBits);
+ READWRITE(nNonce);
+ }
+
+ uint256 GetBlockHash() const
+ {
+ CBlockHeader block;
+ block.nVersion = nVersion;
+ block.hashPrevBlock = hashPrev;
+ block.hashMerkleRoot = hashMerkleRoot;
+ block.nTime = nTime;
+ block.nBits = nBits;
+ block.nNonce = nNonce;
+ return block.GetHash();
+ }
+
+
+ std::string ToString() const
+ {
+ std::string str = "CDiskBlockIndex(";
+ str += CBlockIndex::ToString();
+ str += strprintf("\n hashBlock=%s, hashPrev=%s)",
+ GetBlockHash().ToString(),
+ hashPrev.ToString());
+ return str;
+ }
+};
+
+/** An in-memory indexed chain of blocks. */
+class CChain {
+private:
+ std::vector<CBlockIndex*> vChain;
+
+public:
+ /** Returns the index entry for the genesis block of this chain, or NULL if none. */
+ CBlockIndex *Genesis() const {
+ return vChain.size() > 0 ? vChain[0] : NULL;
+ }
+
+ /** Returns the index entry for the tip of this chain, or NULL if none. */
+ CBlockIndex *Tip() const {
+ return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL;
+ }
+
+ /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */
+ CBlockIndex *operator[](int nHeight) const {
+ if (nHeight < 0 || nHeight >= (int)vChain.size())
+ return NULL;
+ return vChain[nHeight];
+ }
+
+ /** Compare two chains efficiently. */
+ friend bool operator==(const CChain &a, const CChain &b) {
+ return a.vChain.size() == b.vChain.size() &&
+ a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1];
+ }
+
+ /** Efficiently check whether a block is present in this chain. */
+ bool Contains(const CBlockIndex *pindex) const {
+ return (*this)[pindex->nHeight] == pindex;
+ }
+
+ /** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */
+ CBlockIndex *Next(const CBlockIndex *pindex) const {
+ if (Contains(pindex))
+ return (*this)[pindex->nHeight + 1];
+ else
+ return NULL;
+ }
+
+ /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */
+ int Height() const {
+ return vChain.size() - 1;
+ }
+
+ /** Set/initialize a chain with a given tip. Returns the forking point. */
+ CBlockIndex *SetTip(CBlockIndex *pindex);
+
+ /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */
+ CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const;
+
+ /** Find the last common block between this chain and a block index entry. */
+ const CBlockIndex *FindFork(const CBlockIndex *pindex) const;
+};
+
+#endif // H_BITCOIN_CHAIN
diff --git a/src/compat/glibc_compat.cpp b/src/compat/glibc_compat.cpp
index 94c79e4b97..f149a08cd5 100644
--- a/src/compat/glibc_compat.cpp
+++ b/src/compat/glibc_compat.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
@@ -7,6 +7,7 @@
#endif
#include <cstddef>
+
#if defined(HAVE_SYS_SELECT_H)
#include <sys/select.h>
#endif
diff --git a/src/compat/glibc_sanity.cpp b/src/compat/glibc_sanity.cpp
index acc7809d77..607e23b568 100644
--- a/src/compat/glibc_sanity.cpp
+++ b/src/compat/glibc_sanity.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
@@ -7,6 +7,7 @@
#endif
#include <cstddef>
+
#if defined(HAVE_SYS_SELECT_H)
#include <sys/select.h>
#endif
diff --git a/src/compat/glibcxx_compat.cpp b/src/compat/glibcxx_compat.cpp
index 41d8458cb2..e0b4ac51f5 100644
--- a/src/compat/glibcxx_compat.cpp
+++ b/src/compat/glibcxx_compat.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <cstddef>
diff --git a/src/compat/glibcxx_sanity.cpp b/src/compat/glibcxx_sanity.cpp
index 9b1fefd448..aafa4a6aef 100644
--- a/src/compat/glibcxx_sanity.cpp
+++ b/src/compat/glibcxx_sanity.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <list>
diff --git a/src/compat/sanity.h b/src/compat/sanity.h
index e7df44307a..7016ac0ab7 100644
--- a/src/compat/sanity.h
+++ b/src/compat/sanity.h
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCON_COMPAT_SANITY_H
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/crypto/common.h b/src/crypto/common.h
index 7c3d0a135b..67c30023c3 100644
--- a/src/crypto/common.h
+++ b/src/crypto/common.h
@@ -1,5 +1,5 @@
// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_CRYPTO_COMMON_H
@@ -8,7 +8,9 @@
#if defined(HAVE_CONFIG_H)
#include "bitcoin-config.h"
#endif
+
#include <stdint.h>
+
#if defined(HAVE_ENDIAN_H)
#include <endian.h>
#endif
@@ -115,4 +117,4 @@ void static inline WriteBE64(unsigned char* ptr, uint64_t x)
#endif
}
-#endif
+#endif // BITCOIN_CRYPTO_COMMON_H
diff --git a/src/crypto/ripemd160.cpp b/src/crypto/ripemd160.cpp
index 90b196ba32..cb4a94a44d 100644
--- a/src/crypto/ripemd160.cpp
+++ b/src/crypto/ripemd160.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "crypto/ripemd160.h"
diff --git a/src/crypto/ripemd160.h b/src/crypto/ripemd160.h
index 76197543be..902e7ca83f 100644
--- a/src/crypto/ripemd160.h
+++ b/src/crypto/ripemd160.h
@@ -1,5 +1,5 @@
// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_RIPEMD160_H
@@ -25,4 +25,4 @@ public:
CRIPEMD160& Reset();
};
-#endif
+#endif // BITCOIN_RIPEMD160_H
diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp
index 5fbea002d6..7f78fdfc6d 100644
--- a/src/crypto/sha1.cpp
+++ b/src/crypto/sha1.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "crypto/sha1.h"
diff --git a/src/crypto/sha1.h b/src/crypto/sha1.h
index 4fa2b333ba..68bd7ced9f 100644
--- a/src/crypto/sha1.h
+++ b/src/crypto/sha1.h
@@ -1,5 +1,5 @@
// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SHA1_H
@@ -25,4 +25,4 @@ public:
CSHA1& Reset();
};
-#endif
+#endif // BITCOIN_SHA1_H
diff --git a/src/crypto/sha2.cpp b/src/crypto/sha2.cpp
index 9a96c5125a..613aac2d71 100644
--- a/src/crypto/sha2.cpp
+++ b/src/crypto/sha2.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "crypto/sha2.h"
diff --git a/src/crypto/sha2.h b/src/crypto/sha2.h
index 15ad5ac383..a6cbe58554 100644
--- a/src/crypto/sha2.h
+++ b/src/crypto/sha2.h
@@ -1,5 +1,5 @@
// Copyright (c) 2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SHA2_H
@@ -61,4 +61,4 @@ public:
void Finalize(unsigned char hash[OUTPUT_SIZE]);
};
-#endif
+#endif // BITCOIN_SHA2_H
diff --git a/src/init.cpp b/src/init.cpp
index dfb984cb0d..503df7ad3f 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1159,7 +1159,7 @@ bool AppInit2(boost::thread_group& threadGroup)
CWalletDB walletdb(strWalletFile);
CBlockLocator locator;
if (walletdb.ReadBestBlock(locator))
- pindexRescan = chainActive.FindFork(locator);
+ pindexRescan = FindForkInGlobalIndex(chainActive, locator);
else
pindexRescan = chainActive.Genesis();
}
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/main.cpp b/src/main.cpp
index 234b343983..5a5c700574 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -391,72 +391,19 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals)
nodeSignals.FinalizeNode.disconnect(&FinalizeNode);
}
-//////////////////////////////////////////////////////////////////////////////
-//
-// CChain implementation
-//
-
-CBlockIndex *CChain::SetTip(CBlockIndex *pindex) {
- if (pindex == NULL) {
- vChain.clear();
- return NULL;
- }
- vChain.resize(pindex->nHeight + 1);
- while (pindex && vChain[pindex->nHeight] != pindex) {
- vChain[pindex->nHeight] = pindex;
- pindex = pindex->pprev;
- }
- return pindex;
-}
-
-CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
- int nStep = 1;
- std::vector<uint256> vHave;
- vHave.reserve(32);
-
- if (!pindex)
- pindex = Tip();
- while (pindex) {
- vHave.push_back(pindex->GetBlockHash());
- // Stop when we have added the genesis block.
- if (pindex->nHeight == 0)
- break;
- // Exponentially larger steps back, plus the genesis block.
- int nHeight = std::max(pindex->nHeight - nStep, 0);
- if (Contains(pindex)) {
- // Use O(1) CChain index if possible.
- pindex = (*this)[nHeight];
- } else {
- // Otherwise, use O(log n) skiplist.
- pindex = pindex->GetAncestor(nHeight);
- }
- if (vHave.size() > 10)
- nStep *= 2;
- }
-
- return CBlockLocator(vHave);
-}
-
-CBlockIndex *CChain::FindFork(const CBlockLocator &locator) const {
+CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator)
+{
// Find the first block the caller has in the main chain
BOOST_FOREACH(const uint256& hash, locator.vHave) {
BlockMap::iterator mi = mapBlockIndex.find(hash);
if (mi != mapBlockIndex.end())
{
CBlockIndex* pindex = (*mi).second;
- if (Contains(pindex))
+ if (chain.Contains(pindex))
return pindex;
}
}
- return Genesis();
-}
-
-const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {
- if (pindex->nHeight > Height())
- pindex = pindex->GetAncestor(Height());
- while (pindex && !Contains(pindex))
- pindex = pindex->pprev;
- return pindex;
+ return chain.Genesis();
}
CCoinsViewCache *pcoinsTip = NULL;
@@ -3709,7 +3656,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
LOCK(cs_main);
// Find the last block the caller has in the main chain
- CBlockIndex* pindex = chainActive.FindFork(locator);
+ CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
// Send the rest of the chain
if (pindex)
@@ -3756,7 +3703,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
else
{
// Find the last block the caller has in the main chain
- pindex = chainActive.FindFork(locator);
+ pindex = FindForkInGlobalIndex(chainActive, locator);
if (pindex)
pindex = chainActive.Next(pindex);
}
diff --git a/src/main.h b/src/main.h
index 93915db519..7e849505dd 100644
--- a/src/main.h
+++ b/src/main.h
@@ -10,6 +10,7 @@
#include "config/bitcoin-config.h"
#endif
+#include "chain.h"
#include "chainparams.h"
#include "coins.h"
#include "core.h"
@@ -113,7 +114,6 @@ static const uint64_t nMinDiskSpace = 52428800;
class CBlockTreeDB;
-struct CDiskBlockPos;
class CTxUndo;
class CScriptCheck;
class CValidationState;
@@ -189,51 +189,11 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
bool* pfMissingInputs, bool fRejectInsaneFee=false);
-
-
-
-
-
-
struct CNodeStateStats {
int nMisbehavior;
int nSyncHeight;
};
-struct CDiskBlockPos
-{
- int nFile;
- unsigned int nPos;
-
- ADD_SERIALIZE_METHODS;
-
- template <typename Stream, typename Operation>
- inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(VARINT(nFile));
- READWRITE(VARINT(nPos));
- }
-
- CDiskBlockPos() {
- SetNull();
- }
-
- CDiskBlockPos(int nFileIn, unsigned int nPosIn) {
- nFile = nFileIn;
- nPos = nPosIn;
- }
-
- friend bool operator==(const CDiskBlockPos &a, const CDiskBlockPos &b) {
- return (a.nFile == b.nFile && a.nPos == b.nPos);
- }
-
- friend bool operator!=(const CDiskBlockPos &a, const CDiskBlockPos &b) {
- return !(a == b);
- }
-
- void SetNull() { nFile = -1; nPos = 0; }
- bool IsNull() const { return (nFile == -1); }
-};
-
struct CDiskTxPos : public CDiskBlockPos
{
unsigned int nTxOffset; // after header
@@ -545,288 +505,6 @@ public:
}
};
-enum BlockStatus {
- BLOCK_VALID_UNKNOWN = 0,
- BLOCK_VALID_HEADER = 1, // parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future
- BLOCK_VALID_TREE = 2, // parent found, difficulty matches, timestamp >= median previous, checkpoint
- BLOCK_VALID_TRANSACTIONS = 3, // only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids, sigops, size, merkle root
- BLOCK_VALID_CHAIN = 4, // outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30
- BLOCK_VALID_SCRIPTS = 5, // scripts/signatures ok
- BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS |
- BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS,
-
- BLOCK_HAVE_DATA = 8, // full block available in blk*.dat
- BLOCK_HAVE_UNDO = 16, // undo data available in rev*.dat
- BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO,
-
- BLOCK_FAILED_VALID = 32, // stage after last reached validness failed
- BLOCK_FAILED_CHILD = 64, // descends from failed block
- BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD,
-};
-
-/** The block chain is a tree shaped structure starting with the
- * genesis block at the root, with each block potentially having multiple
- * candidates to be the next block. A blockindex may have multiple pprev pointing
- * to it, but at most one of them can be part of the currently active branch.
- */
-class CBlockIndex
-{
-public:
- // 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
- CBlockIndex* pprev;
-
- // pointer to the index of some further predecessor of this block
- CBlockIndex* pskip;
-
- // height of the entry in the chain. The genesis block has height 0
- int nHeight;
-
- // Which # file this block is stored in (blk?????.dat)
- int nFile;
-
- // Byte offset within blk?????.dat where this block's data is stored
- unsigned int nDataPos;
-
- // Byte offset within rev?????.dat where this block's undo data is stored
- unsigned int nUndoPos;
-
- // (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
- uint256 nChainWork;
-
- // Number of transactions in this block.
- // Note: in a potential headers-first mode, this number cannot be relied upon
- unsigned int nTx;
-
- // (memory only) Number of transactions in the chain up to and including this block
- unsigned int nChainTx; // change to 64-bit type when necessary; won't happen before 2030
-
- // Verification status of this block. See enum BlockStatus
- unsigned int nStatus;
-
- // block header
- int nVersion;
- uint256 hashMerkleRoot;
- unsigned int nTime;
- unsigned int nBits;
- unsigned int nNonce;
-
- // (memory only) Sequencial id assigned to distinguish order in which blocks are received.
- uint32_t nSequenceId;
-
- void SetNull()
- {
- phashBlock = NULL;
- pprev = NULL;
- pskip = NULL;
- nHeight = 0;
- nFile = 0;
- nDataPos = 0;
- nUndoPos = 0;
- nChainWork = 0;
- nTx = 0;
- nChainTx = 0;
- nStatus = 0;
- nSequenceId = 0;
-
- nVersion = 0;
- hashMerkleRoot = 0;
- nTime = 0;
- nBits = 0;
- nNonce = 0;
- }
-
- CBlockIndex()
- {
- SetNull();
- }
-
- CBlockIndex(CBlockHeader& block)
- {
- SetNull();
-
- nVersion = block.nVersion;
- hashMerkleRoot = block.hashMerkleRoot;
- nTime = block.nTime;
- nBits = block.nBits;
- nNonce = block.nNonce;
- }
-
- CDiskBlockPos GetBlockPos() const {
- CDiskBlockPos ret;
- if (nStatus & BLOCK_HAVE_DATA) {
- ret.nFile = nFile;
- ret.nPos = nDataPos;
- }
- return ret;
- }
-
- CDiskBlockPos GetUndoPos() const {
- CDiskBlockPos ret;
- if (nStatus & BLOCK_HAVE_UNDO) {
- ret.nFile = nFile;
- ret.nPos = nUndoPos;
- }
- return ret;
- }
-
- CBlockHeader GetBlockHeader() const
- {
- CBlockHeader block;
- block.nVersion = nVersion;
- if (pprev)
- block.hashPrevBlock = pprev->GetBlockHash();
- block.hashMerkleRoot = hashMerkleRoot;
- block.nTime = nTime;
- block.nBits = nBits;
- block.nNonce = nNonce;
- return block;
- }
-
- uint256 GetBlockHash() const
- {
- return *phashBlock;
- }
-
- int64_t GetBlockTime() const
- {
- return (int64_t)nTime;
- }
-
- uint256 GetBlockWork() const
- {
- return GetProofIncrement(nBits);
- }
-
- enum { nMedianTimeSpan=11 };
-
- int64_t GetMedianTimePast() const
- {
- int64_t pmedian[nMedianTimeSpan];
- int64_t* pbegin = &pmedian[nMedianTimeSpan];
- int64_t* pend = &pmedian[nMedianTimeSpan];
-
- const CBlockIndex* pindex = this;
- for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
- *(--pbegin) = pindex->GetBlockTime();
-
- std::sort(pbegin, pend);
- 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)",
- pprev, nHeight,
- hashMerkleRoot.ToString(),
- GetBlockHash().ToString());
- }
-
- // Check whether this block index entry is valid up to the passed validity level.
- bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const
- {
- assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
- if (nStatus & BLOCK_FAILED_MASK)
- return false;
- return ((nStatus & BLOCK_VALID_MASK) >= nUpTo);
- }
-
- // Raise the validity level of this block index entry.
- // Returns true if the validity was changed.
- bool RaiseValidity(enum BlockStatus nUpTo)
- {
- assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
- if (nStatus & BLOCK_FAILED_MASK)
- return false;
- if ((nStatus & BLOCK_VALID_MASK) < nUpTo) {
- nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo;
- return true;
- }
- return false;
- }
-
- // Build the skiplist pointer for this entry.
- void BuildSkip();
-
- // Efficiently find an ancestor of this block.
- CBlockIndex* GetAncestor(int height);
- const CBlockIndex* GetAncestor(int height) const;
-};
-
-/** Used to marshal pointers into hashes for db storage. */
-class CDiskBlockIndex : public CBlockIndex
-{
-public:
- uint256 hashPrev;
-
- CDiskBlockIndex() {
- hashPrev = 0;
- }
-
- explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) {
- hashPrev = (pprev ? pprev->GetBlockHash() : 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(VARINT(nVersion));
-
- READWRITE(VARINT(nHeight));
- READWRITE(VARINT(nStatus));
- READWRITE(VARINT(nTx));
- if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO))
- READWRITE(VARINT(nFile));
- if (nStatus & BLOCK_HAVE_DATA)
- READWRITE(VARINT(nDataPos));
- if (nStatus & BLOCK_HAVE_UNDO)
- READWRITE(VARINT(nUndoPos));
-
- // block header
- READWRITE(this->nVersion);
- READWRITE(hashPrev);
- READWRITE(hashMerkleRoot);
- READWRITE(nTime);
- READWRITE(nBits);
- READWRITE(nNonce);
- }
-
- uint256 GetBlockHash() const
- {
- CBlockHeader block;
- block.nVersion = nVersion;
- block.hashPrevBlock = hashPrev;
- block.hashMerkleRoot = hashMerkleRoot;
- block.nTime = nTime;
- block.nBits = nBits;
- block.nNonce = nNonce;
- return block.GetHash();
- }
-
-
- std::string ToString() const
- {
- std::string str = "CDiskBlockIndex(";
- str += CBlockIndex::ToString();
- str += strprintf("\n hashBlock=%s, hashPrev=%s)",
- GetBlockHash().ToString(),
- hashPrev.ToString());
- return str;
- }
-};
-
/** Capture information about block/transaction validation */
class CValidationState {
private:
@@ -898,65 +576,8 @@ public:
bool VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth);
};
-/** An in-memory indexed chain of blocks. */
-class CChain {
-private:
- std::vector<CBlockIndex*> vChain;
-
-public:
- /** Returns the index entry for the genesis block of this chain, or NULL if none. */
- CBlockIndex *Genesis() const {
- return vChain.size() > 0 ? vChain[0] : NULL;
- }
-
- /** Returns the index entry for the tip of this chain, or NULL if none. */
- CBlockIndex *Tip() const {
- return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL;
- }
-
- /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */
- CBlockIndex *operator[](int nHeight) const {
- if (nHeight < 0 || nHeight >= (int)vChain.size())
- return NULL;
- return vChain[nHeight];
- }
-
- /** Compare two chains efficiently. */
- friend bool operator==(const CChain &a, const CChain &b) {
- return a.vChain.size() == b.vChain.size() &&
- a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1];
- }
-
- /** Efficiently check whether a block is present in this chain. */
- bool Contains(const CBlockIndex *pindex) const {
- return (*this)[pindex->nHeight] == pindex;
- }
-
- /** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */
- CBlockIndex *Next(const CBlockIndex *pindex) const {
- if (Contains(pindex))
- return (*this)[pindex->nHeight + 1];
- else
- return NULL;
- }
-
- /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */
- int Height() const {
- return vChain.size() - 1;
- }
-
- /** Set/initialize a chain with a given tip. Returns the forking point. */
- CBlockIndex *SetTip(CBlockIndex *pindex);
-
- /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */
- CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const;
-
- /** Find the last common block between this chain and a locator. */
- CBlockIndex *FindFork(const CBlockLocator &locator) const;
-
- /** Find the last common block between this chain and a block index entry. */
- const CBlockIndex *FindFork(const CBlockIndex *pindex) const;
-};
+/** Find the last common block between the parameter chain and a locator. */
+CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator);
/** The currently-connected chain of blocks. */
extern CChain chainActive;
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/bctest.py b/src/test/bctest.py
index 1839f4fef4..ef461014ea 100644
--- a/src/test/bctest.py
+++ b/src/test/bctest.py
@@ -7,9 +7,11 @@ import os
import json
import sys
-def bctest(testDir, testObj):
- execargs = testObj['exec']
+def bctest(testDir, testObj, exeext):
+ execprog = testObj['exec'] + exeext
+ execargs = testObj['args']
+ execrun = [execprog] + execargs
stdinCfg = None
inputData = None
if "input" in testObj:
@@ -22,12 +24,11 @@ def bctest(testDir, testObj):
if "output_cmp" in testObj:
outputFn = testObj['output_cmp']
outputData = open(testDir + "/" + outputFn).read()
-
- proc = subprocess.Popen(execargs, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ proc = subprocess.Popen(execrun, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True)
try:
outs = proc.communicate(input=inputData)
except OSError:
- print("OSError, Failed to execute " + execargs[0])
+ print("OSError, Failed to execute " + execprog)
sys.exit(1)
if outputData and (outs[0] != outputData):
@@ -41,13 +42,13 @@ def bctest(testDir, testObj):
print("Return code mismatch for " + outputFn)
sys.exit(1)
-def bctester(testDir, input_basename):
+def bctester(testDir, input_basename, buildenv):
input_filename = testDir + "/" + input_basename
raw_data = open(input_filename).read()
input_data = json.loads(raw_data)
for testObj in input_data:
- bctest(testDir, testObj)
+ bctest(testDir, testObj, buildenv.exeext)
sys.exit(0)
diff --git a/src/test/bignum.h b/src/test/bignum.h
index a75f5250fa..86980b2af6 100644
--- a/src/test/bignum.h
+++ b/src/test/bignum.h
@@ -63,11 +63,11 @@ public:
int getint() const
{
- unsigned long n = BN_get_word(this);
+ BN_ULONG n = BN_get_word(this);
if (!BN_is_negative(this))
- return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
+ return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
else
- return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
+ return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
}
void setint64(int64_t sn)
diff --git a/src/test/bitcoin-util-test.py b/src/test/bitcoin-util-test.py
index 40690c2fed..0eece14cfe 100755
--- a/src/test/bitcoin-util-test.py
+++ b/src/test/bitcoin-util-test.py
@@ -5,8 +5,9 @@
import os
import bctest
+import buildenv
if __name__ == '__main__':
bctest.bctester(os.environ["srcdir"] + "/test/data",
- "bitcoin-util-test.json")
+ "bitcoin-util-test.json",buildenv)
diff --git a/src/test/buildenv.py.in b/src/test/buildenv.py.in
new file mode 100644
index 0000000000..1618bdeb76
--- /dev/null
+++ b/src/test/buildenv.py.in
@@ -0,0 +1,2 @@
+#!/usr/bin/python
+exeext="@EXEEXT@"
diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json
index cb74d73ef2..f8424b72a3 100644
--- a/src/test/data/bitcoin-util-test.json
+++ b/src/test/data/bitcoin-util-test.json
@@ -1,33 +1,41 @@
[
- { "exec": ["./bitcoin-tx", "-create"],
+ { "exec": "././bitcoin-tx",
+ "args": ["-create"],
"output_cmp": "blanktx.hex"
},
- { "exec": ["./bitcoin-tx", "-"],
+ { "exec": "./bitcoin-tx",
+ "args": ["-"],
"input": "blanktx.hex",
"output_cmp": "blanktx.hex"
},
- { "exec": ["./bitcoin-tx", "-", "delin=1"],
+ { "exec": "./bitcoin-tx",
+ "args": ["-", "delin=1"],
"input": "tx394b54bb.hex",
"output_cmp": "tt-delin1-out.hex"
},
- { "exec": ["./bitcoin-tx", "-", "delin=31"],
+ { "exec": "./bitcoin-tx",
+ "args": ["-", "delin=31"],
"input": "tx394b54bb.hex",
"return_code": 1
},
- { "exec": ["./bitcoin-tx", "-", "delout=1"],
+ { "exec": "./bitcoin-tx",
+ "args": ["-", "delout=1"],
"input": "tx394b54bb.hex",
"output_cmp": "tt-delout1-out.hex"
},
- { "exec": ["./bitcoin-tx", "-", "delout=2"],
+ { "exec": "./bitcoin-tx",
+ "args": ["-", "delout=2"],
"input": "tx394b54bb.hex",
"return_code": 1
},
- { "exec": ["./bitcoin-tx", "-", "locktime=317000"],
+ { "exec": "./bitcoin-tx",
+ "args": ["-", "locktime=317000"],
"input": "tx394b54bb.hex",
"output_cmp": "tt-locktime317000-out.hex"
},
- { "exec":
- ["./bitcoin-tx", "-create",
+ { "exec": "./bitcoin-tx",
+ "args":
+ ["-create",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
"in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18",
"in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1",
@@ -35,7 +43,8 @@
"outaddr=4:1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"],
"output_cmp": "txcreate1.hex"
},
- { "exec": ["./bitcoin-tx", "-create", "outscript=0:"],
+ { "exec": "./bitcoin-tx",
+ "args": ["-create", "outscript=0:"],
"output_cmp": "txcreate2.hex"
}
]
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)