aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--contrib/debian/changelog6
-rw-r--r--contrib/debian/control1
-rw-r--r--depends/Makefile14
-rw-r--r--depends/README.packages12
-rw-r--r--depends/README.usage1
-rw-r--r--depends/config.site.in13
-rw-r--r--depends/funcs.mk71
-rw-r--r--depends/hosts/darwin.mk10
-rw-r--r--depends/hosts/default.mk5
-rw-r--r--depends/hosts/linux.mk10
-rw-r--r--depends/hosts/mingw32.mk10
-rw-r--r--depends/packages/boost.mk6
-rw-r--r--depends/packages/miniupnpc.mk2
-rw-r--r--depends/packages/openssl.mk2
-rw-r--r--depends/packages/qt.mk13
-rw-r--r--doc/release-process.md15
-rw-r--r--src/Makefile.am2
-rw-r--r--src/chain.cpp59
-rw-r--r--src/chain.h390
-rw-r--r--src/init.cpp2
-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/getarg_tests.cpp3
26 files changed, 602 insertions, 504 deletions
diff --git a/.travis.yml b/.travis.yml
index 54799362a2..155ac012d8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -27,9 +27,9 @@ matrix:
- compiler: "true 1"
env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
- compiler: "true 2"
- env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_QT=1 NO_WALLET=1 NO_UPNP=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat CPPFLAGS=-DDEBUG_LOCKORDER"
+ env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat CPPFLAGS=-DDEBUG_LOCKORDER"
- compiler: "true 3"
- env: HOST=x86_64-unknown-linux-gnu RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
+ env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
- compiler: "true 4"
env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
- compiler: "true 5"
diff --git a/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/depends/Makefile b/depends/Makefile
index f5fb5b865f..fc763bedeb 100644
--- a/depends/Makefile
+++ b/depends/Makefile
@@ -22,6 +22,12 @@ host:=$(HOST)
host_toolchain:=$(HOST)-
endif
+ifneq ($(DEBUG),)
+release_type=debug
+else
+release_type=release
+endif
+
base_build_dir=$(BASEDIR)/work/build
base_staging_dir=$(BASEDIR)/work/staging
canonical_host:=$(shell ./config.sub $(HOST))
@@ -103,12 +109,14 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_
-e 's|@STRIP@|$(toolchain_path)$(host_STRIP)|' \
-e 's|@build_os@|$(build_os)|' \
-e 's|@host_os@|$(host_os)|' \
- -e 's|@CFLAGS@|$(host_CFLAGS)|' \
- -e 's|@CXXFLAGS@|$(host_CXXFLAGS)|' \
- -e 's|@LDFLAGS@|$(host_LDFLAGS)|' \
+ -e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \
+ -e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS) $(host_$(release_type)_CXXFLAGS))|' \
+ -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \
+ -e 's|@LDFLAGS@|$(strip $(host_LDFLAGS) $(host_$(release_type)_LDFLAGS))|' \
-e 's|@no_qt@|$(NO_QT)|' \
-e 's|@no_wallet@|$(NO_WALLET)|' \
-e 's|@no_upnp@|$(NO_UPNP)|' \
+ -e 's|@debug@|$(DEBUG)|' \
$< > $@
$(AT)touch $@
diff --git a/depends/README.packages b/depends/README.packages
index c35abfbdc1..5ab7ed7dee 100644
--- a/depends/README.packages
+++ b/depends/README.packages
@@ -65,10 +65,22 @@ These variables may be set to override or append their default values.
$(package)_config_env
$(package)_build_env
$(package)_stage_env
+ $(package)_build_opts
+ $(package)_config_opts
The *_env variables are used to add environment variables to the respective
commands.
+Many variables respect a debug/release suffix as well, in order to use them for
+only the appropriate build config. For example:
+ $(package)_cflags_release = -O3
+ $(package)_cflags_i686_debug = -g
+ $(package)_config_opts_release = --disable-debug
+
+These will be used in addition to the options that do not specify
+debug/release. All builds are considered to be release unless DEBUG=1 is set by
+the user.
+
Other variables may be defined as needed.
Build commands:
diff --git a/depends/README.usage b/depends/README.usage
index 0aacefbf94..d3c57956f1 100644
--- a/depends/README.usage
+++ b/depends/README.usage
@@ -22,6 +22,7 @@ FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before givin
NO_QT: Don't download/build/cache qt and its dependencies
NO_WALLET: Don't download/build/cache libs needed to enable the wallet
NO_UPNP: Don't download/build/cache packages needed for enabling upnp
+DEBUG: disable some optimizations and enable more runtime checking
If some packages are not built, for example 'make NO_WALLET=1', the appropriate
options will be passed to bitcoin's configure. In this case, --disable-wallet.
diff --git a/depends/config.site.in b/depends/config.site.in
index 1df04eec3f..3426050cd3 100644
--- a/depends/config.site.in
+++ b/depends/config.site.in
@@ -52,7 +52,9 @@ export PATH=$prefix/native/bin:$PATH
export PKG_CONFIG="`which pkg-config` --static"
export PKG_CONFIG_LIBDIR=$prefix/lib/pkgconfig
export PKG_CONFIG_PATH=$prefix/share/pkgconfig
+
export CPPFLAGS="-I$prefix/include/ $CPPFLAGS"
+export LDFLAGS="-L$prefix/lib $LDFLAGS"
export CC="@CC@"
export CXX="@CXX@"
@@ -75,10 +77,19 @@ if test -n "@NM@"; then
ac_cv_path_ac_pt_NM=${NM}
fi
+if test -n "@debug@"; then
+ enable_reduce_exports=no
+fi
+
if test -n "@CFLAGS@"; then
export CFLAGS="@CFLAGS@ $CFLAGS"
fi
if test -n "@CXXFLAGS@"; then
export CXXFLAGS="@CXXFLAGS@ $CXXFLAGS"
fi
-export LDFLAGS="-L$prefix/lib @LDFLAGS@ $LDFLAGS"
+if test -n "@CPPFLAGS@"; then
+ export CPPFLAGS="@CPPFLAGS@ $CPPFLAGS"
+fi
+if test -n "@LDFLAGS@"; then
+ export LDFLAGS="@LDFLAGS@ $LDFLAGS"
+fi
diff --git a/depends/funcs.mk b/depends/funcs.mk
index 28bfb85492..c1fc0a0e33 100644
--- a/depends/funcs.mk
+++ b/depends/funcs.mk
@@ -8,10 +8,10 @@ $(1)_ar=$($($(1)_type)_AR)
$(1)_ranlib=$($($(1)_type)_RANLIB)
$(1)_libtool=$($($(1)_type)_LIBTOOL)
$(1)_nm=$($($(1)_type)_NM)
-$(1)_cflags=$($($(1)_type)_CFLAGS)
-$(1)_cxxflags=$($($(1)_type)_CXXFLAGS)
-$(1)_ldflags=$($($(1)_type)_LDFLAGS) -L$($($(1)_type)_prefix)/lib
-$(1)_cppflags:=-I$($($(1)_type)_prefix)/include
+$(1)_cflags=$($($(1)_type)_CFLAGS) $($($(1)_type)_$(release_type)_CFLAGS)
+$(1)_cxxflags=$($($(1)_type)_CXXFLAGS) $($($(1)_type)_$(release_type)_CXXFLAGS)
+$(1)_ldflags=$($($(1)_type)_LDFLAGS) $($($(1)_type)_$(release_type)_LDFLAGS) -L$($($(1)_type)_prefix)/lib
+$(1)_cppflags=$($($(1)_type)_CPPFLAGS) $($($(1)_type)_$(release_type)_CPPFLAGS) -I$($($(1)_type)_prefix)/include
$(1)_recipe_hash:=
endef
@@ -38,7 +38,7 @@ define int_get_build_id
$(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies))
$(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($(1)_dependencies)))
$(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash)))
-$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash) $($(1)_build_id_deps))
+$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps))
$(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)))
final_build_id_long+=$($(package)_build_id_long)
@@ -83,33 +83,40 @@ endef
define int_config_attach_build_config
$(eval $(call $(1)_set_vars,$(1)))
-$(1)_cflags+=$($(1)_cflags_$(host_arch))
-$(1)_cflags+=$($(1)_cflags_$(host_os))
-$(1)_cflags+=$($(1)_cflags_$(host_arch)_$(host_os))
-
-$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch))
-$(1)_cxxflags+=$($(1)_cxxflags_$(host_os))
-$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch)_$(host_os))
-
-$(1)_cppflags+=$($(1)_cppflags_$(host_arch))
-$(1)_cppflags+=$($(1)_cppflags_$(host_os))
-$(1)_cppflags+=$($(1)_cppflags_$(host_arch)_$(host_os))
-
-$(1)_ldflags+=$($(1)_ldflags_$(host_arch))
-$(1)_ldflags+=$($(1)_ldflags_$(host_os))
-$(1)_ldflags+=$($(1)_ldflags_$(host_arch)_$(host_os))
-
-$(1)_build_opts+=$$($(1)_build_opts_$(host_arch))
-$(1)_build_opts+=$$($(1)_build_opts_$(host_os))
-$(1)_build_opts+=$$($(1)_build_opts_$(host_arch)_$(host_os))
-
-$(1)_config_opts+=$$($(1)_config_opts_$(host_arch))
-$(1)_config_opts+=$$($(1)_config_opts_$(host_os))
-$(1)_config_opts+=$$($(1)_config_opts_$(host_arch)_$(host_os))
-
-$(1)_config_env+=$($(1)_config_env_$(host_arch))
-$(1)_config_env+=$($(1)_config_env_$(host_os))
-$(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os))
+$(1)_cflags+=$($(1)_cflags_$(release_type))
+$(1)_cflags+=$($(1)_cflags_$(host_arch)) $($(1)_cflags_$(host_arch)_$(release_type))
+$(1)_cflags+=$($(1)_cflags_$(host_os)) $($(1)_cflags_$(host_os)_$(release_type))
+$(1)_cflags+=$($(1)_cflags_$(host_arch)_$(host_os)) $($(1)_cflags_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_cxxflags+=$($(1)_cxxflags_$(release_type))
+$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch)) $($(1)_cxxflags_$(host_arch)_$(release_type))
+$(1)_cxxflags+=$($(1)_cxxflags_$(host_os)) $($(1)_cxxflags_$(host_os)_$(release_type))
+$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch)_$(host_os)) $($(1)_cxxflags_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_cppflags+=$($(1)_cppflags_$(release_type))
+$(1)_cppflags+=$($(1)_cppflags_$(host_arch)) $($(1)_cppflags_$(host_arch)_$(release_type))
+$(1)_cppflags+=$($(1)_cppflags_$(host_os)) $($(1)_cppflags_$(host_os)_$(release_type))
+$(1)_cppflags+=$($(1)_cppflags_$(host_arch)_$(host_os)) $($(1)_cppflags_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_ldflags+=$($(1)_ldflags_$(release_type))
+$(1)_ldflags+=$($(1)_ldflags_$(host_arch)) $($(1)_ldflags_$(host_arch)_$(release_type))
+$(1)_ldflags+=$($(1)_ldflags_$(host_os)) $($(1)_ldflags_$(host_os)_$(release_type))
+$(1)_ldflags+=$($(1)_ldflags_$(host_arch)_$(host_os)) $($(1)_ldflags_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_build_opts+=$$($(1)_build_opts_$(release_type))
+$(1)_build_opts+=$$($(1)_build_opts_$(host_arch)) $$($(1)_build_opts_$(host_arch)_$(release_type))
+$(1)_build_opts+=$$($(1)_build_opts_$(host_os)) $$($(1)_build_opts_$(host_os)_$(release_type))
+$(1)_build_opts+=$$($(1)_build_opts_$(host_arch)_$(host_os)) $$($(1)_build_opts_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_config_opts+=$$($(1)_config_opts_$(release_type))
+$(1)_config_opts+=$$($(1)_config_opts_$(host_arch)) $$($(1)_config_opts_$(host_arch)_$(release_type))
+$(1)_config_opts+=$$($(1)_config_opts_$(host_os)) $$($(1)_config_opts_$(host_os)_$(release_type))
+$(1)_config_opts+=$$($(1)_config_opts_$(host_arch)_$(host_os)) $$($(1)_config_opts_$(host_arch)_$(host_os)_$(release_type))
+
+$(1)_config_env+=$$($(1)_config_env_$(release_type))
+$(1)_config_env+=$($(1)_config_env_$(host_arch)) $($(1)_config_env_$(host_arch)_$(release_type))
+$(1)_config_env+=$($(1)_config_env_$(host_os)) $($(1)_config_env_$(host_os)_$(release_type))
+$(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os)) $($(1)_config_env_$(host_arch)_$(host_os)_$(release_type))
$(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig
$(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig
diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk
index 9e2415655e..8d718eba17 100644
--- a/depends/hosts/darwin.mk
+++ b/depends/hosts/darwin.mk
@@ -3,6 +3,14 @@ OSX_SDK_VERSION=10.7
OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk
darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK)
darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK)
-darwin_CFLAGS=-pipe -O2
+
+darwin_CFLAGS=-pipe
darwin_CXXFLAGS=$(darwin_CFLAGS)
+
+darwin_release_CFLAGS=-O2
+darwin_release_CXXFLAGS=$(darwin_release_CFLAGS)
+
+darwin_debug_CFLAGS=-O1
+darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS)
+
darwin_native_toolchain=native_cctools
diff --git a/depends/hosts/default.mk b/depends/hosts/default.mk
index b9fe5d858a..6f60d6b3fd 100644
--- a/depends/hosts/default.mk
+++ b/depends/hosts/default.mk
@@ -11,13 +11,16 @@ default_host_NM = $(host_toolchain)nm
define add_host_tool_func
$(host_os)_$1?=$$(default_host_$1)
$(host_arch)_$(host_os)_$1?=$$($(host_os)_$1)
+$(host_arch)_$(host_os)_$(release_type)_$1?=$$($(host_os)_$1)
host_$1=$$($(host_arch)_$(host_os)_$1)
endef
define add_host_flags_func
$(host_arch)_$(host_os)_$1 += $($(host_os)_$1)
+$(host_arch)_$(host_os)_$(release_type)_$1 += $($(host_os)_$(release_type)_$1)
host_$1 = $$($(host_arch)_$(host_os)_$1)
+host_$(release_type)_$1 = $$($(host_arch)_$(host_os)_$(release_type)_$1)
endef
$(foreach tool,CC CXX AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL,$(eval $(call add_host_tool_func,$(tool))))
-$(foreach flags,CFLAGS CXXFLAGS LDFLAGS, $(eval $(call add_host_flags_func,$(flags))))
+$(foreach flags,CFLAGS CXXFLAGS CPPFLAGS LDFLAGS, $(eval $(call add_host_flags_func,$(flags))))
diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk
index 194d71d557..b13a0f1ad7 100644
--- a/depends/hosts/linux.mk
+++ b/depends/hosts/linux.mk
@@ -1,6 +1,14 @@
-linux_CFLAGS=-pipe -O2
+linux_CFLAGS=-pipe
linux_CXXFLAGS=$(linux_CFLAGS)
+linux_release_CFLAGS=-O2
+linux_release_CXXFLAGS=$(linux_release_CFLAGS)
+
+linux_debug_CFLAGS=-O1
+linux_debug_CXXFLAGS=$(linux_debug_CFLAGS)
+
+linux_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
+
ifeq (86,$(findstring 86,$(build_arch)))
i686_linux_CC=gcc -m32
i686_linux_CXX=g++ -m32
diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk
index ffe4a55842..dbfb62fdcf 100644
--- a/depends/hosts/mingw32.mk
+++ b/depends/hosts/mingw32.mk
@@ -1,2 +1,10 @@
-mingw32_CFLAGS=-pipe -O2
+mingw32_CFLAGS=-pipe
mingw32_CXXFLAGS=$(mingw32_CFLAGS)
+
+mingw32_release_CFLAGS=-O2
+mingw32_release_CXXFLAGS=$(mingw32_release_CFLAGS)
+
+mingw32_debug_CFLAGS=-O1
+mingw32_debug_CXXFLAGS=$(mingw32_debug_CFLAGS)
+
+mingw32_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk
index a3cacbcbb6..98ed3de772 100644
--- a/depends/packages/boost.mk
+++ b/depends/packages/boost.mk
@@ -6,8 +6,10 @@ $(package)_sha256_hash=fff00023dd79486d444c8e29922f4072e1d451fc5a4d2b6075852ead7
$(package)_patches=darwin_boost_atomic-1.patch darwin_boost_atomic-2.patch
define $(package)_set_vars
+$(package)_config_opts_release=variant=release
+$(package)_config_opts_debug=variant=debug
$(package)_config_opts=--layout=tagged --build-type=complete --user-config=user-config.jam
-$(package)_config_opts+=variant=release threading=multi link=static -sNO_BZIP2=1 -sNO_ZLIB=1
+$(package)_config_opts+=threading=multi link=static -sNO_BZIP2=1 -sNO_ZLIB=1
$(package)_config_opts_linux=threadapi=pthread runtime-link=shared
$(package)_config_opts_darwin=--toolset=darwin-4.2.1 runtime-link=shared
$(package)_config_opts_mingw32=binary-format=pe target-os=windows threadapi=win32 runtime-link=static
@@ -26,7 +28,7 @@ endef
define $(package)_preprocess_cmds
patch -p2 < $($(package)_patch_dir)/darwin_boost_atomic-1.patch && \
patch -p2 < $($(package)_patch_dir)/darwin_boost_atomic-2.patch && \
- echo "using $(boost_toolset_$(host_os)) : : $($(package)_cxx) : <cxxflags>\"$($(package)_cxxflags)\" <linkflags>\"$($(package)_ldflags)\" <archiver>\"$(boost_archiver_$(host_os))\" <striper>\"$(host_STRIP)\" <ranlib>\"$(host_RANLIB)\" <rc>\"$(host_WINDRES)\" : ;" > user-config.jam
+ echo "using $(boost_toolset_$(host_os)) : : $($(package)_cxx) : <cxxflags>\"$($(package)_cxxflags) $($(package)_cppflags)\" <linkflags>\"$($(package)_ldflags)\" <archiver>\"$(boost_archiver_$(host_os))\" <striper>\"$(host_STRIP)\" <ranlib>\"$(host_RANLIB)\" <rc>\"$(host_WINDRES)\" : ;" > user-config.jam
endef
define $(package)_config_cmds
diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk
index 30f2d3f315..00101f1b91 100644
--- a/depends/packages/miniupnpc.mk
+++ b/depends/packages/miniupnpc.mk
@@ -8,7 +8,7 @@ define $(package)_set_vars
$(package)_build_opts=CC="$($(package)_cc)"
$(package)_build_opts_darwin=OS=Darwin
$(package)_build_opts_mingw32=-f Makefile.mingw
-$(package)_build_env+=CFLAGS="$($(package)_cflags)" AR="$($(package)_ar)"
+$(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$($(package)_ar)"
endef
define $(package)_preprocess_cmds
diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk
index b1dcc6f81f..3ccdaf6f2f 100644
--- a/depends/packages/openssl.mk
+++ b/depends/packages/openssl.mk
@@ -9,7 +9,7 @@ $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$(
$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl no-zlib no-shared no-dso
$(package)_config_opts+=no-krb5 no-camellia no-capieng no-cast no-cms no-dtls1 no-gost no-gmp no-heartbeats no-idea no-jpake no-md2
$(package)_config_opts+=no-mdc2 no-rc5 no-rdrand no-rfc3779 no-rsax no-sctp no-seed no-sha0 no-static_engine no-whirlpool no-rc2 no-rc4 no-ssl3
-$(package)_config_opts+=$($(package)_cflags)
+$(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags)
$(package)_config_opts_x86_64_linux=-fPIC linux-x86_64
$(package)_config_opts_arm_linux=-fPIC linux-generic32
$(package)_config_opts_x86_64_darwin=darwin64-x86_64-cc
diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk
index e719e2e506..5fbab57dd4 100644
--- a/depends/packages/qt.mk
+++ b/depends/packages/qt.mk
@@ -10,8 +10,9 @@ $(package)_qt_libs=corelib network widgets gui plugins testlib
$(package)_patches=mac-qmake.conf fix-xcb-include-order.patch qt5-tablet-osx.patch
define $(package)_set_vars
-$(package)_config_opts = -release -opensource -confirm-license
-$(package)_config_opts += -no-audio-backend -no-sql-tds -no-glib -no-icu
+$(package)_config_opts_release = -release
+$(package)_config_opts_debug = -debug
+$(package)_config_opts += -opensource -confirm-license -no-audio-backend -no-sql-tds -no-glib -no-icu
$(package)_config_opts += -no-cups -no-iconv -no-gif -no-audio-backend -no-freetype
$(package)_config_opts += -no-sql-sqlite -no-nis -no-cups -no-iconv -no-pch
$(package)_config_opts += -no-gif -no-feature-style-plastique
@@ -53,7 +54,13 @@ define $(package)_preprocess_cmds
cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\
cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \
patch -p1 < $($(package)_patch_dir)/fix-xcb-include-order.patch && \
- patch -p1 < $($(package)_patch_dir)/qt5-tablet-osx.patch
+ patch -p1 < $($(package)_patch_dir)/qt5-tablet-osx.patch && \
+ echo "QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
+ echo "QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
+ echo "QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \
+ sed -i.old "s|QMAKE_CFLAGS = |QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
+ sed -i.old "s|QMAKE_LFLAGS = |QMAKE_LFLAGS = $($(package)_ldflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \
+ sed -i.old "s|QMAKE_CXXFLAGS = |QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf
endef
define $(package)_config_cmds
diff --git a/doc/release-process.md b/doc/release-process.md
index 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 94a582dfac..2c64cb74a0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -67,6 +67,7 @@ BITCOIN_CORE_H = \
allocators.h \
base58.h \
bloom.h \
+ chain.h \
chainparams.h \
chainparamsbase.h \
chainparamsseeds.h \
@@ -145,6 +146,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..bcb497b2d4
--- /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/X11 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..91bdf38347
--- /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/X11 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
diff --git a/src/init.cpp b/src/init.cpp
index 27594ecbe3..85f4d360d2 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/main.cpp b/src/main.cpp
index 60e2a56795..9a4271eda2 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 5acc551793..c75841538f 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/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");