mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-22 00:00:55 +01:00
Compare commits
221 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9cea169813 | ||
|
|
4e1134bdf1 | ||
|
|
12a0c0b3aa | ||
|
|
61646394b7 | ||
|
|
6bf4884d7b | ||
|
|
dc9ae4c26e | ||
|
|
b0c97ce31a | ||
|
|
c2e7baf2bd | ||
|
|
3b89bf6438 | ||
|
|
8b3311fb8d | ||
|
|
97546fc44c | ||
|
|
38671bff4e | ||
|
|
256321ebd2 | ||
|
|
eae0350b9c | ||
|
|
90897ab343 | ||
|
|
a2f2fb6acf | ||
|
|
cf67d8b49b | ||
|
|
b3964e3b7a | ||
|
|
43c2789fe3 | ||
|
|
dfe0d4da7e | ||
|
|
612efe89e3 | ||
|
|
3ad96bdf73 | ||
|
|
9c810058d8 | ||
|
|
cbc4e3bd37 | ||
|
|
94b67e58d1 | ||
|
|
5216f3c5d4 | ||
|
|
72a0adfb3c | ||
|
|
4b80b09f73 | ||
|
|
5297194bbd | ||
|
|
7e9a9874f3 | ||
|
|
0b3fd07fd2 | ||
|
|
fb818b6be4 | ||
|
|
8d598c26e3 | ||
|
|
842c48dba3 | ||
|
|
91ef4d93d4 | ||
|
|
f2778e0ce6 | ||
|
|
cf5bf5542a | ||
|
|
44d6bc8528 | ||
|
|
1bf6ac62ab | ||
|
|
093d7b5895 | ||
|
|
5dc72f8bb0 | ||
|
|
6a1343b470 | ||
|
|
41372485ce | ||
|
|
0e01d0f89d | ||
|
|
6d0132520c | ||
|
|
750d54f951 | ||
|
|
689746841a | ||
|
|
1cea6b0dee | ||
|
|
9bd0b4a633 | ||
|
|
743cc9e08b | ||
|
|
f696ea12e1 | ||
|
|
5e6d893650 | ||
|
|
ceba0f8c7e | ||
|
|
2ede6b7142 | ||
|
|
0dfcdd41eb | ||
|
|
c9ad65e5fa | ||
|
|
0194bddde4 | ||
|
|
bdf2542787 | ||
|
|
65426acb4d | ||
|
|
28d76d2aea | ||
|
|
843469ee15 | ||
|
|
4e5ea71bd5 | ||
|
|
3861f0fa21 | ||
|
|
04507de3b7 | ||
|
|
8b59079b8d | ||
|
|
ae52a7ffd1 | ||
|
|
0739e6e57a | ||
|
|
255eced936 | ||
|
|
7e66e9c97b | ||
|
|
3f5563877a | ||
|
|
be6420407b | ||
|
|
0fd8464458 | ||
|
|
09334e04a9 | ||
|
|
181771b712 | ||
|
|
ecc96f5ba9 | ||
|
|
ebd7d8d78c | ||
|
|
ae3d8f371a | ||
|
|
e4a7d51537 | ||
|
|
16f45600c8 | ||
|
|
ff32503267 | ||
|
|
da656068ec | ||
|
|
49e4d14f75 | ||
|
|
d7e7727658 | ||
|
|
424ae6629b | ||
|
|
9a5b88cc0c | ||
|
|
824c011d16 | ||
|
|
ebc0e41ede | ||
|
|
d8ac901842 | ||
|
|
bf8ad0dc6b | ||
|
|
139cd8177b | ||
|
|
bac6fca3c9 | ||
|
|
3a70613398 | ||
|
|
323de27f4b | ||
|
|
7494e0915b | ||
|
|
df45564cf0 | ||
|
|
57d1f46952 | ||
|
|
eae305f4c4 | ||
|
|
34127c77cb | ||
|
|
1c62e84099 | ||
|
|
149c1d890d | ||
|
|
24e48991d3 | ||
|
|
bf1cc80372 | ||
|
|
9e1cc16296 | ||
|
|
fe3122580e | ||
|
|
2b7636c3d6 | ||
|
|
ae1479a114 | ||
|
|
aa587d4cae | ||
|
|
0c6f334c32 | ||
|
|
214154e6fc | ||
|
|
2218d4bbe0 | ||
|
|
cf0218f8b2 | ||
|
|
b788994256 | ||
|
|
90bef6638f | ||
|
|
a1f425b48b | ||
|
|
4635a4c4e7 | ||
|
|
0eccf0ae30 | ||
|
|
78f64ef0b2 | ||
|
|
a316622fd0 | ||
|
|
1d2cdd2ef9 | ||
|
|
c9e022b7ee | ||
|
|
10c09f98b2 | ||
|
|
8752b5c882 | ||
|
|
601327be8c | ||
|
|
ca301bf98c | ||
|
|
2c0840631d | ||
|
|
81145a6ccd | ||
|
|
11173786ce | ||
|
|
c91c660e49 | ||
|
|
002c8a2411 | ||
|
|
200f29363b | ||
|
|
d5d8998028 | ||
|
|
786cf72c7f | ||
|
|
aeb9279228 | ||
|
|
23126a0a09 | ||
|
|
d148f62e00 | ||
|
|
7f502be259 | ||
|
|
047a898317 | ||
|
|
327d3e8824 | ||
|
|
7b6c847f67 | ||
|
|
e43f25c5b1 | ||
|
|
275400bfcc | ||
|
|
63efb36672 | ||
|
|
1eb14af28f | ||
|
|
336f9fbd30 | ||
|
|
b6347bf813 | ||
|
|
2448d34298 | ||
|
|
1bbad80bf4 | ||
|
|
b788c5561a | ||
|
|
fd7350d22e | ||
|
|
3916a81a27 | ||
|
|
6da2028b55 | ||
|
|
773c30d756 | ||
|
|
18695f08ef | ||
|
|
abfbeafe84 | ||
|
|
6a02ef8bdb | ||
|
|
b61940b3a1 | ||
|
|
c5044bc169 | ||
|
|
b24ff47c64 | ||
|
|
ed4206acb1 | ||
|
|
58259ad1ed | ||
|
|
186a517692 | ||
|
|
aaf55d25c6 | ||
|
|
249bf0e049 | ||
|
|
c3200bcd1e | ||
|
|
af35bdc6b0 | ||
|
|
4e7c219122 | ||
|
|
a3a73170a9 | ||
|
|
12b7c444f0 | ||
|
|
76ce5c8de3 | ||
|
|
2d375fe97b | ||
|
|
ace39db764 | ||
|
|
263b65ebf0 | ||
|
|
e2677d7ae8 | ||
|
|
7fdbedcaf8 | ||
|
|
867c600c29 | ||
|
|
008138c04a | ||
|
|
3022e7df2a | ||
|
|
06fdf326d3 | ||
|
|
58fda4d689 | ||
|
|
68c0580dfb | ||
|
|
4a3d3e20c0 | ||
|
|
94b362dbd6 | ||
|
|
221a38024a | ||
|
|
c2029018cc | ||
|
|
50891ad080 | ||
|
|
9241f7a7c1 | ||
|
|
4f57a3b20c | ||
|
|
8061d67aeb | ||
|
|
d1bcef4391 | ||
|
|
1eadfd9753 | ||
|
|
18021d08f7 | ||
|
|
b790d139c9 | ||
|
|
8543b0dfd9 | ||
|
|
968f13cae3 | ||
|
|
87d43a3c8e | ||
|
|
ed934bdb4d | ||
|
|
591c5692f8 | ||
|
|
52e57055cc | ||
|
|
b3d67e1c34 | ||
|
|
06ca0651b6 | ||
|
|
4e0bfa5814 | ||
|
|
2bb0ca9b55 | ||
|
|
a2300499b7 | ||
|
|
343492795a | ||
|
|
13e129ed9a | ||
|
|
3aa3c710ac | ||
|
|
f4dcc1e009 | ||
|
|
63b5a1dc80 | ||
|
|
c888111a3f | ||
|
|
3a88ba0794 | ||
|
|
d10a9015ad | ||
|
|
15ad0b54fa | ||
|
|
11855c1f99 | ||
|
|
8446262597 | ||
|
|
ad3d208fb9 | ||
|
|
0cb8763cbb | ||
|
|
b03632a671 | ||
|
|
c3c635b316 | ||
|
|
a572ff7139 | ||
|
|
44b4c0d8a9 | ||
|
|
0133e4fb48 |
13
.travis.yml
13
.travis.yml
@@ -2,10 +2,17 @@
|
||||
# - A travis bug causes caches to trample eachother when using the same
|
||||
# compiler key (which we don't use anyway). This is worked around for now by
|
||||
# replacing the "compilers" with a build name prefixed by the no-op ":"
|
||||
# command. See: https://github.com/travis-ci/casher/issues/6
|
||||
# command. See: https://github.com/travis-ci/travis-ci/issues/4393
|
||||
# - sudo/dist/group are set so as to get Blue Box VMs, necessary for [loopback]
|
||||
# IPv6 support
|
||||
|
||||
sudo: required
|
||||
dist: precise
|
||||
group: legacy
|
||||
|
||||
os: linux
|
||||
language: cpp
|
||||
compiler: gcc
|
||||
env:
|
||||
global:
|
||||
- MAKEJOBS=-j3
|
||||
@@ -38,13 +45,15 @@ matrix:
|
||||
env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2"
|
||||
- compiler: ": Win32"
|
||||
env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2"
|
||||
exclude:
|
||||
- compiler: gcc
|
||||
install:
|
||||
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi
|
||||
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi
|
||||
before_script:
|
||||
- unset CC; unset CXX
|
||||
- mkdir -p depends/SDKs depends/sdk-sources
|
||||
- if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then wget $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -O depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
|
||||
- if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
|
||||
- if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
|
||||
- make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS
|
||||
script:
|
||||
|
||||
2
COPYING
2
COPYING
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2009-2014 Bitcoin Developers
|
||||
Copyright (c) 2009-2015 Bitcoin Developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -190,6 +190,8 @@ check-local:
|
||||
@qa/pull-tester/run-bitcoind-for-test.sh $(JAVA) -jar $(JAVA_COMPARISON_TOOL) qa/tmp/compTool $(COMPARISON_TOOL_REORG_TESTS) 2>&1
|
||||
endif
|
||||
|
||||
dist_noinst_SCRIPTS = autogen.sh
|
||||
|
||||
EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.sh qa/pull-tester/run-bitcoin-cli qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING)
|
||||
|
||||
CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER)
|
||||
|
||||
@@ -5,8 +5,6 @@ Bitcoin Core integration/staging tree
|
||||
|
||||
https://www.bitcoin.org
|
||||
|
||||
Copyright (c) 2009-2014 Bitcoin Core Developers
|
||||
|
||||
What is Bitcoin?
|
||||
----------------
|
||||
|
||||
@@ -36,7 +34,7 @@ development team members simply pulls it.
|
||||
|
||||
If it is a *more complicated or potentially controversial* change, then the patch
|
||||
submitter will be asked to start a discussion (if they haven't already) on the
|
||||
[mailing list](http://sourceforge.net/mailarchive/forum.php?forum_name=bitcoin-development).
|
||||
[mailing list](https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev)
|
||||
|
||||
The patch will be accepted if there is broad consensus that it is a good thing.
|
||||
Developers should expect to rework and resubmit patches if the code doesn't
|
||||
|
||||
33
configure.ac
33
configure.ac
@@ -1,11 +1,11 @@
|
||||
dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
|
||||
AC_PREREQ([2.60])
|
||||
define(_CLIENT_VERSION_MAJOR, 0)
|
||||
define(_CLIENT_VERSION_MINOR, 9)
|
||||
define(_CLIENT_VERSION_REVISION, 99)
|
||||
define(_CLIENT_VERSION_MINOR, 10)
|
||||
define(_CLIENT_VERSION_REVISION, 4)
|
||||
define(_CLIENT_VERSION_BUILD, 0)
|
||||
define(_CLIENT_VERSION_IS_RELEASE, false)
|
||||
define(_COPYRIGHT_YEAR, 2014)
|
||||
define(_CLIENT_VERSION_IS_RELEASE, true)
|
||||
define(_COPYRIGHT_YEAR, 2015)
|
||||
AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[info@bitcoin.org],[bitcoin])
|
||||
AC_CONFIG_SRCDIR([src/main.cpp])
|
||||
AC_CONFIG_HEADERS([src/config/bitcoin-config.h])
|
||||
@@ -167,7 +167,7 @@ fi
|
||||
## compatibility with the legacy buildsystem.
|
||||
##
|
||||
if test "x$CXXFLAGS_overridden" = "xno"; then
|
||||
CXXFLAGS="$CXXFLAGS -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter"
|
||||
CXXFLAGS="$CXXFLAGS -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter -Wno-self-assign"
|
||||
fi
|
||||
CPPFLAGS="$CPPFLAGS -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS"
|
||||
|
||||
@@ -701,11 +701,34 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB([crypto],[RAND_egd],[],[
|
||||
AC_ARG_WITH([libressl],
|
||||
[AS_HELP_STRING([--with-libressl],[Build with system LibreSSL (default is no; DANGEROUS; NOT SUPPORTED)])],
|
||||
[AC_MSG_WARN([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])],
|
||||
[AC_MSG_ERROR([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])]
|
||||
)
|
||||
])
|
||||
|
||||
CFLAGS_TEMP="$CFLAGS"
|
||||
LIBS_TEMP="$LIBS"
|
||||
CFLAGS="$CFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS"
|
||||
LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS"
|
||||
AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),)
|
||||
|
||||
AC_MSG_CHECKING(for a supported OpenSSL version)
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <openssl/rand.h>
|
||||
]],
|
||||
[[RAND_egd(NULL);]])],
|
||||
[AC_MSG_RESULT(yes)],
|
||||
[
|
||||
AC_ARG_WITH([libressl],
|
||||
[AS_HELP_STRING([--with-libressl],[Build with system LibreSSL (default is no; DANGEROUS; NOT SUPPORTED)])],
|
||||
[AC_MSG_WARN([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])],
|
||||
[AC_MSG_ERROR([Detected LibreSSL: This is NOT supported, and may break consensus compatibility!])]
|
||||
)]
|
||||
)
|
||||
|
||||
CFLAGS="$CFLAGS_TEMP"
|
||||
LIBS="$LIBS_TEMP"
|
||||
|
||||
|
||||
1
contrib/debian/bitcoin-tx.install
Normal file
1
contrib/debian/bitcoin-tx.install
Normal file
@@ -0,0 +1 @@
|
||||
usr/local/bin/bitcoin-tx usr/bin
|
||||
@@ -1,3 +1,39 @@
|
||||
bitcoin (0.10.2-precise1) precise; urgency=medium
|
||||
|
||||
* New upstream release.
|
||||
|
||||
-- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Mon, 29 Jun 2015 17:33:00 -1000
|
||||
|
||||
bitcoin (0.10.1-precise3) precise; urgency=medium
|
||||
|
||||
* Fix build dep (include python).
|
||||
|
||||
-- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Tue, 5 May 2015 09:28:00 -1000
|
||||
|
||||
bitcoin (0.10.1-precise2) precise; urgency=medium
|
||||
|
||||
* Fix miniupnpc dep.
|
||||
|
||||
-- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Tue, 5 May 2015 00:33:00 -1000
|
||||
|
||||
bitcoin (0.10.1-precise1) precise; urgency=medium
|
||||
|
||||
* New upstream release.
|
||||
|
||||
-- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Tue, 5 May 2015 00:07:00 -1000
|
||||
|
||||
bitcoin (0.10.0-precise1) precise; urgency=medium
|
||||
|
||||
* New upstream releases.
|
||||
|
||||
-- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Wed, 18 Feb 2015 13:22:00 -1000
|
||||
|
||||
bitcoin (0.9.4-precise1) precise; urgency=high
|
||||
|
||||
* New upstream releases.
|
||||
|
||||
-- Matt Corallo (laptop - only while traveling) <matt@mattcorallo.com> Mon, 12 Jan 2015 23:30:00 -1000
|
||||
|
||||
bitcoin (0.9.3-precise1) precise; urgency=medium
|
||||
|
||||
* New upstream releases.
|
||||
@@ -137,7 +173,7 @@ bitcoin (0.5.3-natty0) natty; urgency=low
|
||||
bitcoin (0.5.2-natty1) natty; urgency=low
|
||||
|
||||
* Remove mentions on anonymity in package descriptions and manpage.
|
||||
These should never have been there, bitcoin isnt anonymous without
|
||||
These should never have been there, bitcoin isn't anonymous without
|
||||
a ton of work that virtually no users will ever be willing and
|
||||
capable of doing
|
||||
|
||||
@@ -178,7 +214,7 @@ bitcoin (0.5.0~rc1-natty1) natty; urgency=low
|
||||
|
||||
* Add test_bitcoin to build test
|
||||
* Fix clean
|
||||
* Remove uneccessary build-dependancies
|
||||
* Remove unnecessary build-dependancies
|
||||
|
||||
-- Matt Corallo <matt@bluematt.me> Wed, 26 Oct 2011 14:37:18 -0400
|
||||
|
||||
@@ -338,7 +374,7 @@ bitcoin (0.3.20.01~dfsg-1) unstable; urgency=low
|
||||
|
||||
bitcoin (0.3.19~dfsg-6) unstable; urgency=low
|
||||
|
||||
* Fix override agressive optimizations.
|
||||
* Fix override aggressive optimizations.
|
||||
* Fix tighten build-dependencies to really fit backporting to Lenny:
|
||||
+ Add fallback build-dependency on libdb4.6++-dev.
|
||||
+ Tighten unversioned Boost build-dependencies to recent versions,
|
||||
|
||||
@@ -20,11 +20,12 @@ Build-Depends: debhelper,
|
||||
qt4-qmake,
|
||||
libqt4-dev,
|
||||
libqrencode-dev,
|
||||
libprotobuf-dev, protobuf-compiler
|
||||
libprotobuf-dev, protobuf-compiler,
|
||||
python
|
||||
Standards-Version: 3.9.2
|
||||
Homepage: http://www.bitcoin.org/
|
||||
Homepage: https://www.bitcoin.org/
|
||||
Vcs-Git: git://github.com/bitcoin/bitcoin.git
|
||||
Vcs-Browser: http://github.com/bitcoin/bitcoin
|
||||
Vcs-Browser: https://github.com/bitcoin/bitcoin
|
||||
|
||||
Package: bitcoind
|
||||
Architecture: any
|
||||
@@ -56,3 +57,17 @@ Description: peer-to-peer network based digital currency - Qt GUI
|
||||
requires 20+ GB of space, slowly growing.
|
||||
.
|
||||
This package provides Bitcoin-Qt, a GUI for Bitcoin based on Qt.
|
||||
|
||||
Package: bitcoin-tx
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: peer-to-peer digital currency - standalone transaction tool
|
||||
Bitcoin is a free open source peer-to-peer electronic cash system that
|
||||
is completely decentralized, without the need for a central server or
|
||||
trusted parties. Users hold the crypto keys to their own money and
|
||||
transact directly with each other, with the help of a P2P network to
|
||||
check for double-spending.
|
||||
.
|
||||
This package provides bitcoin-tx, a command-line transaction creation
|
||||
tool which can be used without a bitcoin daemon. Some means of
|
||||
exchanging minimal transaction data with peers is still required.
|
||||
|
||||
@@ -2,8 +2,7 @@ Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?rev=174
|
||||
Upstream-Name: Bitcoin
|
||||
Upstream-Contact: Satoshi Nakamoto <satoshin@gmx.com>
|
||||
irc://#bitcoin@freenode.net
|
||||
Source: http://sourceforge.net/projects/bitcoin/files/
|
||||
https://github.com/bitcoin/bitcoin
|
||||
Source: https://github.com/bitcoin/bitcoin
|
||||
|
||||
Files: *
|
||||
Copyright: 2009-2012, Bitcoin Core Developers
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
# JSON-RPC options (for controlling a running Bitcoin/bitcoind process)
|
||||
#
|
||||
|
||||
# server=1 tells Bitcoin-QT and bitcoind to accept JSON-RPC commands
|
||||
# server=1 tells Bitcoin-Qt and bitcoind to accept JSON-RPC commands
|
||||
#server=0
|
||||
|
||||
# You must set rpcuser and rpcpassword to secure the JSON-RPC api
|
||||
@@ -72,7 +72,7 @@
|
||||
# NOTE: opening up the RPC port to hosts outside your local trusted network is NOT RECOMMENDED,
|
||||
# because the rpcpassword is transmitted over the network unencrypted.
|
||||
|
||||
# server=1 tells Bitcoin-QT to accept JSON-RPC commands.
|
||||
# server=1 tells Bitcoin-Qt to accept JSON-RPC commands.
|
||||
# it is also read by bitcoind to determine if RPC should be enabled
|
||||
#rpcallowip=10.1.1.34/255.255.255.0
|
||||
#rpcallowip=1.2.3.4/24
|
||||
|
||||
@@ -6,6 +6,7 @@ suites:
|
||||
architectures:
|
||||
- "amd64"
|
||||
packages:
|
||||
- "curl"
|
||||
- "g++-multilib"
|
||||
- "git-core"
|
||||
- "pkg-config"
|
||||
@@ -23,7 +24,7 @@ files: []
|
||||
script: |
|
||||
WRAP_DIR=$HOME/wrapped
|
||||
HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu"
|
||||
CONFIGFLAGS="--enable-upnp-default --enable-glibc-back-compat"
|
||||
CONFIGFLAGS="--enable-glibc-back-compat"
|
||||
FAKETIME_HOST_PROGS=""
|
||||
FAKETIME_PROGS="date ar ranlib nm strip"
|
||||
|
||||
@@ -79,7 +80,7 @@ script: |
|
||||
mkdir -p temp
|
||||
pushd temp
|
||||
tar xf ../$SOURCEDIST
|
||||
find bitcoin-* | sort | tar --no-recursion -c -T - | gzip -9n > ../$SOURCEDIST
|
||||
find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST
|
||||
popd
|
||||
|
||||
ORIGPATH="$PATH"
|
||||
@@ -99,7 +100,7 @@ script: |
|
||||
find . -name "lib*.la" -delete
|
||||
find . -name "lib*.a" -delete
|
||||
rm -rf ${DISTNAME}/lib/pkgconfig
|
||||
find . | sort | tar --no-recursion -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
|
||||
find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
|
||||
cd ../../
|
||||
done
|
||||
mkdir -p $OUTDIR/src
|
||||
|
||||
@@ -10,7 +10,7 @@ packages:
|
||||
reference_datetime: "2013-06-01 00:00:00"
|
||||
remotes: []
|
||||
files:
|
||||
- "bitcoin-0.9.99-osx-unsigned.tar.gz"
|
||||
- "bitcoin-osx-unsigned.tar.gz"
|
||||
- "signature.tar.gz"
|
||||
script: |
|
||||
WRAP_DIR=$HOME/wrapped
|
||||
@@ -28,8 +28,8 @@ script: |
|
||||
chmod +x ${WRAP_DIR}/${prog}
|
||||
done
|
||||
|
||||
UNSIGNED=`echo bitcoin-*.tar.gz`
|
||||
SIGNED=`echo ${UNSIGNED} | sed 's/.tar.*//' | sed 's/-unsigned//'`.dmg
|
||||
UNSIGNED=bitcoin-osx-unsigned.tar.gz
|
||||
SIGNED=bitcoin-osx-signed.dmg
|
||||
|
||||
tar -xf ${UNSIGNED}
|
||||
./detached-sig-apply.sh ${UNSIGNED} signature.tar.gz
|
||||
|
||||
@@ -7,6 +7,7 @@ architectures:
|
||||
- "amd64"
|
||||
packages:
|
||||
- "g++-multilib"
|
||||
- "curl"
|
||||
- "git-core"
|
||||
- "pkg-config"
|
||||
- "autoconf2.13"
|
||||
@@ -27,7 +28,7 @@ files:
|
||||
script: |
|
||||
WRAP_DIR=$HOME/wrapped
|
||||
HOSTS="x86_64-apple-darwin11"
|
||||
CONFIGFLAGS="--enable-upnp-default GENISOIMAGE=$WRAP_DIR/genisoimage"
|
||||
CONFIGFLAGS="GENISOIMAGE=$WRAP_DIR/genisoimage"
|
||||
FAKETIME_HOST_PROGS=""
|
||||
FAKETIME_PROGS="ar ranlib date dmg genisoimage"
|
||||
|
||||
@@ -90,7 +91,7 @@ script: |
|
||||
mkdir -p temp
|
||||
pushd temp
|
||||
tar xf ../$SOURCEDIST
|
||||
find bitcoin-* | sort | tar --no-recursion -c -T - | gzip -9n > ../$SOURCEDIST
|
||||
find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST
|
||||
popd
|
||||
|
||||
ORIGPATH="$PATH"
|
||||
@@ -116,7 +117,7 @@ script: |
|
||||
cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff
|
||||
mv dist unsigned-app-${i}
|
||||
pushd unsigned-app-${i}
|
||||
find . | sort | tar --no-recursion -czf ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz -T -
|
||||
find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz
|
||||
popd
|
||||
|
||||
make deploy
|
||||
@@ -126,7 +127,7 @@ script: |
|
||||
find . -name "lib*.la" -delete
|
||||
find . -name "lib*.a" -delete
|
||||
rm -rf ${DISTNAME}/lib/pkgconfig
|
||||
find . | sort | tar --no-recursion -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
|
||||
find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
|
||||
cd ../../
|
||||
done
|
||||
mkdir -p $OUTDIR/src
|
||||
|
||||
@@ -6,6 +6,7 @@ suites:
|
||||
architectures:
|
||||
- "amd64"
|
||||
packages:
|
||||
- "curl"
|
||||
- "g++"
|
||||
- "git-core"
|
||||
- "pkg-config"
|
||||
@@ -26,7 +27,7 @@ files: []
|
||||
script: |
|
||||
WRAP_DIR=$HOME/wrapped
|
||||
HOSTS="x86_64-w64-mingw32 i686-w64-mingw32"
|
||||
CONFIGFLAGS="--enable-upnp-default"
|
||||
CONFIGFLAGS=""
|
||||
FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip"
|
||||
FAKETIME_PROGS="date makensis zip"
|
||||
|
||||
@@ -83,7 +84,7 @@ script: |
|
||||
mkdir -p temp
|
||||
pushd temp
|
||||
tar xf ../$SOURCEDIST
|
||||
find bitcoin-* | sort | tar --no-recursion -c -T - | gzip -9n > ../$SOURCEDIST
|
||||
find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST
|
||||
popd
|
||||
|
||||
ORIGPATH="$PATH"
|
||||
@@ -106,7 +107,7 @@ script: |
|
||||
find . -name "lib*.la" -delete
|
||||
find . -name "lib*.a" -delete
|
||||
rm -rf ${DISTNAME}/lib/pkgconfig
|
||||
find . -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip
|
||||
find ${DISTNAME} -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip
|
||||
cd ../..
|
||||
done
|
||||
mkdir -p $OUTDIR/src
|
||||
|
||||
Binary file not shown.
@@ -3,7 +3,7 @@ name: bitcoin
|
||||
urls:
|
||||
- http://bitcoin.org/bitcoin-latest-linux-gitian.zip
|
||||
rss:
|
||||
- url: http://sourceforge.net/api/file/index/project-id/244765/mtime/desc/limit/100/rss
|
||||
- url:
|
||||
xpath: //item/link/text()
|
||||
pattern: bitcoin-\d+.\d+.\d+-linux-gitian.zip
|
||||
signers:
|
||||
|
||||
@@ -3,7 +3,7 @@ name: bitcoin
|
||||
urls:
|
||||
- http://bitcoin.org/bitcoin-latest-win32-gitian.zip
|
||||
rss:
|
||||
- url: http://sourceforge.net/api/file/index/project-id/244765/mtime/desc/limit/100/rss
|
||||
- url:
|
||||
xpath: //item/link/text()
|
||||
pattern: bitcoin-\d+.\d+.\d+-win32-gitian.zip
|
||||
signers:
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
### Seeds ###
|
||||
|
||||
Utility to generate the pnSeed[] array that is compiled into the client
|
||||
(see [src/net.cpp](/src/net.cpp)).
|
||||
Utility to generate the seeds.txt list that is compiled into the client
|
||||
(see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and [share/seeds](/share/seeds)).
|
||||
|
||||
The 600 seeds compiled into the 0.8 release were created from sipa's DNS seed data, like this:
|
||||
The 512 seeds compiled into the 0.10 release were created from sipa's DNS seed data, like this:
|
||||
|
||||
curl -s http://bitcoin.sipa.be/seeds.txt | head -1000 | makeseeds.py
|
||||
|
||||
The input to makeseeds.py is assumed to be approximately sorted from most-reliable to least-reliable,
|
||||
with IP:port first on each line (lines that don't match IPv4:port are ignored).
|
||||
curl -s http://bitcoin.sipa.be/seeds.txt | makeseeds.py
|
||||
|
||||
@@ -1,32 +1,118 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Generate pnSeed[] from Pieter's DNS seeder
|
||||
# Generate seeds.txt from Pieter's DNS seeder
|
||||
#
|
||||
|
||||
NSEEDS=600
|
||||
NSEEDS=512
|
||||
|
||||
MAX_SEEDS_PER_ASN=2
|
||||
|
||||
MIN_BLOCKS = 337600
|
||||
|
||||
# These are hosts that have been observed to be behaving strangely (e.g.
|
||||
# aggressively connecting to every node).
|
||||
SUSPICIOUS_HOSTS = set([
|
||||
"130.211.129.106", "178.63.107.226",
|
||||
"83.81.130.26", "88.198.17.7", "148.251.238.178", "176.9.46.6",
|
||||
"54.173.72.127", "54.174.10.182", "54.183.64.54", "54.194.231.211",
|
||||
"54.66.214.167", "54.66.220.137", "54.67.33.14", "54.77.251.214",
|
||||
"54.94.195.96", "54.94.200.247"
|
||||
])
|
||||
|
||||
import re
|
||||
import sys
|
||||
from subprocess import check_output
|
||||
import dns.resolver
|
||||
|
||||
PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):8333$")
|
||||
PATTERN_AGENT = re.compile(r"^(\/Satoshi:0.8.6\/|\/Satoshi:0.9.(2|3)\/|\/Satoshi:0.10.\d{1,2}\/)$")
|
||||
|
||||
def parseline(line):
|
||||
sline = line.split()
|
||||
if len(sline) < 11:
|
||||
return None
|
||||
# Match only IPv4
|
||||
m = PATTERN_IPV4.match(sline[0])
|
||||
if m is None:
|
||||
return None
|
||||
# Do IPv4 sanity check
|
||||
ip = 0
|
||||
for i in range(0,4):
|
||||
if int(m.group(i+2)) < 0 or int(m.group(i+2)) > 255:
|
||||
return None
|
||||
ip = ip + (int(m.group(i+2)) << (8*(3-i)))
|
||||
if ip == 0:
|
||||
return None
|
||||
# Skip bad results.
|
||||
if sline[1] == 0:
|
||||
return None
|
||||
# Extract uptime %.
|
||||
uptime30 = float(sline[7][:-1])
|
||||
# Extract Unix timestamp of last success.
|
||||
lastsuccess = int(sline[2])
|
||||
# Extract protocol version.
|
||||
version = int(sline[10])
|
||||
# Extract user agent.
|
||||
agent = sline[11][1:-1]
|
||||
# Extract service flags.
|
||||
service = int(sline[9], 16)
|
||||
# Extract blocks.
|
||||
blocks = int(sline[8])
|
||||
# Construct result.
|
||||
return {
|
||||
'ip': m.group(1),
|
||||
'ipnum': ip,
|
||||
'uptime': uptime30,
|
||||
'lastsuccess': lastsuccess,
|
||||
'version': version,
|
||||
'agent': agent,
|
||||
'service': service,
|
||||
'blocks': blocks,
|
||||
}
|
||||
|
||||
# Based on Greg Maxwell's seed_filter.py
|
||||
def filterbyasn(ips, max_per_asn, max_total):
|
||||
result = []
|
||||
asn_count = {}
|
||||
for ip in ips:
|
||||
if len(result) == max_total:
|
||||
break
|
||||
try:
|
||||
asn = int([x.to_text() for x in dns.resolver.query('.'.join(reversed(ip['ip'].split('.'))) + '.origin.asn.cymru.com', 'TXT').response.answer][0].split('\"')[1].split(' ')[0])
|
||||
if asn not in asn_count:
|
||||
asn_count[asn] = 0
|
||||
if asn_count[asn] == max_per_asn:
|
||||
continue
|
||||
asn_count[asn] += 1
|
||||
result.append(ip)
|
||||
except:
|
||||
sys.stderr.write('ERR: Could not resolve ASN for "' + ip['ip'] + '"\n')
|
||||
return result
|
||||
|
||||
def main():
|
||||
lines = sys.stdin.readlines()
|
||||
ips = [parseline(line) for line in lines]
|
||||
|
||||
ips = []
|
||||
pattern = re.compile(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):8333")
|
||||
for line in lines:
|
||||
m = pattern.match(line)
|
||||
if m is None:
|
||||
continue
|
||||
ip = 0
|
||||
for i in range(0,4):
|
||||
ip = ip + (int(m.group(i+1)) << (8*(i)))
|
||||
if ip == 0:
|
||||
continue
|
||||
ips.append(ip)
|
||||
# Skip entries with valid IPv4 address.
|
||||
ips = [ip for ip in ips if ip is not None]
|
||||
# Skip entries from suspicious hosts.
|
||||
ips = [ip for ip in ips if ip['ip'] not in SUSPICIOUS_HOSTS]
|
||||
# Enforce minimal number of blocks.
|
||||
ips = [ip for ip in ips if ip['blocks'] >= MIN_BLOCKS]
|
||||
# Require service bit 1.
|
||||
ips = [ip for ip in ips if (ip['service'] & 1) == 1]
|
||||
# Require at least 50% 30-day uptime.
|
||||
ips = [ip for ip in ips if ip['uptime'] > 50]
|
||||
# Require a known and recent user agent.
|
||||
ips = [ip for ip in ips if PATTERN_AGENT.match(ip['agent'])]
|
||||
# Sort by availability (and use last success as tie breaker)
|
||||
ips.sort(key=lambda x: (x['uptime'], x['lastsuccess'], x['ip']), reverse=True)
|
||||
# Look up ASNs and limit results, both per ASN and globally.
|
||||
ips = filterbyasn(ips, MAX_SEEDS_PER_ASN, NSEEDS)
|
||||
# Sort the results by IP address (for deterministic output).
|
||||
ips.sort(key=lambda x: (x['ipnum']))
|
||||
|
||||
for row in range(0, min(NSEEDS,len(ips)), 8):
|
||||
print " " + ", ".join([ "0x%08x"%i for i in ips[row:row+8] ]) + ","
|
||||
for ip in ips:
|
||||
print ip['ip']
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -31,6 +31,7 @@ endif
|
||||
|
||||
base_build_dir=$(BASEDIR)/work/build
|
||||
base_staging_dir=$(BASEDIR)/work/staging
|
||||
base_download_dir=$(BASEDIR)/work/download
|
||||
canonical_host:=$(shell ./config.sub $(HOST))
|
||||
build:=$(shell ./config.sub $(BUILD))
|
||||
|
||||
@@ -122,5 +123,12 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_
|
||||
$(AT)touch $@
|
||||
|
||||
install: $(host_prefix)/share/config.site
|
||||
download: $(all_sources)
|
||||
.PHONY: install cached
|
||||
download-one: $(all_sources)
|
||||
download-osx:
|
||||
@$(MAKE) -s HOST=x86_64-apple-darwin11 download-one
|
||||
download-linux:
|
||||
@$(MAKE) -s HOST=x86_64-unknown-linux-gnu download-one
|
||||
download-win:
|
||||
@$(MAKE) -s HOST=x86_64-w64-mingw32 download-one
|
||||
download: download-osx download-linux download-win
|
||||
.PHONY: install cached download-one download-osx download-linux download-win download
|
||||
|
||||
@@ -29,4 +29,7 @@ If some packages are not built, for example 'make NO_WALLET=1', the appropriate
|
||||
options will be passed to bitcoin's configure. In this case, --disable-wallet.
|
||||
|
||||
Additional targets:
|
||||
download: run 'make download' to fetch sources without building them
|
||||
download: run 'make download' to fetch all sources without building them
|
||||
download-osx: run 'make download-osx' to fetch all sources needed for osx builds
|
||||
download-win: run 'make download-win' to fetch all sources needed for win builds
|
||||
download-linux: run 'make download-linux' to fetch all sources needed for linux builds
|
||||
|
||||
@@ -7,7 +7,7 @@ build_darwin_OTOOL: = $(shell xcrun -f otool)
|
||||
build_darwin_NM: = $(shell xcrun -f nm)
|
||||
build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool)
|
||||
build_darwin_SHA256SUM = shasum -a 256
|
||||
build_darwin_DOWNLOAD = curl --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o
|
||||
build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o
|
||||
|
||||
#darwin host on darwin builder. overrides darwin host preferences.
|
||||
darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
build_linux_SHA256SUM = sha256sum
|
||||
build_linux_DOWNLOAD = wget --timeout=$(DOWNLOAD_CONNECT_TIMEOUT) --tries=$(DOWNLOAD_RETRIES) -nv -O
|
||||
build_linux_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o
|
||||
|
||||
2
depends/config.guess
vendored
2
depends/config.guess
vendored
@@ -1099,7 +1099,7 @@ EOF
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i586.
|
||||
# Note: whatever this is, it MUST be the same as what config.sub
|
||||
# prints for the "djgpp" host, or else GDB configury will decide that
|
||||
# prints for the "djgpp" host, or else GDB configure will decide that
|
||||
# this is a cross-build.
|
||||
echo i586-pc-msdosdjgpp
|
||||
exit ;;
|
||||
|
||||
@@ -20,18 +20,19 @@ $(sort $(foreach dep,$(2),$(2) $(call int_get_all_dependencies,$(1),$($(dep)_dep
|
||||
endef
|
||||
|
||||
define fetch_file
|
||||
(test -f $(SOURCES_PATH)/$(4) || \
|
||||
( mkdir -p $$($(1)_extract_dir) && \
|
||||
( $(build_DOWNLOAD) "$$($(1)_extract_dir)/$(4).temp" "$(2)/$(3)" || \
|
||||
$(build_DOWNLOAD) "$$($(1)_extract_dir)/$(4).temp" "$(FALLBACK_DOWNLOAD_PATH)/$(3)" ) && \
|
||||
echo "$(5) $$($(1)_extract_dir)/$(4).temp" > $$($(1)_extract_dir)/.$(4).hash && \
|
||||
$(build_SHA256SUM) -c $$($(1)_extract_dir)/.$(4).hash && \
|
||||
mv $$($(1)_extract_dir)/$(4).temp $(SOURCES_PATH)/$(4) ))
|
||||
(test -f $$($(1)_source_dir)/$(4) || \
|
||||
( mkdir -p $$($(1)_download_dir) && echo Fetching $(1)... && \
|
||||
( $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(2)/$(3)" || \
|
||||
$(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(FALLBACK_DOWNLOAD_PATH)/$(3)" ) && \
|
||||
echo "$(5) $$($(1)_download_dir)/$(4).temp" > $$($(1)_download_dir)/.$(4).hash && \
|
||||
$(build_SHA256SUM) -c $$($(1)_download_dir)/.$(4).hash && \
|
||||
mv $$($(1)_download_dir)/$(4).temp $$($(1)_source_dir)/$(4) && \
|
||||
rm -rf $$($(1)_download_dir) ))
|
||||
endef
|
||||
|
||||
define int_get_build_recipe_hash
|
||||
$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches))))
|
||||
$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | $(build_SHA256SUM)))
|
||||
$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches)) | cut -d" " -f1))
|
||||
$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | $(build_SHA256SUM) | cut -d" " -f1))
|
||||
endef
|
||||
|
||||
define int_get_build_id
|
||||
@@ -45,17 +46,19 @@ final_build_id_long+=$($(package)_build_id_long)
|
||||
#compute package-specific paths
|
||||
$(1)_build_subdir?=.
|
||||
$(1)_download_file?=$($(1)_file_name)
|
||||
$(1)_source:=$(SOURCES_PATH)/$($(1)_file_name)
|
||||
$(1)_source_dir:=$(SOURCES_PATH)
|
||||
$(1)_source:=$$($(1)_source_dir)/$($(1)_file_name)
|
||||
$(1)_staging_dir=$(base_staging_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)
|
||||
$(1)_staging_prefix_dir:=$$($(1)_staging_dir)$($($(1)_type)_prefix)
|
||||
$(1)_extract_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)
|
||||
$(1)_download_dir:=$(base_download_dir)/$(1)-$($(1)_version)
|
||||
$(1)_build_dir:=$$($(1)_extract_dir)/$$($(1)_build_subdir)
|
||||
$(1)_patch_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)/.patches-$($(1)_build_id)
|
||||
$(1)_prefixbin:=$($($(1)_type)_prefix)/bin/
|
||||
$(1)_cached:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz
|
||||
|
||||
#stamps
|
||||
$(1)_fetched=$$($(1)_extract_dir)/.stamp_fetched
|
||||
$(1)_fetched=$$($(1)_source_dir)/download-stamps/.stamp_fetched-$(1)-$($(1)_file_name)
|
||||
$(1)_extracted=$$($(1)_extract_dir)/.stamp_extracted
|
||||
$(1)_preprocessed=$$($(1)_extract_dir)/.stamp_preprocessed
|
||||
$(1)_cleaned=$$($(1)_extract_dir)/.stamp_cleaned
|
||||
@@ -150,7 +153,6 @@ endef
|
||||
|
||||
define int_add_cmds
|
||||
$($(1)_fetched):
|
||||
$(AT)echo Fetching $(1)...
|
||||
$(AT)mkdir -p $$(@D) $(SOURCES_PATH)
|
||||
$(AT)cd $$(@D); $(call $(1)_fetch_cmds,$(1))
|
||||
$(AT)touch $$@
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package=miniupnpc
|
||||
$(package)_version=1.9.20140701
|
||||
$(package)_version=1.9.20151008
|
||||
$(package)_download_path=http://miniupnp.free.fr/files
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=26f3985bad7768b8483b793448ae49414cdc4451d0ec83e7c1944367e15f9f07
|
||||
$(package)_sha256_hash=e444ac3b587ce82709c4d0cfca1fe71f44f9fc433e9f946b12b9e1bfe667a633
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_build_opts=CC="$($(package)_cc)"
|
||||
|
||||
@@ -39,11 +39,11 @@ $(package)_ldflags+=-m32 -Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib
|
||||
$(package)_ldflags+=-L$$(native_cctools_extract_dir)/clang+llvm-3.2-x86-linux-ubuntu-12.04/lib
|
||||
endef
|
||||
define $(package)_extract_cmds
|
||||
tar --strip-components=1 -xf $(SOURCES_PATH)/$($(package)_toolchain4_file_name) && \
|
||||
tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_toolchain4_file_name) && \
|
||||
ln -sf $($(package)_source) cctools2odcctools/$($(package)_file_name) && \
|
||||
ln -sf $(SOURCES_PATH)/$($(package)_ld64_file_name) cctools2odcctools/$($(package)_ld64_file_name) && \
|
||||
ln -sf $(SOURCES_PATH)/$($(package)_dyld_file_name) cctools2odcctools/$($(package)_dyld_file_name) && \
|
||||
tar xf $(SOURCES_PATH)/$($(package)_clang_file_name) && \
|
||||
ln -sf $($(package)_source_dir)/$($(package)_ld64_file_name) cctools2odcctools/$($(package)_ld64_file_name) && \
|
||||
ln -sf $($(package)_source_dir)/$($(package)_dyld_file_name) cctools2odcctools/$($(package)_dyld_file_name) && \
|
||||
tar xf $($(package)_source_dir)/$($(package)_clang_file_name) && \
|
||||
mkdir -p $(SDK_PATH) sdks &&\
|
||||
cd sdks; ln -sf $(OSX_SDK) MacOSX$(OSX_SDK_VERSION).sdk
|
||||
endef
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package=native_cdrkit
|
||||
$(package)_version=1.1.11
|
||||
$(package)_download_path=http://distro.ibiblio.org/fatdog/source/c
|
||||
$(package)_download_path=http://distro.ibiblio.org/fatdog/source/600/c
|
||||
$(package)_file_name=cdrkit-$($(package)_version).tar.bz2
|
||||
$(package)_sha256_hash=b50d64c214a65b1a79afe3a964c691931a4233e2ba605d793eb85d0ac3652564
|
||||
$(package)_patches=cdrkit-deterministic.patch
|
||||
|
||||
@@ -17,5 +17,5 @@ endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
mkdir -p $($(package)_staging_prefix_dir)/share/$($(package)_install_dirname) && \
|
||||
mv $(SOURCES_PATH)/$($(package)_file_name) $($(package)_staging_prefix_dir)/share/$($(package)_install_dirname)/$($(package)_install_filename)
|
||||
cp $($(package)_source) $($(package)_staging_prefix_dir)/share/$($(package)_install_dirname)/$($(package)_install_filename)
|
||||
endef
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package=openssl
|
||||
$(package)_version=1.0.1j
|
||||
$(package)_version=1.0.1k
|
||||
$(package)_download_path=https://www.openssl.org/source
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=1b60ca8789ba6f03e8ef20da2293b8dc131c39d83814e775069f02d26354edf3
|
||||
$(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fcebe7a41c
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
|
||||
@@ -10,7 +10,7 @@ $(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/o
|
||||
$(package)_config_opts+=no-krb5 no-camellia no-capieng no-cast no-cms no-dtls1 no-gost no-gmp no-heartbeats no-idea no-jpake no-md2
|
||||
$(package)_config_opts+=no-mdc2 no-rc5 no-rdrand no-rfc3779 no-rsax no-sctp no-seed no-sha0 no-static_engine no-whirlpool no-rc2 no-rc4 no-ssl2 no-ssl3
|
||||
$(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags)
|
||||
$(package)_config_opts_linux=-fPIC
|
||||
$(package)_config_opts_linux=-fPIC -Wa,--noexecstack
|
||||
$(package)_config_opts_x86_64_linux=linux-x86_64
|
||||
$(package)_config_opts_i686_linux=linux-generic32
|
||||
$(package)_config_opts_arm_linux=linux-generic32
|
||||
@@ -20,7 +20,7 @@ $(package)_config_opts_i686_mingw32=mingw
|
||||
endef
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
sed -i.old "/define DATE/d" crypto/Makefile && \
|
||||
sed -i.old "/define DATE/d" util/mkbuildinf.pl && \
|
||||
sed -i.old "s|engines apps test|engines|" Makefile.org
|
||||
endef
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ PROJECT_NAME = Bitcoin
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 0.9.99
|
||||
PROJECT_NUMBER = 0.10.4
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
Bitcoin 0.9.99 BETA
|
||||
Bitcoin Core 0.10.4
|
||||
=====================
|
||||
|
||||
Copyright (c) 2009-2014 Bitcoin Developers
|
||||
|
||||
|
||||
Setup
|
||||
---------------------
|
||||
[Bitcoin Core](http://bitcoin.org/en/download) is the original Bitcoin client and it builds the backbone of the network. However, it downloads and stores the entire history of Bitcoin transactions (which is currently several GBs); depending on the speed of your computer and network connection, the synchronization process can take anywhere from a few hours to a day or more. Thankfully you only have to do this once. If you would like the process to go faster you can [download the blockchain directly](bootstrap.md).
|
||||
|
||||
Running
|
||||
---------------------
|
||||
The following are some helpful notes on how to run Bitcoin on your native platform.
|
||||
The following are some helpful notes on how to run Bitcoin on your native platform.
|
||||
|
||||
### Unix
|
||||
|
||||
@@ -29,7 +26,7 @@ Unpack the files into a directory and run:
|
||||
|
||||
Unpack the files into a directory, and then run bitcoin-qt.exe.
|
||||
|
||||
### OSX
|
||||
### OS X
|
||||
|
||||
Drag Bitcoin-Qt to your applications folder, and then run Bitcoin-Qt.
|
||||
|
||||
@@ -44,7 +41,7 @@ Building
|
||||
---------------------
|
||||
The following are developer notes on how to build Bitcoin on your native platform. They are not complete guides, but include notes on the necessary libraries, compile flags, etc.
|
||||
|
||||
- [OSX Build Notes](build-osx.md)
|
||||
- [OS X Build Notes](build-osx.md)
|
||||
- [Unix Build Notes](build-unix.md)
|
||||
|
||||
Development
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
Deterministic OSX Dmg Notes.
|
||||
Deterministic OS X Dmg Notes.
|
||||
|
||||
Working OSX DMG's are created in Linux by combining a recent clang,
|
||||
Working OS X DMGs are created in Linux by combining a recent clang,
|
||||
the Apple's binutils (ld, ar, etc), and DMG authoring tools.
|
||||
|
||||
Apple uses clang extensively for development and has upstreamed the necessary
|
||||
functionality so that a vanilla clang can take advantage. It supports the use
|
||||
of -F, -target, -mmacosx-version-min, and --sysroot, which are all necessary
|
||||
when building for OSX. A pre-compiled version of 3.2 is used because it was not
|
||||
when building for OS X. A pre-compiled version of 3.2 is used because it was not
|
||||
available in the Precise repositories at the time this work was started. In the
|
||||
future, it can be switched to use system packages instead.
|
||||
|
||||
@@ -35,11 +35,11 @@ This file is several gigabytes in size, but only a single directory inside is
|
||||
needed: Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk
|
||||
|
||||
Unfortunately, the usual linux tools (7zip, hpmount, loopback mount) are incapable of opening this file.
|
||||
To create a tarball suitable for gitian input, mount the dmg in OSX, then create it with:
|
||||
To create a tarball suitable for Gitian input, mount the dmg in OS X, then create it with:
|
||||
$ tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.7.sdk.tar.gz MacOSX10.7.sdk
|
||||
|
||||
|
||||
The gitian descriptors build 2 sets of files: Linux tools, then Apple binaries
|
||||
The Gitian descriptors build 2 sets of files: Linux tools, then Apple binaries
|
||||
which are created using these tools. The build process has been designed to
|
||||
avoid including the SDK's files in Gitian's outputs. All interim tarballs are
|
||||
fully deterministic and may be freely redistributed.
|
||||
@@ -63,20 +63,20 @@ Ideally, the creation could be fixed and genisoimage would no longer be necessar
|
||||
|
||||
Background images and other features can be added to DMG files by inserting a
|
||||
.DS_Store before creation. The easiest way to create this file is to build a
|
||||
DMG without one, move it to a device running OSX, customize the layout, then
|
||||
DMG without one, move it to a device running OS X, customize the layout, then
|
||||
grab the .DS_Store file for later use. That is the approach taken here.
|
||||
|
||||
As of OSX Mavericks (10.9), using an Apple-blessed key to sign binaries is a
|
||||
As of OS X Mavericks (10.9), using an Apple-blessed key to sign binaries is a
|
||||
requirement in order to satisfy the new Gatekeeper requirements. Because this
|
||||
private key cannot be shared, we'll have to be a bit creative in order for the
|
||||
build process to remain somewhat deterministic. Here's how it works:
|
||||
|
||||
- Builders use gitian to create an unsigned release. This outputs an unsigned
|
||||
- Builders use Gitian to create an unsigned release. This outputs an unsigned
|
||||
dmg which users may choose to bless and run. It also outputs an unsigned app
|
||||
structure in the form of a tarball, which also contains all of the tools
|
||||
that have been previously (deterministically) built in order to create a
|
||||
final dmg.
|
||||
- The Apple keyholder uses this unsigned app to create a detached signature,
|
||||
using the script that is also included there.
|
||||
- Builders feed the unsigned app + detached signature back into gitian. It
|
||||
- Builders feed the unsigned app + detached signature back into Gitian. It
|
||||
uses the pre-built tools to recombine the pieces into a deterministic dmg.
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
Bitcoin 0.9.99 BETA
|
||||
|
||||
Copyright (c) 2009-2014 Bitcoin Core Developers
|
||||
|
||||
Distributed under the MIT/X11 software license, see the accompanying
|
||||
file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
This product includes software developed by the OpenSSL Project for use in
|
||||
the OpenSSL Toolkit (https://www.openssl.org/). This product includes
|
||||
cryptographic software written by Eric Young (eay@cryptsoft.com).
|
||||
|
||||
Bitcoin Core 0.10.4
|
||||
=====================
|
||||
|
||||
Intro
|
||||
-----
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Mac OS X Build Instructions and Notes
|
||||
====================================
|
||||
This guide will show you how to build bitcoind(headless client) for OSX.
|
||||
This guide will show you how to build bitcoind(headless client) for OS X.
|
||||
|
||||
Notes
|
||||
-----
|
||||
@@ -13,8 +13,8 @@ built-in one is located in `/Applications/Utilities`.
|
||||
Preparation
|
||||
-----------
|
||||
|
||||
You need to install XCode with all the options checked so that the compiler
|
||||
and everything is available in /usr not just /Developer. XCode should be
|
||||
You need to install Xcode with all the options checked so that the compiler
|
||||
and everything is available in /usr not just /Developer. Xcode should be
|
||||
available on your OS X installation media, but if not, you can get the
|
||||
current version from https://developer.apple.com/xcode/. If you install
|
||||
Xcode 4.3 or later, you'll need to install its command line tools. This can
|
||||
@@ -65,7 +65,7 @@ After exiting, you'll get a warning that the install is keg-only, which means it
|
||||
|
||||
### Building `bitcoind`
|
||||
|
||||
1. Clone the github tree to get the source code and go into the directory.
|
||||
1. Clone the GitHub tree to get the source code and go into the directory.
|
||||
|
||||
git clone https://github.com/bitcoin/bitcoin.git
|
||||
cd bitcoin
|
||||
@@ -89,7 +89,7 @@ Use Qt Creator as IDE
|
||||
You can use Qt Creator as IDE, for debugging and for manipulating forms, etc.
|
||||
Download Qt Creator from http://www.qt.io/download/. Download the "community edition" and only install Qt Creator (uncheck the rest during the installation process).
|
||||
|
||||
1. Make sure you installed everything through homebrew mentioned above
|
||||
1. Make sure you installed everything through Homebrew mentioned above
|
||||
2. Do a proper ./configure --with-gui=qt5 --enable-debug
|
||||
3. In Qt Creator do "New Project" -> Import Project -> Import Existing Project
|
||||
4. Enter "bitcoin-qt" as project name, enter src/qt as location
|
||||
|
||||
@@ -57,7 +57,7 @@ As Doxygen recognizes the comments by the delimiters (`/**` and `*/` in this cas
|
||||
|
||||
To describe a class use the same construct above the class definition:
|
||||
```c++
|
||||
/**
|
||||
/**
|
||||
* Alerts are for notifying old versions if they become too obsolete and
|
||||
* need to upgrade. The message is displayed in the status bar.
|
||||
* @see GetWarnings()
|
||||
|
||||
@@ -45,7 +45,8 @@ related to the DNS seed operation.
|
||||
|
||||
If these expectations cannot be satisfied the operator should
|
||||
discontinue providing services and contact the active Bitcoin
|
||||
Core development team as well as posting on bitcoin-development.
|
||||
Core development team as well as posting on
|
||||
[bitcoin-dev](https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev).
|
||||
|
||||
Behavior outside of these expectations may be reasonable in some
|
||||
situations but should be discussed in public in advance.
|
||||
|
||||
12
doc/files.md
12
doc/files.md
@@ -1,12 +1,16 @@
|
||||
Used in 0.8.0
|
||||
---------------------
|
||||
* wallet.dat: personal wallet (BDB) with keys and transactions
|
||||
* peers.dat: peer IP address database (custom format); since 0.7.0
|
||||
|
||||
* bitcoin.conf: contains configuration settings for bitcoind or bitcoin-qt
|
||||
* bitcoind.pid: stores the process id of bitcoind while running
|
||||
* blocks/blk000??.dat: block data (custom, 128 MiB per file); since 0.8.0
|
||||
* blocks/rev000??.dat; block undo data (custom); since 0.8.0 (format changed since pre-0.8)
|
||||
* blocks/index/*; block index (LevelDB); since 0.8.0
|
||||
* chainstate/*; block chain state database (LevelDB); since 0.8.0
|
||||
* database/*: BDB database environment; only used for wallet since 0.8.0
|
||||
* db.log: wallet database log file
|
||||
* debug.log: contains debug information and general logging generated by bitcoind or bitcoin-qt
|
||||
* fee_estimates.dat: stores statistics used to estimate minimum transaction fees and priorities required for confirmation; since 0.10.0
|
||||
* peers.dat: peer IP address database (custom format); since 0.7.0
|
||||
* wallet.dat: personal wallet (BDB) with keys and transactions
|
||||
|
||||
Only used in pre-0.8.0
|
||||
---------------------
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Gitian building
|
||||
================
|
||||
|
||||
*Setup instructions for a gitian build of Bitcoin using a Debian VM or physical system.*
|
||||
*Setup instructions for a Gitian build of Bitcoin using a Debian VM or physical system.*
|
||||
|
||||
Gitian is the deterministic build process that is used to build the Bitcoin
|
||||
Core executables. It provides a way to be reasonably sure that the
|
||||
@@ -13,7 +13,7 @@ Multiple developers build the source code by following a specific descriptor
|
||||
These results are compared and only if they match, the build is accepted and uploaded
|
||||
to bitcoin.org.
|
||||
|
||||
More independent gitian builders are needed, which is why I wrote this
|
||||
More independent Gitian builders are needed, which is why I wrote this
|
||||
guide. It is preferred to follow these steps yourself instead of using someone else's
|
||||
VM image to avoid 'contaminating' the build.
|
||||
|
||||
@@ -22,9 +22,9 @@ Table of Contents
|
||||
|
||||
- [Create a new VirtualBox VM](#create-a-new-virtualbox-vm)
|
||||
- [Connecting to the VM](#connecting-to-the-vm)
|
||||
- [Setting up Debian for gitian building](#setting-up-debian-for-gitian-building)
|
||||
- [Installing gitian](#installing-gitian)
|
||||
- [Setting up gitian images](#setting-up-gitian-images)
|
||||
- [Setting up Debian for Gitian building](#setting-up-debian-for-gitian-building)
|
||||
- [Installing Gitian](#installing-gitian)
|
||||
- [Setting up Gitian images](#setting-up-gitian-images)
|
||||
- [Getting and building the inputs](#getting-and-building-the-inputs)
|
||||
- [Building Bitcoin](#building-bitcoin)
|
||||
- [Building an alternative repository](#building-an-alternative-repository)
|
||||
@@ -60,28 +60,28 @@ In the VirtualBox GUI click "Create" and choose the following parameters in the
|
||||

|
||||
|
||||
- Hard Drive: Create a virtual hard drive now
|
||||
|
||||
|
||||

|
||||
|
||||
- Hard Drive file type: Use the default, VDI (VirtualBox Disk Image)
|
||||
- Hard Drive file type: Use the default, VDI (VirtualBox Disk Image)
|
||||
|
||||

|
||||
|
||||
- Storage on Physical hard drive: Dynamically Allocated
|
||||
|
||||
|
||||
- Storage on Physical hard drive: Dynamically Allocated
|
||||
|
||||

|
||||
|
||||
- Disk size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side
|
||||
- Disk size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side
|
||||
- Push the `Create` button
|
||||
|
||||
Get the [Debian 7.4 net installer](http://ftp.at.debian.org/debian-jigdo/current/amd64/iso-cd/debian-7.4.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)).
|
||||
Get the [Debian 7.8 net installer](http://cdimage.debian.org/cdimage/archive/7.8.0/amd64/iso-cd/debian-7.8.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)).
|
||||
This DVD image can be validated using a SHA256 hashing tool, for example on
|
||||
Unixy OSes by entering the following in a terminal:
|
||||
|
||||
echo "b712a141bc60269db217d3b3e456179bd6b181645f90e4aac9c42ed63de492e9 debian-7.4.0-amd64-netinst.iso" | sha256sum -c
|
||||
# (must return OK)
|
||||
|
||||
After creating the VM, we need to configure it.
|
||||
After creating the VM, we need to configure it.
|
||||
|
||||
- Click the `Settings` button, then go to the `Network` tab. Adapter 1 should be attacked to `NAT`.
|
||||
|
||||
@@ -125,22 +125,22 @@ and proceed, just press `Enter`. To select a different button, press `Tab`.
|
||||

|
||||
|
||||
- The VM will detect network settings using DHCP, this should all proceed automatically
|
||||
- Configure the network:
|
||||
- Configure the network:
|
||||
- System name `debian`.
|
||||
- Leave domain name empty.
|
||||
|
||||

|
||||
|
||||
- Choose a root password and enter it twice (remember it for later)
|
||||
- Choose a root password and enter it twice (remember it for later)
|
||||
|
||||

|
||||
|
||||
- Name the new user `debian` (the full name doesn't matter, you can leave it empty)
|
||||
- Name the new user `debian` (the full name doesn't matter, you can leave it empty)
|
||||
|
||||

|
||||

|
||||
|
||||
- Choose a user password and enter it twice (remember it for later)
|
||||
- Choose a user password and enter it twice (remember it for later)
|
||||
|
||||

|
||||
|
||||
@@ -150,11 +150,11 @@ and proceed, just press `Enter`. To select a different button, press `Tab`.
|
||||

|
||||
|
||||
- Disk setup
|
||||
- Partitioning method: Guided - Use the entire disk
|
||||
|
||||
- Partitioning method: Guided - Use the entire disk
|
||||
|
||||

|
||||
|
||||
- Select disk to partition: SCSI1 (0,0,0)
|
||||
- Select disk to partition: SCSI1 (0,0,0)
|
||||
|
||||

|
||||
|
||||
@@ -168,7 +168,7 @@ and proceed, just press `Enter`. To select a different button, press `Tab`.
|
||||

|
||||
|
||||
- The base system will be installed, this will take a minute or so
|
||||
- Choose a mirror (any will do)
|
||||
- Choose a mirror (any will do)
|
||||
|
||||

|
||||
|
||||
@@ -217,7 +217,7 @@ Replace `root` with `debian` to log in as user.
|
||||
[1] http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
|
||||
[2] http://winscp.net/eng/index.php
|
||||
|
||||
Setting up Debian for gitian building
|
||||
Setting up Debian for Gitian building
|
||||
--------------------------------------
|
||||
|
||||
In this section we will be setting up the Debian installation for Gitian building.
|
||||
@@ -237,7 +237,7 @@ Then set up LXC and the rest with the following, which is a complex jumble of se
|
||||
|
||||
```bash
|
||||
# the version of lxc-start in Debian 7.4 needs to run as root, so make sure
|
||||
# that the build script can exectute it without providing a password
|
||||
# that the build script can execute it without providing a password
|
||||
echo "%sudo ALL=NOPASSWD: /usr/bin/lxc-start" > /etc/sudoers.d/gitian-lxc
|
||||
# add cgroup for LXC
|
||||
echo "cgroup /sys/fs/cgroup cgroup defaults 0 0" >> /etc/fstab
|
||||
@@ -257,7 +257,7 @@ reboot
|
||||
At the end the VM is rebooted to make sure that the changes take effect. The steps in this
|
||||
section need only to be performed once.
|
||||
|
||||
Installing gitian
|
||||
Installing Gitian
|
||||
------------------
|
||||
|
||||
Re-login as the user `debian` that was created during installation.
|
||||
@@ -277,7 +277,7 @@ cd ..
|
||||
|
||||
**Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*.
|
||||
|
||||
Clone the git repositories for bitcoin and gitian and then checkout the bitcoin version that you want to build.
|
||||
Clone the git repositories for bitcoin and Gitian and then checkout the bitcoin version that you want to build.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/devrandom/gitian-builder.git
|
||||
@@ -287,11 +287,11 @@ git checkout v${VERSION}
|
||||
cd ..
|
||||
```
|
||||
|
||||
Setting up gitian images
|
||||
Setting up Gitian images
|
||||
-------------------------
|
||||
|
||||
Gitian needs virtual images of the operating system to build in.
|
||||
Currently this is Ubuntu Precise for both x86 architectures.
|
||||
Currently this is Ubuntu Precise for x86_64.
|
||||
These images will be copied and used every time that a build is started to
|
||||
make sure that the build is deterministic.
|
||||
Creating the images will take a while, but only has to be done once.
|
||||
@@ -300,7 +300,6 @@ Execute the following as user `debian`:
|
||||
|
||||
```bash
|
||||
cd gitian-builder
|
||||
bin/make-base-vm --lxc --arch i386 --suite precise
|
||||
bin/make-base-vm --lxc --arch amd64 --suite precise
|
||||
```
|
||||
|
||||
@@ -311,33 +310,25 @@ There will be a lot of warnings printed during build of the images. These can be
|
||||
Getting and building the inputs
|
||||
--------------------------------
|
||||
|
||||
In [doc/release-process.md](release-process.md) in the bitcoin repository under 'Fetch and build inputs'.
|
||||
you will find a list of `wget` commands that can be executed to get the dependencies.
|
||||
Follow the instructions in [doc/release-process.md](release-process.md) in the bitcoin repository
|
||||
under 'Fetch and build inputs' to install sources which require manual intervention. Also follow
|
||||
the next step: 'Seed the Gitian sources cache', which will fetch all necessary source files allowing
|
||||
for Gitian to work offline.
|
||||
|
||||
I needed to add `--no-check-certificate` to the OpenSSL wget line to make it work.
|
||||
Likely this is because the ca-certificates in Debian 7.4 is fairly old. This does not create a
|
||||
security issue as the gitian descriptors check the integrity of the input archives and refuse to work
|
||||
if any one is corrupted.
|
||||
Building Bitcoin
|
||||
----------------
|
||||
|
||||
After downloading the archives, execute the `gbuild` commands to build the dependencies.
|
||||
This can take a long time, but only has to be done when the dependencies change, for example
|
||||
to upgrade the used version.
|
||||
To build Bitcoin (for Linux, OS X and Windows) just follow the steps under 'perform
|
||||
Gitian builds' in [doc/release-process.md](release-process.md) in the bitcoin repository.
|
||||
|
||||
**Note**: Do not forget to copy the result from `build/out` to `inputs` after every gbuild command! This will save
|
||||
you a lot of time.
|
||||
This may take a long time as it also builds the dependencies needed for each descriptor.
|
||||
These dependencies will be cached after a successful build to avoid rebuilding them when possible.
|
||||
|
||||
At any time you can check the package installation and build progress with
|
||||
|
||||
```bash
|
||||
tail -f var/install.log
|
||||
tail -f var/build.log
|
||||
```
|
||||
|
||||
Building Bitcoin
|
||||
----------------
|
||||
|
||||
To build Bitcoin (for Linux, OSX and Windows) just follow the steps under 'perform
|
||||
gitian builds' in [doc/release-process.md](release-process.md) in the bitcoin repository.
|
||||
|
||||
Output from `gbuild` will look something like
|
||||
|
||||
@@ -348,7 +339,7 @@ Output from `gbuild` will look something like
|
||||
Resolving deltas: 100% (25724/25724), done.
|
||||
From https://github.com/bitcoin/bitcoin
|
||||
... (new tags, new branch etc)
|
||||
--- Building for precise i386 ---
|
||||
--- Building for precise x86_64 ---
|
||||
Stopping target if it is up
|
||||
Making a new image copy
|
||||
stdin: is not a tty
|
||||
@@ -363,14 +354,11 @@ Output from `gbuild` will look something like
|
||||
lxc-start: Connection refused - inotify event with no name (mask 32768)
|
||||
Running build script (log in var/build.log)
|
||||
|
||||
As when building the dependencies, the progress of package installation and building
|
||||
can be inspected in `var/install.log` and `var/build.log`.
|
||||
|
||||
Building an alternative repository
|
||||
-----------------------------------
|
||||
|
||||
If you want to do a test build of a pull on GitHub it can be useful to point
|
||||
the gitian builder at an alternative repository, using the same descriptors
|
||||
the Gitian builder at an alternative repository, using the same descriptors
|
||||
and inputs.
|
||||
|
||||
For example:
|
||||
@@ -400,7 +388,7 @@ in `gitian.sigs` to your signing machine and do
|
||||
```
|
||||
|
||||
This will create the `.sig` files that can be committed together with the `.assert` files to assert your
|
||||
gitian build.
|
||||
Gitian build.
|
||||
|
||||
Uploading signatures
|
||||
---------------------
|
||||
|
||||
@@ -34,9 +34,8 @@ generate one from the shell yourself like this:
|
||||
|
||||
bash -c 'tr -dc a-zA-Z0-9 < /dev/urandom | head -c32 && echo'
|
||||
|
||||
Once you have a password in hand, set rpcpassword= in /etc/bitcoin/bitcoin.conf
|
||||
|
||||
For an example configuration file that describes the configuration settings,
|
||||
For an example configuration file that describes the configuration settings,
|
||||
see contrib/debian/examples/bitcoin.conf.
|
||||
|
||||
3. Paths
|
||||
@@ -81,7 +80,7 @@ Drop bitcoind.conf in /etc/init. Test by running "service bitcoind start"
|
||||
it will automatically start on reboot.
|
||||
|
||||
NOTE: This script is incompatible with CentOS 5 and Amazon Linux 2014 as they
|
||||
use old versions of Upstart and do not supply the start-stop-daemon uitility.
|
||||
use old versions of Upstart and do not supply the start-stop-daemon utility.
|
||||
|
||||
5. Auto-respawn
|
||||
-----------------------------------
|
||||
@@ -89,4 +88,3 @@ use old versions of Upstart and do not supply the start-stop-daemon uitility.
|
||||
Auto respawning is currently only configured for Upstart and systemd.
|
||||
Reasonable defaults have been chosen but YMMV.
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,32 @@
|
||||
(note: this is a temporary file, to be added-to by anybody, and moved to
|
||||
release-notes at release time)
|
||||
Bitcoin Core version 0.10.4 is now available from:
|
||||
|
||||
Block file backwards-compatibility warning
|
||||
===========================================
|
||||
<https://bitcoin.org/bin/bitcoin-core-0.10.4/>
|
||||
|
||||
Because release 0.10.0 makes use of headers-first synchronization and parallel
|
||||
block download, the block files and databases are not backwards-compatible
|
||||
with older versions of Bitcoin Core:
|
||||
This is a new minor version release, bringing bug fixes, the BIP65
|
||||
(CLTV) consensus change, and relay policy preparation for BIP113. It is
|
||||
recommended to upgrade to this version as soon as possible.
|
||||
|
||||
Please report bugs using the issue tracker at github:
|
||||
|
||||
<https://github.com/bitcoin/bitcoin/issues>
|
||||
|
||||
Upgrading and downgrading
|
||||
=========================
|
||||
|
||||
How to Upgrade
|
||||
--------------
|
||||
|
||||
If you are running an older version, shut it down. Wait until it has completely
|
||||
shut down (which might take a few minutes for older versions), then run the
|
||||
installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
|
||||
bitcoind/bitcoin-qt (on Linux).
|
||||
|
||||
Downgrade warning
|
||||
------------------
|
||||
|
||||
Because release 0.10.0 and later makes use of headers-first synchronization and
|
||||
parallel block download (see further), the block files and databases are not
|
||||
backwards-compatible with pre-0.10 versions of Bitcoin Core or other software:
|
||||
|
||||
* Blocks will be stored on disk out of order (in the order they are
|
||||
received, really), which makes it incompatible with some tools or
|
||||
@@ -18,109 +38,135 @@ stored on disk, which earlier versions won't support.
|
||||
|
||||
If you want to be able to downgrade smoothly, make a backup of your entire data
|
||||
directory. Without this your node will need start syncing (or importing from
|
||||
bootstrap.dat) anew afterwards.
|
||||
bootstrap.dat) anew afterwards. It is possible that the data from a completely
|
||||
synchronised 0.10 node may be usable in older versions as-is, but this is not
|
||||
supported and may break as soon as the older version attempts to reindex.
|
||||
|
||||
This does not affect wallet forward or backward compatibility.
|
||||
This does not affect wallet forward or backward compatibility. There are no
|
||||
known problems when downgrading from 0.11.x to 0.10.x.
|
||||
|
||||
Transaction fee changes
|
||||
=======================
|
||||
Notable changes since 0.10.3
|
||||
============================
|
||||
|
||||
This release automatically estimates how high a transaction fee (or how
|
||||
high a priority) transactions require to be confirmed quickly. The default
|
||||
settings will create transactions that confirm quickly; see the new
|
||||
'txconfirmtarget' setting to control the tradeoff between fees and
|
||||
confirmation times.
|
||||
BIP65 soft fork to enforce OP_CHECKLOCKTIMEVERIFY opcode
|
||||
--------------------------------------------------------
|
||||
|
||||
Prior releases used hard-coded fees (and priorities), and would
|
||||
sometimes create transactions that took a very long time to confirm.
|
||||
This release includes several changes related to the [BIP65][] soft fork
|
||||
which redefines the existing OP_NOP2 opcode as OP_CHECKLOCKTIMEVERIFY
|
||||
(CLTV) so that a transaction output can be made unspendable until a
|
||||
specified point in the future.
|
||||
|
||||
Statistics used to estimate fees and priorities are saved in the
|
||||
data directory in the `fee_estimates.dat` file just before
|
||||
program shutdown, and are read in at startup.
|
||||
1. This release will only relay and mine transactions spending a CLTV
|
||||
output if they comply with the BIP65 rules as provided in code.
|
||||
|
||||
New Command Line Options
|
||||
---------------------------
|
||||
2. This release will produce version 4 blocks by default. Please see the
|
||||
*notice to miners* below.
|
||||
|
||||
- `-txconfirmtarget=n` : create transactions that have enough fees (or priority)
|
||||
so they are likely to confirm within n blocks (default: 1). This setting
|
||||
is over-ridden by the -paytxfee option.
|
||||
3. Once 951 out of a sequence of 1,001 blocks on the local node's best block
|
||||
chain contain version 4 (or higher) blocks, this release will no
|
||||
longer accept new version 3 blocks and it will only accept version 4
|
||||
blocks if they comply with the BIP65 rules for CLTV.
|
||||
|
||||
New RPC methods
|
||||
----------------
|
||||
For more information about the soft-forking change, please see
|
||||
<https://github.com/bitcoin/bitcoin/pull/6351>
|
||||
|
||||
- `estimatefee nblocks` : Returns approximate fee-per-1,000-bytes needed for
|
||||
a transaction to be confirmed within nblocks. Returns -1 if not enough
|
||||
transactions have been observed to compute a good estimate.
|
||||
Graphs showing the progress towards block version 4 adoption may be
|
||||
found at the URLs below:
|
||||
|
||||
- `estimatepriority nblocks` : Returns approximate priority needed for
|
||||
a zero-fee transaction to confirm within nblocks. Returns -1 if not
|
||||
enough free transactions have been observed to compute a good
|
||||
estimate.
|
||||
- Block versions over the last 50,000 blocks as progress towards BIP65
|
||||
consensus enforcement: <http://bitcoin.sipa.be/ver-50k.png>
|
||||
|
||||
RPC access control changes
|
||||
==========================================
|
||||
- Block versions over the last 2,000 blocks showing the days to the
|
||||
earliest possible BIP65 consensus-enforced block: <http://bitcoin.sipa.be/ver-2k.png>
|
||||
|
||||
Subnet matching for the purpose of access control is now done
|
||||
by matching the binary network address, instead of with string wildcard matching.
|
||||
For the user this means that `-rpcallowip` takes a subnet specification, which can be
|
||||
**Notice to miners:** Bitcoin Core’s block templates are now for
|
||||
version 4 blocks only, and any mining software relying on its
|
||||
getblocktemplate must be updated in parallel to use libblkmaker either
|
||||
version FIXME or any version from FIXME onward.
|
||||
|
||||
- a single IP address (e.g. `1.2.3.4` or `fe80::0012:3456:789a:bcde`)
|
||||
- a network/CIDR (e.g. `1.2.3.0/24` or `fe80::0000/64`)
|
||||
- a network/netmask (e.g. `1.2.3.4/255.255.255.0` or `fe80::0012:3456:789a:bcde/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff`)
|
||||
- If you are solo mining, this will affect you the moment you upgrade
|
||||
Bitcoin Core, which must be done prior to BIP65 achieving its 951/1001
|
||||
status.
|
||||
|
||||
An arbitrary number of `-rpcallow` arguments can be given. An incoming connection will be accepted if its origin address
|
||||
matches one of them.
|
||||
- If you are mining with the stratum mining protocol: this does not
|
||||
affect you.
|
||||
|
||||
For example:
|
||||
- If you are mining with the getblocktemplate protocol to a pool: this
|
||||
will affect you at the pool operator’s discretion, which must be no
|
||||
later than BIP65 achieving its 951/1001 status.
|
||||
|
||||
| 0.9.x and before | 0.10.x |
|
||||
|--------------------------------------------|---------------------------------------|
|
||||
| `-rpcallowip=192.168.1.1` | `-rpcallowip=192.168.1.1` (unchanged) |
|
||||
| `-rpcallowip=192.168.1.*` | `-rpcallowip=192.168.1.0/24` |
|
||||
| `-rpcallowip=192.168.*` | `-rpcallowip=192.168.0.0/16` |
|
||||
| `-rpcallowip=*` (dangerous!) | `-rpcallowip=::/0` |
|
||||
[BIP65]: https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki
|
||||
|
||||
Using wildcards will result in the rule being rejected with the following error in debug.log:
|
||||
Windows bug fix for corrupted UTXO database on unclean shutdowns
|
||||
----------------------------------------------------------------
|
||||
|
||||
Error: Invalid -rpcallowip subnet specification: *. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).
|
||||
Several Windows users reported that they often need to reindex the
|
||||
entire blockchain after an unclean shutdown of Bitcoin Core on Windows
|
||||
(or an unclean shutdown of Windows itself). Although unclean shutdowns
|
||||
remain unsafe, this release no longer relies on memory-mapped files for
|
||||
the UTXO database, which significantly reduced the frequency of unclean
|
||||
shutdowns leading to required reindexes during testing.
|
||||
|
||||
RPC Server "Warm-Up" Mode
|
||||
=========================
|
||||
For more information, see: <https://github.com/bitcoin/bitcoin/pull/6917>
|
||||
|
||||
The RPC server is started earlier now, before most of the expensive
|
||||
intialisations like loading the block index. It is available now almost
|
||||
immediately after starting the process. However, until all initialisations
|
||||
are done, it always returns an immediate error with code -28 to all calls.
|
||||
Other fixes for database corruption on Windows are expected in the
|
||||
next major release.
|
||||
|
||||
This new behaviour can be useful for clients to know that a server is already
|
||||
started and will be available soon (for instance, so that they do not
|
||||
have to start it themselves).
|
||||
0.10.4 Change log
|
||||
=================
|
||||
|
||||
Improved signing security
|
||||
=========================
|
||||
Detailed release notes follow. This overview includes changes that affect
|
||||
behavior, not code moves, refactors and string updates. For convenience in locating
|
||||
the code changes and accompanying discussion, both the pull request and
|
||||
git merge commit are mentioned.
|
||||
|
||||
For 0.10 the security of signing against unusual attacks has been
|
||||
improved by making the signatures constant time and deterministic.
|
||||
- #6953 `8b3311f` alias -h for --help
|
||||
- #6953 `97546fc` Change URLs to https in debian/control
|
||||
- #6953 `38671bf` Update debian/changelog and slight tweak to debian/control
|
||||
- #6953 `256321e` Correct spelling mistakes in doc folder
|
||||
- #6953 `eae0350` Clarification of unit test build instructions
|
||||
- #6953 `90897ab` Update bluematt-key, the old one is long-since revoked
|
||||
- #6953 `a2f2fb6` build: disable -Wself-assign
|
||||
- #6953 `cf67d8b` Bugfix: Allow mining on top of old tip blocks for testnet (fixes testnet-in-a-box use case)
|
||||
- #6953 `b3964e3` Drop "with minimal dependencies" from description
|
||||
- #6953 `43c2789` Split bitcoin-tx into its own package
|
||||
- #6953 `dfe0d4d` Include bitcoin-tx binary on Debian/Ubuntu
|
||||
- #6953 `612efe8` [Qt] Raise debug window when requested
|
||||
- #6953 `3ad96bd` Fix locking in GetTransaction
|
||||
- #6953 `9c81005` Fix spelling of Qt
|
||||
- #6946 `94b67e5` Update LevelDB
|
||||
- #6706 `5dc72f8` CLTV: Add more tests to improve coverage
|
||||
- #6706 `6a1343b` Add RPC tests for the CHECKLOCKTIMEVERIFY (BIP65) soft-fork
|
||||
- #6706 `4137248` Add CHECKLOCKTIMEVERIFY (BIP65) soft-fork logic
|
||||
- #6706 `0e01d0f` Enable CHECKLOCKTIMEVERIFY as a standard script verify flag
|
||||
- #6706 `6d01325` Replace NOP2 with CHECKLOCKTIMEVERIFY (BIP65)
|
||||
- #6706 `750d54f` Move LOCKTIME_THRESHOLD to src/script/script.h
|
||||
- #6706 `6897468` Make CScriptNum() take nMaxNumSize as an argument
|
||||
- #6867 `5297194` Set TCP_NODELAY on P2P sockets
|
||||
- #6836 `fb818b6` Bring historical release notes up to date
|
||||
- #6852 `0b3fd07` build: make sure OpenSSL heeds noexecstack
|
||||
|
||||
This change is a result of switching signing to use libsecp256k1
|
||||
instead of OpenSSL. Libsecp256k1 is a cryptographic library
|
||||
optimized for the curve Bitcoin uses which was created by Bitcoin
|
||||
Core developer Pieter Wuille.
|
||||
Credits
|
||||
=======
|
||||
|
||||
There exist attacks[1] against most ECC implementations where an
|
||||
attacker on shared virtual machine hardware could extract a private
|
||||
key if they could cause a target to sign using the same key hundreds
|
||||
of times. While using shared hosts and reusing keys are inadvisable
|
||||
for other reasons, it's a better practice to avoid the exposure.
|
||||
Thanks to everyone who directly contributed to this release:
|
||||
|
||||
OpenSSL has code in their source repository for derandomization
|
||||
and reduction in timing leaks, and we've eagerly wanted to use
|
||||
it for a long time but this functionality has still not made its
|
||||
way into a released version of OpenSSL. Libsecp256k1 achieves
|
||||
significantly stronger protection: As far as we're aware this is
|
||||
the only deployed implementation of constant time signing for
|
||||
the curve Bitcoin uses and we have reason to believe that
|
||||
libsecp256k1 is better tested and more thoroughly reviewed
|
||||
than the implementation in OpenSSL.
|
||||
- Alex Morcos
|
||||
- Daniel Cousens
|
||||
- Diego Viola
|
||||
- Eric Lombrozo
|
||||
- Esteban Ordano
|
||||
- Gregory Maxwell
|
||||
- Luke Dashjr
|
||||
- MarcoFalke
|
||||
- Matt Corallo
|
||||
- Micha
|
||||
- Mitchell Cash
|
||||
- Peter Todd
|
||||
- Pieter Wuille
|
||||
- Wladimir J. van der Laan
|
||||
- Zak Wilcox
|
||||
|
||||
[1] https://eprint.iacr.org/2014/161.pdf
|
||||
And those who contributed additional code review and/or security research.
|
||||
|
||||
As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
|
||||
|
||||
762
doc/release-notes/release-notes-0.10.0.md
Normal file
762
doc/release-notes/release-notes-0.10.0.md
Normal file
@@ -0,0 +1,762 @@
|
||||
Bitcoin Core version 0.10.0 is now available from:
|
||||
|
||||
https://bitcoin.org/bin/0.10.0/
|
||||
|
||||
This is a new major version release, bringing both new features and
|
||||
bug fixes.
|
||||
|
||||
Please report bugs using the issue tracker at github:
|
||||
|
||||
https://github.com/bitcoin/bitcoin/issues
|
||||
|
||||
Upgrading and downgrading
|
||||
=========================
|
||||
|
||||
How to Upgrade
|
||||
--------------
|
||||
|
||||
If you are running an older version, shut it down. Wait until it has completely
|
||||
shut down (which might take a few minutes for older versions), then run the
|
||||
installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
|
||||
bitcoind/bitcoin-qt (on Linux).
|
||||
|
||||
Downgrading warning
|
||||
---------------------
|
||||
|
||||
Because release 0.10.0 makes use of headers-first synchronization and parallel
|
||||
block download (see further), the block files and databases are not
|
||||
backwards-compatible with older versions of Bitcoin Core or other software:
|
||||
|
||||
* Blocks will be stored on disk out of order (in the order they are
|
||||
received, really), which makes it incompatible with some tools or
|
||||
other programs. Reindexing using earlier versions will also not work
|
||||
anymore as a result of this.
|
||||
|
||||
* The block index database will now hold headers for which no block is
|
||||
stored on disk, which earlier versions won't support.
|
||||
|
||||
If you want to be able to downgrade smoothly, make a backup of your entire data
|
||||
directory. Without this your node will need start syncing (or importing from
|
||||
bootstrap.dat) anew afterwards. It is possible that the data from a completely
|
||||
synchronised 0.10 node may be usable in older versions as-is, but this is not
|
||||
supported and may break as soon as the older version attempts to reindex.
|
||||
|
||||
This does not affect wallet forward or backward compatibility.
|
||||
|
||||
|
||||
Notable changes
|
||||
===============
|
||||
|
||||
Faster synchronization
|
||||
----------------------
|
||||
|
||||
Bitcoin Core now uses 'headers-first synchronization'. This means that we first
|
||||
ask peers for block headers (a total of 27 megabytes, as of December 2014) and
|
||||
validate those. In a second stage, when the headers have been discovered, we
|
||||
download the blocks. However, as we already know about the whole chain in
|
||||
advance, the blocks can be downloaded in parallel from all available peers.
|
||||
|
||||
In practice, this means a much faster and more robust synchronization. On
|
||||
recent hardware with a decent network link, it can be as little as 3 hours
|
||||
for an initial full synchronization. You may notice a slower progress in the
|
||||
very first few minutes, when headers are still being fetched and verified, but
|
||||
it should gain speed afterwards.
|
||||
|
||||
A few RPCs were added/updated as a result of this:
|
||||
- `getblockchaininfo` now returns the number of validated headers in addition to
|
||||
the number of validated blocks.
|
||||
- `getpeerinfo` lists both the number of blocks and headers we know we have in
|
||||
common with each peer. While synchronizing, the heights of the blocks that we
|
||||
have requested from peers (but haven't received yet) are also listed as
|
||||
'inflight'.
|
||||
- A new RPC `getchaintips` lists all known branches of the block chain,
|
||||
including those we only have headers for.
|
||||
|
||||
Transaction fee changes
|
||||
-----------------------
|
||||
|
||||
This release automatically estimates how high a transaction fee (or how
|
||||
high a priority) transactions require to be confirmed quickly. The default
|
||||
settings will create transactions that confirm quickly; see the new
|
||||
'txconfirmtarget' setting to control the tradeoff between fees and
|
||||
confirmation times. Fees are added by default unless the 'sendfreetransactions'
|
||||
setting is enabled.
|
||||
|
||||
Prior releases used hard-coded fees (and priorities), and would
|
||||
sometimes create transactions that took a very long time to confirm.
|
||||
|
||||
Statistics used to estimate fees and priorities are saved in the
|
||||
data directory in the `fee_estimates.dat` file just before
|
||||
program shutdown, and are read in at startup.
|
||||
|
||||
New command line options for transaction fee changes:
|
||||
- `-txconfirmtarget=n` : create transactions that have enough fees (or priority)
|
||||
so they are likely to begin confirmation within n blocks (default: 1). This setting
|
||||
is over-ridden by the -paytxfee option.
|
||||
- `-sendfreetransactions` : Send transactions as zero-fee transactions if possible
|
||||
(default: 0)
|
||||
|
||||
New RPC commands for fee estimation:
|
||||
- `estimatefee nblocks` : Returns approximate fee-per-1,000-bytes needed for
|
||||
a transaction to begin confirmation within nblocks. Returns -1 if not enough
|
||||
transactions have been observed to compute a good estimate.
|
||||
- `estimatepriority nblocks` : Returns approximate priority needed for
|
||||
a zero-fee transaction to begin confirmation within nblocks. Returns -1 if not
|
||||
enough free transactions have been observed to compute a good
|
||||
estimate.
|
||||
|
||||
RPC access control changes
|
||||
--------------------------
|
||||
|
||||
Subnet matching for the purpose of access control is now done
|
||||
by matching the binary network address, instead of with string wildcard matching.
|
||||
For the user this means that `-rpcallowip` takes a subnet specification, which can be
|
||||
|
||||
- a single IP address (e.g. `1.2.3.4` or `fe80::0012:3456:789a:bcde`)
|
||||
- a network/CIDR (e.g. `1.2.3.0/24` or `fe80::0000/64`)
|
||||
- a network/netmask (e.g. `1.2.3.4/255.255.255.0` or `fe80::0012:3456:789a:bcde/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff`)
|
||||
|
||||
An arbitrary number of `-rpcallow` arguments can be given. An incoming connection will be accepted if its origin address
|
||||
matches one of them.
|
||||
|
||||
For example:
|
||||
|
||||
| 0.9.x and before | 0.10.x |
|
||||
|--------------------------------------------|---------------------------------------|
|
||||
| `-rpcallowip=192.168.1.1` | `-rpcallowip=192.168.1.1` (unchanged) |
|
||||
| `-rpcallowip=192.168.1.*` | `-rpcallowip=192.168.1.0/24` |
|
||||
| `-rpcallowip=192.168.*` | `-rpcallowip=192.168.0.0/16` |
|
||||
| `-rpcallowip=*` (dangerous!) | `-rpcallowip=::/0` (still dangerous!) |
|
||||
|
||||
Using wildcards will result in the rule being rejected with the following error in debug.log:
|
||||
|
||||
Error: Invalid -rpcallowip subnet specification: *. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).
|
||||
|
||||
|
||||
REST interface
|
||||
--------------
|
||||
|
||||
A new HTTP API is exposed when running with the `-rest` flag, which allows
|
||||
unauthenticated access to public node data.
|
||||
|
||||
It is served on the same port as RPC, but does not need a password, and uses
|
||||
plain HTTP instead of JSON-RPC.
|
||||
|
||||
Assuming a local RPC server running on port 8332, it is possible to request:
|
||||
- Blocks: http://localhost:8332/rest/block/*HASH*.*EXT*
|
||||
- Blocks without transactions: http://localhost:8332/rest/block/notxdetails/*HASH*.*EXT*
|
||||
- Transactions (requires `-txindex`): http://localhost:8332/rest/tx/*HASH*.*EXT*
|
||||
|
||||
In every case, *EXT* can be `bin` (for raw binary data), `hex` (for hex-encoded
|
||||
binary) or `json`.
|
||||
|
||||
For more details, see the `doc/REST-interface.md` document in the repository.
|
||||
|
||||
RPC Server "Warm-Up" Mode
|
||||
-------------------------
|
||||
|
||||
The RPC server is started earlier now, before most of the expensive
|
||||
intialisations like loading the block index. It is available now almost
|
||||
immediately after starting the process. However, until all initialisations
|
||||
are done, it always returns an immediate error with code -28 to all calls.
|
||||
|
||||
This new behaviour can be useful for clients to know that a server is already
|
||||
started and will be available soon (for instance, so that they do not
|
||||
have to start it themselves).
|
||||
|
||||
Improved signing security
|
||||
-------------------------
|
||||
|
||||
For 0.10 the security of signing against unusual attacks has been
|
||||
improved by making the signatures constant time and deterministic.
|
||||
|
||||
This change is a result of switching signing to use libsecp256k1
|
||||
instead of OpenSSL. Libsecp256k1 is a cryptographic library
|
||||
optimized for the curve Bitcoin uses which was created by Bitcoin
|
||||
Core developer Pieter Wuille.
|
||||
|
||||
There exist attacks[1] against most ECC implementations where an
|
||||
attacker on shared virtual machine hardware could extract a private
|
||||
key if they could cause a target to sign using the same key hundreds
|
||||
of times. While using shared hosts and reusing keys are inadvisable
|
||||
for other reasons, it's a better practice to avoid the exposure.
|
||||
|
||||
OpenSSL has code in their source repository for derandomization
|
||||
and reduction in timing leaks that we've eagerly wanted to use for a
|
||||
long time, but this functionality has still not made its
|
||||
way into a released version of OpenSSL. Libsecp256k1 achieves
|
||||
significantly stronger protection: As far as we're aware this is
|
||||
the only deployed implementation of constant time signing for
|
||||
the curve Bitcoin uses and we have reason to believe that
|
||||
libsecp256k1 is better tested and more thoroughly reviewed
|
||||
than the implementation in OpenSSL.
|
||||
|
||||
[1] https://eprint.iacr.org/2014/161.pdf
|
||||
|
||||
Watch-only wallet support
|
||||
-------------------------
|
||||
|
||||
The wallet can now track transactions to and from wallets for which you know
|
||||
all addresses (or scripts), even without the private keys.
|
||||
|
||||
This can be used to track payments without needing the private keys online on a
|
||||
possibly vulnerable system. In addition, it can help for (manual) construction
|
||||
of multisig transactions where you are only one of the signers.
|
||||
|
||||
One new RPC, `importaddress`, is added which functions similarly to
|
||||
`importprivkey`, but instead takes an address or script (in hexadecimal) as
|
||||
argument. After using it, outputs credited to this address or script are
|
||||
considered to be received, and transactions consuming these outputs will be
|
||||
considered to be sent.
|
||||
|
||||
The following RPCs have optional support for watch-only:
|
||||
`getbalance`, `listreceivedbyaddress`, `listreceivedbyaccount`,
|
||||
`listtransactions`, `listaccounts`, `listsinceblock`, `gettransaction`. See the
|
||||
RPC documentation for those methods for more information.
|
||||
|
||||
Compared to using `getrawtransaction`, this mechanism does not require
|
||||
`-txindex`, scales better, integrates better with the wallet, and is compatible
|
||||
with future block chain pruning functionality. It does mean that all relevant
|
||||
addresses need to added to the wallet before the payment, though.
|
||||
|
||||
Consensus library
|
||||
-----------------
|
||||
|
||||
Starting from 0.10.0, the Bitcoin Core distribution includes a consensus library.
|
||||
|
||||
The purpose of this library is to make the verification functionality that is
|
||||
critical to Bitcoin's consensus available to other applications, e.g. to language
|
||||
bindings such as [python-bitcoinlib](https://pypi.python.org/pypi/python-bitcoinlib) or
|
||||
alternative node implementations.
|
||||
|
||||
This library is called `libbitcoinconsensus.so` (or, `.dll` for Windows).
|
||||
Its interface is defined in the C header [bitcoinconsensus.h](https://github.com/bitcoin/bitcoin/blob/0.10/src/script/bitcoinconsensus.h).
|
||||
|
||||
In its initial version the API includes two functions:
|
||||
|
||||
- `bitcoinconsensus_verify_script` verifies a script. It returns whether the indicated input of the provided serialized transaction
|
||||
correctly spends the passed scriptPubKey under additional constraints indicated by flags
|
||||
- `bitcoinconsensus_version` returns the API version, currently at an experimental `0`
|
||||
|
||||
The functionality is planned to be extended to e.g. UTXO management in upcoming releases, but the interface
|
||||
for existing methods should remain stable.
|
||||
|
||||
Standard script rules relaxed for P2SH addresses
|
||||
------------------------------------------------
|
||||
|
||||
The IsStandard() rules have been almost completely removed for P2SH
|
||||
redemption scripts, allowing applications to make use of any valid
|
||||
script type, such as "n-of-m OR y", hash-locked oracle addresses, etc.
|
||||
While the Bitcoin protocol has always supported these types of script,
|
||||
actually using them on mainnet has been previously inconvenient as
|
||||
standard Bitcoin Core nodes wouldn't relay them to miners, nor would
|
||||
most miners include them in blocks they mined.
|
||||
|
||||
bitcoin-tx
|
||||
----------
|
||||
|
||||
It has been observed that many of the RPC functions offered by bitcoind are
|
||||
"pure functions", and operate independently of the bitcoind wallet. This
|
||||
included many of the RPC "raw transaction" API functions, such as
|
||||
createrawtransaction.
|
||||
|
||||
bitcoin-tx is a newly introduced command line utility designed to enable easy
|
||||
manipulation of bitcoin transactions. A summary of its operation may be
|
||||
obtained via "bitcoin-tx --help" Transactions may be created or signed in a
|
||||
manner similar to the RPC raw tx API. Transactions may be updated, deleting
|
||||
inputs or outputs, or appending new inputs and outputs. Custom scripts may be
|
||||
easily composed using a simple text notation, borrowed from the bitcoin test
|
||||
suite.
|
||||
|
||||
This tool may be used for experimenting with new transaction types, signing
|
||||
multi-party transactions, and many other uses. Long term, the goal is to
|
||||
deprecate and remove "pure function" RPC API calls, as those do not require a
|
||||
server round-trip to execute.
|
||||
|
||||
Other utilities "bitcoin-key" and "bitcoin-script" have been proposed, making
|
||||
key and script operations easily accessible via command line.
|
||||
|
||||
Mining and relay policy enhancements
|
||||
------------------------------------
|
||||
|
||||
Bitcoin Core's block templates are now for version 3 blocks only, and any mining
|
||||
software relying on its `getblocktemplate` must be updated in parallel to use
|
||||
libblkmaker either version 0.4.2 or any version from 0.5.1 onward.
|
||||
If you are solo mining, this will affect you the moment you upgrade Bitcoin
|
||||
Core, which must be done prior to BIP66 achieving its 951/1001 status.
|
||||
If you are mining with the stratum mining protocol: this does not affect you.
|
||||
If you are mining with the getblocktemplate protocol to a pool: this will affect
|
||||
you at the pool operator's discretion, which must be no later than BIP66
|
||||
achieving its 951/1001 status.
|
||||
|
||||
The `prioritisetransaction` RPC method has been added to enable miners to
|
||||
manipulate the priority of transactions on an individual basis.
|
||||
|
||||
Bitcoin Core now supports BIP 22 long polling, so mining software can be
|
||||
notified immediately of new templates rather than having to poll periodically.
|
||||
|
||||
Support for BIP 23 block proposals is now available in Bitcoin Core's
|
||||
`getblocktemplate` method. This enables miners to check the basic validity of
|
||||
their next block before expending work on it, reducing risks of accidental
|
||||
hardforks or mining invalid blocks.
|
||||
|
||||
Two new options to control mining policy:
|
||||
- `-datacarrier=0/1` : Relay and mine "data carrier" (OP_RETURN) transactions
|
||||
if this is 1.
|
||||
- `-datacarriersize=n` : Maximum size, in bytes, we consider acceptable for
|
||||
"data carrier" outputs.
|
||||
|
||||
The relay policy has changed to more properly implement the desired behavior of not
|
||||
relaying free (or very low fee) transactions unless they have a priority above the
|
||||
AllowFreeThreshold(), in which case they are relayed subject to the rate limiter.
|
||||
|
||||
BIP 66: strict DER encoding for signatures
|
||||
------------------------------------------
|
||||
|
||||
Bitcoin Core 0.10 implements BIP 66, which introduces block version 3, and a new
|
||||
consensus rule, which prohibits non-DER signatures. Such transactions have been
|
||||
non-standard since Bitcoin v0.8.0 (released in February 2013), but were
|
||||
technically still permitted inside blocks.
|
||||
|
||||
This change breaks the dependency on OpenSSL's signature parsing, and is
|
||||
required if implementations would want to remove all of OpenSSL from the
|
||||
consensus code.
|
||||
|
||||
The same miner-voting mechanism as in BIP 34 is used: when 751 out of a
|
||||
sequence of 1001 blocks have version number 3 or higher, the new consensus
|
||||
rule becomes active for those blocks. When 951 out of a sequence of 1001
|
||||
blocks have version number 3 or higher, it becomes mandatory for all blocks.
|
||||
|
||||
Backward compatibility with current mining software is NOT provided, thus miners
|
||||
should read the first paragraph of "Mining and relay policy enhancements" above.
|
||||
|
||||
0.10.0 Change log
|
||||
=================
|
||||
|
||||
Detailed release notes follow. This overview includes changes that affect external
|
||||
behavior, not code moves, refactors or string updates.
|
||||
|
||||
RPC:
|
||||
- `f923c07` Support IPv6 lookup in bitcoin-cli even when IPv6 only bound on localhost
|
||||
- `b641c9c` Fix addnode "onetry": Connect with OpenNetworkConnection
|
||||
- `171ca77` estimatefee / estimatepriority RPC methods
|
||||
- `b750cf1` Remove cli functionality from bitcoind
|
||||
- `f6984e8` Add "chain" to getmininginfo, improve help in getblockchaininfo
|
||||
- `99ddc6c` Add nLocalServices info to RPC getinfo
|
||||
- `cf0c47b` Remove getwork() RPC call
|
||||
- `2a72d45` prioritisetransaction <txid> <priority delta> <priority tx fee>
|
||||
- `e44fea5` Add an option `-datacarrier` to allow users to disable relaying/mining data carrier transactions
|
||||
- `2ec5a3d` Prevent easy RPC memory exhaustion attack
|
||||
- `d4640d7` Added argument to getbalance to include watchonly addresses and fixed errors in balance calculation
|
||||
- `83f3543` Added argument to listaccounts to include watchonly addresses
|
||||
- `952877e` Showing 'involvesWatchonly' property for transactions returned by 'listtransactions' and 'listsinceblock'. It is only appended when the transaction involves a watchonly address
|
||||
- `d7d5d23` Added argument to listtransactions and listsinceblock to include watchonly addresses
|
||||
- `f87ba3d` added includeWatchonly argument to 'gettransaction' because it affects balance calculation
|
||||
- `0fa2f88` added includedWatchonly argument to listreceivedbyaddress/...account
|
||||
- `6c37f7f` `getrawchangeaddress`: fail when keypool exhausted and wallet locked
|
||||
- `ff6a7af` getblocktemplate: longpolling support
|
||||
- `c4a321f` Add peerid to getpeerinfo to allow correlation with the logs
|
||||
- `1b4568c` Add vout to ListTransactions output
|
||||
- `b33bd7a` Implement "getchaintips" RPC command to monitor blockchain forks
|
||||
- `733177e` Remove size limit in RPC client, keep it in server
|
||||
- `6b5b7cb` Categorize rpc help overview
|
||||
- `6f2c26a` Closely track mempool byte total. Add "getmempoolinfo" RPC
|
||||
- `aa82795` Add detailed network info to getnetworkinfo RPC
|
||||
- `01094bd` Don't reveal whether password is <20 or >20 characters in RPC
|
||||
- `57153d4` rpc: Compute number of confirmations of a block from block height
|
||||
- `ff36cbe` getnetworkinfo: export local node's client sub-version string
|
||||
- `d14d7de` SanitizeString: allow '(' and ')'
|
||||
- `31d6390` Fixed setaccount accepting foreign address
|
||||
- `b5ec5fe` update getnetworkinfo help with subversion
|
||||
- `ad6e601` RPC additions after headers-first
|
||||
- `33dfbf5` rpc: Fix leveldb iterator leak, and flush before `gettxoutsetinfo`
|
||||
- `2aa6329` Enable customising node policy for datacarrier data size with a -datacarriersize option
|
||||
- `f877aaa` submitblock: Use a temporary CValidationState to determine accurately the outcome of ProcessBlock
|
||||
- `e69a587` submitblock: Support for returning specific rejection reasons
|
||||
- `af82884` Add "warmup mode" for RPC server
|
||||
- `e2655e0` Add unauthenticated HTTP REST interface to public blockchain data
|
||||
- `683dc40` Disable SSLv3 (in favor of TLS) for the RPC client and server
|
||||
- `44b4c0d` signrawtransaction: validate private key
|
||||
- `9765a50` Implement BIP 23 Block Proposal
|
||||
- `f9de17e` Add warning comment to getinfo
|
||||
|
||||
Command-line options:
|
||||
- `ee21912` Use netmasks instead of wildcards for IP address matching
|
||||
- `deb3572` Add `-rpcbind` option to allow binding RPC port on a specific interface
|
||||
- `96b733e` Add `-version` option to get just the version
|
||||
- `1569353` Add `-stopafterblockimport` option
|
||||
- `77cbd46` Let -zapwallettxes recover transaction meta data
|
||||
- `1c750db` remove -tor compatibility code (only allow -onion)
|
||||
- `4aaa017` rework help messages for fee-related options
|
||||
- `4278b1d` Clarify error message when invalid -rpcallowip
|
||||
- `6b407e4` -datadir is now allowed in config files
|
||||
- `bdd5b58` Add option `-sysperms` to disable 077 umask (create new files with system default umask)
|
||||
- `cbe39a3` Add "bitcoin-tx" command line utility and supporting modules
|
||||
- `dbca89b` Trigger -alertnotify if network is upgrading without you
|
||||
- `ad96e7c` Make -reindex cope with out-of-order blocks
|
||||
- `16d5194` Skip reindexed blocks individually
|
||||
- `ec01243` --tracerpc option for regression tests
|
||||
- `f654f00` Change -genproclimit default to 1
|
||||
- `3c77714` Make -proxy set all network types, avoiding a connect leak
|
||||
- `57be955` Remove -printblock, -printblocktree, and -printblockindex
|
||||
- `ad3d208` remove -maxorphanblocks config parameter since it is no longer functional
|
||||
|
||||
Block and transaction handling:
|
||||
- `7a0e84d` ProcessGetData(): abort if a block file is missing from disk
|
||||
- `8c93bf4` LoadBlockIndexDB(): Require block db reindex if any `blk*.dat` files are missing
|
||||
- `77339e5` Get rid of the static chainMostWork (optimization)
|
||||
- `4e0eed8` Allow ActivateBestChain to release its lock on cs_main
|
||||
- `18e7216` Push cs_mains down in ProcessBlock
|
||||
- `fa126ef` Avoid undefined behavior using CFlatData in CScript serialization
|
||||
- `7f3b4e9` Relax IsStandard rules for pay-to-script-hash transactions
|
||||
- `c9a0918` Add a skiplist to the CBlockIndex structure
|
||||
- `bc42503` Use unordered_map for CCoinsViewCache with salted hash (optimization)
|
||||
- `d4d3fbd` Do not flush the cache after every block outside of IBD (optimization)
|
||||
- `ad08d0b` Bugfix: make CCoinsViewMemPool support pruned entries in underlying cache
|
||||
- `5734d4d` Only remove actualy failed blocks from setBlockIndexValid
|
||||
- `d70bc52` Rework block processing benchmark code
|
||||
- `714a3e6` Only keep setBlockIndexValid entries that are possible improvements
|
||||
- `ea100c7` Reduce maximum coinscache size during verification (reduce memory usage)
|
||||
- `4fad8e6` Reject transactions with excessive numbers of sigops
|
||||
- `b0875eb` Allow BatchWrite to destroy its input, reducing copying (optimization)
|
||||
- `92bb6f2` Bypass reloading blocks from disk (optimization)
|
||||
- `2e28031` Perform CVerifyDB on pcoinsdbview instead of pcoinsTip (reduce memory usage)
|
||||
- `ab15b2e` Avoid copying undo data (optimization)
|
||||
- `341735e` Headers-first synchronization
|
||||
- `afc32c5` Fix rebuild-chainstate feature and improve its performance
|
||||
- `e11b2ce` Fix large reorgs
|
||||
- `ed6d1a2` Keep information about all block files in memory
|
||||
- `a48f2d6` Abstract context-dependent block checking from acceptance
|
||||
- `7e615f5` Fixed mempool sync after sending a transaction
|
||||
- `51ce901` Improve chainstate/blockindex disk writing policy
|
||||
- `a206950` Introduce separate flushing modes
|
||||
- `9ec75c5` Add a locking mechanism to IsInitialBlockDownload to ensure it never goes from false to true
|
||||
- `868d041` Remove coinbase-dependant transactions during reorg
|
||||
- `723d12c` Remove txn which are invalidated by coinbase maturity during reorg
|
||||
- `0cb8763` Check against MANDATORY flags prior to accepting to mempool
|
||||
- `8446262` Reject headers that build on an invalid parent
|
||||
- `008138c` Bugfix: only track UTXO modification after lookup
|
||||
|
||||
P2P protocol and network code:
|
||||
- `f80cffa` Do not trigger a DoS ban if SCRIPT_VERIFY_NULLDUMMY fails
|
||||
- `c30329a` Add testnet DNS seed of Alex Kotenko
|
||||
- `45a4baf` Add testnet DNS seed of Andreas Schildbach
|
||||
- `f1920e8` Ping automatically every 2 minutes (unconditionally)
|
||||
- `806fd19` Allocate receive buffers in on the fly
|
||||
- `6ecf3ed` Display unknown commands received
|
||||
- `aa81564` Track peers' available blocks
|
||||
- `caf6150` Use async name resolving to improve net thread responsiveness
|
||||
- `9f4da19` Use pong receive time rather than processing time
|
||||
- `0127a9b` remove SOCKS4 support from core and GUI, use SOCKS5
|
||||
- `40f5cb8` Send rejects and apply DoS scoring for errors in direct block validation
|
||||
- `dc942e6` Introduce whitelisted peers
|
||||
- `c994d2e` prevent SOCKET leak in BindListenPort()
|
||||
- `a60120e` Add built-in seeds for .onion
|
||||
- `60dc8e4` Allow -onlynet=onion to be used
|
||||
- `3a56de7` addrman: Do not propagate obviously poor addresses onto the network
|
||||
- `6050ab6` netbase: Make SOCKS5 negotiation interruptible
|
||||
- `604ee2a` Remove tx from AlreadyAskedFor list once we receive it, not when we process it
|
||||
- `efad808` Avoid reject message feedback loops
|
||||
- `71697f9` Separate protocol versioning from clientversion
|
||||
- `20a5f61` Don't relay alerts to peers before version negotiation
|
||||
- `b4ee0bd` Introduce preferred download peers
|
||||
- `845c86d` Do not use third party services for IP detection
|
||||
- `12a49ca` Limit the number of new addressses to accumulate
|
||||
- `35e408f` Regard connection failures as attempt for addrman
|
||||
- `a3a7317` Introduce 10 minute block download timeout
|
||||
- `3022e7d` Require sufficent priority for relay of free transactions
|
||||
- `58fda4d` Update seed IPs, based on bitcoin.sipa.be crawler data
|
||||
- `18021d0` Remove bitnodes.io from dnsseeds.
|
||||
|
||||
Validation:
|
||||
- `6fd7ef2` Also switch the (unused) verification code to low-s instead of even-s
|
||||
- `584a358` Do merkle root and txid duplicates check simultaneously
|
||||
- `217a5c9` When transaction outputs exceed inputs, show the offending amounts so as to aid debugging
|
||||
- `f74fc9b` Print input index when signature validation fails, to aid debugging
|
||||
- `6fd59ee` script.h: set_vch() should shift a >32 bit value
|
||||
- `d752ba8` Add SCRIPT_VERIFY_SIGPUSHONLY (BIP62 rule 2) (test only)
|
||||
- `698c6ab` Add SCRIPT_VERIFY_MINIMALDATA (BIP62 rules 3 and 4) (test only)
|
||||
- `ab9edbd` script: create sane error return codes for script validation and remove logging
|
||||
- `219a147` script: check ScriptError values in script tests
|
||||
- `0391423` Discourage NOPs reserved for soft-fork upgrades
|
||||
- `98b135f` Make STRICTENC invalid pubkeys fail the script rather than the opcode
|
||||
- `307f7d4` Report script evaluation failures in log and reject messages
|
||||
- `ace39db` consensus: guard against openssl's new strict DER checks
|
||||
- `12b7c44` Improve robustness of DER recoding code
|
||||
- `76ce5c8` fail immediately on an empty signature
|
||||
|
||||
Build system:
|
||||
- `f25e3ad` Fix build in OS X 10.9
|
||||
- `65e8ba4` build: Switch to non-recursive make
|
||||
- `460b32d` build: fix broken boost chrono check on some platforms
|
||||
- `9ce0774` build: Fix windows configure when using --with-qt-libdir
|
||||
- `ea96475` build: Add mention of --disable-wallet to bdb48 error messages
|
||||
- `1dec09b` depends: add shared dependency builder
|
||||
- `c101c76` build: Add --with-utils (bitcoin-cli and bitcoin-tx, default=yes). Help string consistency tweaks. Target sanity check fix
|
||||
- `e432a5f` build: add option for reducing exports (v2)
|
||||
- `6134b43` Fixing condition 'sabotaging' MSVC build
|
||||
- `af0bd5e` osx: fix signing to make Gatekeeper happy (again)
|
||||
- `a7d1f03` build: fix dynamic boost check when --with-boost= is used
|
||||
- `d5fd094` build: fix qt test build when libprotobuf is in a non-standard path
|
||||
- `2cf5f16` Add libbitcoinconsensus library
|
||||
- `914868a` build: add a deterministic dmg signer
|
||||
- `2d375fe` depends: bump openssl to 1.0.1k
|
||||
- `b7a4ecc` Build: Only check for boost when building code that requires it
|
||||
|
||||
Wallet:
|
||||
- `b33d1f5` Use fee/priority estimates in wallet CreateTransaction
|
||||
- `4b7b1bb` Sanity checks for estimates
|
||||
- `c898846` Add support for watch-only addresses
|
||||
- `d5087d1` Use script matching rather than destination matching for watch-only
|
||||
- `d88af56` Fee fixes
|
||||
- `a35b55b` Dont run full check every time we decrypt wallet
|
||||
- `3a7c348` Fix make_change to not create half-satoshis
|
||||
- `f606bb9` fix a possible memory leak in CWalletDB::Recover
|
||||
- `870da77` fix possible memory leaks in CWallet::EncryptWallet
|
||||
- `ccca27a` Watch-only fixes
|
||||
- `9b1627d` [Wallet] Reduce minTxFee for transaction creation to 1000 satoshis
|
||||
- `a53fd41` Deterministic signing
|
||||
- `15ad0b5` Apply AreSane() checks to the fees from the network
|
||||
- `11855c1` Enforce minRelayTxFee on wallet created tx and add a maxtxfee option
|
||||
|
||||
GUI:
|
||||
- `c21c74b` osx: Fix missing dock menu with qt5
|
||||
- `b90711c` Fix Transaction details shows wrong To:
|
||||
- `516053c` Make links in 'About Bitcoin Core' clickable
|
||||
- `bdc83e8` Ensure payment request network matches client network
|
||||
- `65f78a1` Add GUI view of peer information
|
||||
- `06a91d9` VerifyDB progress reporting
|
||||
- `fe6bff2` Add BerkeleyDB version info to RPCConsole
|
||||
- `b917555` PeerTableModel: Fix potential deadlock. #4296
|
||||
- `dff0e3b` Improve rpc console history behavior
|
||||
- `95a9383` Remove CENT-fee-rule from coin control completely
|
||||
- `56b07d2` Allow setting listen via GUI
|
||||
- `d95ba75` Log messages with type>QtDebugMsg as non-debug
|
||||
- `8969828` New status bar Unit Display Control and related changes
|
||||
- `674c070` seed OpenSSL PNRG with Windows event data
|
||||
- `509f926` Payment request parsing on startup now only changes network if a valid network name is specified
|
||||
- `acd432b` Prevent balloon-spam after rescan
|
||||
- `7007402` Implement SI-style (thin space) thoudands separator
|
||||
- `91cce17` Use fixed-point arithmetic in amount spinbox
|
||||
- `bdba2dd` Remove an obscure option no-one cares about
|
||||
- `bd0aa10` Replace the temporary file hack currently used to change Bitcoin-Qt's dock icon (OS X) with a buffer-based solution
|
||||
- `94e1b9e` Re-work overviewpage UI
|
||||
- `8bfdc9a` Better looking trayicon
|
||||
- `b197bf3` disable tray interactions when client model set to 0
|
||||
- `1c5f0af` Add column Watch-only to transactions list
|
||||
- `21f139b` Fix tablet crash. closes #4854
|
||||
- `e84843c` Broken addresses on command line no longer trigger testnet
|
||||
- `a49f11d` Change splash screen to normal window
|
||||
- `1f9be98` Disable App Nap on OSX 10.9+
|
||||
- `27c3e91` Add proxy to options overridden if necessary
|
||||
- `4bd1185` Allow "emergency" shutdown during startup
|
||||
- `d52f072` Don't show wallet options in the preferences menu when running with -disablewallet
|
||||
- `6093aa1` Qt: QProgressBar CPU-Issue workaround
|
||||
- `0ed9675` [Wallet] Add global boolean whether to send free transactions (default=true)
|
||||
- `ed3e5e4` [Wallet] Add global boolean whether to pay at least the custom fee (default=true)
|
||||
- `e7876b2` [Wallet] Prevent user from paying a non-sense fee
|
||||
- `c1c9d5b` Add Smartfee to GUI
|
||||
- `e0a25c5` Make askpassphrase dialog behave more sanely
|
||||
- `94b362d` On close of splashscreen interrupt verifyDB
|
||||
- `b790d13` English translation update
|
||||
- `8543b0d` Correct tooltip on address book page
|
||||
|
||||
Tests:
|
||||
- `b41e594` Fix script test handling of empty scripts
|
||||
- `d3a33fc` Test CHECKMULTISIG with m == 0 and n == 0
|
||||
- `29c1749` Let tx (in)valid tests use any SCRIPT_VERIFY flag
|
||||
- `6380180` Add rejection of non-null CHECKMULTISIG dummy values
|
||||
- `21bf3d2` Add tests for BoostAsioToCNetAddr
|
||||
- `b5ad5e7` Add Python test for -rpcbind and -rpcallowip
|
||||
- `9ec0306` Add CODESEPARATOR/FindAndDelete() tests
|
||||
- `75ebced` Added many rpc wallet tests
|
||||
- `0193fb8` Allow multiple regression tests to run at once
|
||||
- `92a6220` Hook up sanity checks
|
||||
- `3820e01` Extend and move all crypto tests to crypto_tests.cpp
|
||||
- `3f9a019` added list/get received by address/ account tests
|
||||
- `a90689f` Remove timing-based signature cache unit test
|
||||
- `236982c` Add skiplist unit tests
|
||||
- `f4b00be` Add CChain::GetLocator() unit test
|
||||
- `b45a6e8` Add test for getblocktemplate longpolling
|
||||
- `cdf305e` Set -discover=0 in regtest framework
|
||||
- `ed02282` additional test for OP_SIZE in script_valid.json
|
||||
- `0072d98` script tests: BOOLAND, BOOLOR decode to integer
|
||||
- `833ff16` script tests: values that overflow to 0 are true
|
||||
- `4cac5db` script tests: value with trailing 0x00 is true
|
||||
- `89101c6` script test: test case for 5-byte bools
|
||||
- `d2d9dc0` script tests: add tests for CHECKMULTISIG limits
|
||||
- `d789386` Add "it works" test for bitcoin-tx
|
||||
- `df4d61e` Add bitcoin-tx tests
|
||||
- `aa41ac2` Test IsPushOnly() with invalid push
|
||||
- `6022b5d` Make `script_{valid,invalid}.json` validation flags configurable
|
||||
- `8138cbe` Add automatic script test generation, and actual checksig tests
|
||||
- `ed27e53` Add coins_tests with a large randomized CCoinViewCache test
|
||||
- `9df9cf5` Make SCRIPT_VERIFY_STRICTENC compatible with BIP62
|
||||
- `dcb9846` Extend getchaintips RPC test
|
||||
- `554147a` Ensure MINIMALDATA invalid tests can only fail one way
|
||||
- `dfeec18` Test every numeric-accepting opcode for correct handling of the numeric minimal encoding rule
|
||||
- `2b62e17` Clearly separate PUSHDATA and numeric argument MINIMALDATA tests
|
||||
- `16d78bd` Add valid invert of invalid every numeric opcode tests
|
||||
- `f635269` tests: enable alertnotify test for Windows
|
||||
- `7a41614` tests: allow rpc-tests to get filenames for bitcoind and bitcoin-cli from the environment
|
||||
- `5122ea7` tests: fix forknotify.py on windows
|
||||
- `fa7f8cd` tests: remove old pull-tester scripts
|
||||
- `7667850` tests: replace the old (unused since Travis) tests with new rpc test scripts
|
||||
- `f4e0aef` Do signature-s negation inside the tests
|
||||
- `1837987` Optimize -regtest setgenerate block generation
|
||||
- `2db4c8a` Fix node ranges in the test framework
|
||||
- `a8b2ce5` regression test only setmocktime RPC call
|
||||
- `daf03e7` RPC tests: create initial chain with specific timestamps
|
||||
- `8656dbb` Port/fix txnmall.sh regression test
|
||||
- `ca81587` Test the exact order of CHECKMULTISIG sig/pubkey evaluation
|
||||
- `7357893` Prioritize and display -testsafemode status in UI
|
||||
- `f321d6b` Add key generation/verification to ECC sanity check
|
||||
- `132ea9b` miner_tests: Disable checkpoints so they don't fail the subsidy-change test
|
||||
- `bc6cb41` QA RPC tests: Add tests block block proposals
|
||||
- `f67a9ce` Use deterministically generated script tests
|
||||
- `11d7a7d` [RPC] add rpc-test for http keep-alive (persistent connections)
|
||||
- `34318d7` RPC-test based on invalidateblock for mempool coinbase spends
|
||||
- `76ec867` Use actually valid transactions for script tests
|
||||
- `c8589bf` Add actual signature tests
|
||||
- `e2677d7` Fix smartfees test for change to relay policy
|
||||
- `263b65e` tests: run sanity checks in tests too
|
||||
|
||||
Miscellaneous:
|
||||
- `122549f` Fix incorrect checkpoint data for testnet3
|
||||
- `5bd02cf` Log used config file to debug.log on startup
|
||||
- `68ba85f` Updated Debian example bitcoin.conf with config from wiki + removed some cruft and updated comments
|
||||
- `e5ee8f0` Remove -beta suffix
|
||||
- `38405ac` Add comment regarding experimental-use service bits
|
||||
- `be873f6` Issue warning if collecting RandSeed data failed
|
||||
- `8ae973c` Allocate more space if necessary in RandSeedAddPerfMon
|
||||
- `675bcd5` Correct comment for 15-of-15 p2sh script size
|
||||
- `fda3fed` libsecp256k1 integration
|
||||
- `2e36866` Show nodeid instead of addresses in log (for anonymity) unless otherwise requested
|
||||
- `cd01a5e` Enable paranoid corruption checks in LevelDB >= 1.16
|
||||
- `9365937` Add comment about never updating nTimeOffset past 199 samples
|
||||
- `403c1bf` contrib: remove getwork-based pyminer (as getwork API call has been removed)
|
||||
- `0c3e101` contrib: Added systemd .service file in order to help distributions integrate bitcoind
|
||||
- `0a0878d` doc: Add new DNSseed policy
|
||||
- `2887bff` Update coding style and add .clang-format
|
||||
- `5cbda4f` Changed LevelDB cursors to use scoped pointers to ensure destruction when going out of scope
|
||||
- `b4a72a7` contrib/linearize: split output files based on new-timestamp-year or max-file-size
|
||||
- `e982b57` Use explicit fflush() instead of setvbuf()
|
||||
- `234bfbf` contrib: Add init scripts and docs for Upstart and OpenRC
|
||||
- `01c2807` Add warning about the merkle-tree algorithm duplicate txid flaw
|
||||
- `d6712db` Also create pid file in non-daemon mode
|
||||
- `772ab0e` contrib: use batched JSON-RPC in linarize-hashes (optimization)
|
||||
- `7ab4358` Update bash-completion for v0.10
|
||||
- `6e6a36c` contrib: show pull # in prompt for github-merge script
|
||||
- `5b9f842` Upgrade leveldb to 1.18, make chainstate databases compatible between ARM and x86 (issue #2293)
|
||||
- `4e7c219` Catch UTXO set read errors and shutdown
|
||||
- `867c600` Catch LevelDB errors during flush
|
||||
- `06ca065` Fix CScriptID(const CScript& in) in empty script case
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Thanks to everyone who contributed to this release:
|
||||
|
||||
- 21E14
|
||||
- Adam Weiss
|
||||
- Aitor Pazos
|
||||
- Alexander Jeng
|
||||
- Alex Morcos
|
||||
- Alon Muroch
|
||||
- Andreas Schildbach
|
||||
- Andrew Poelstra
|
||||
- Andy Alness
|
||||
- Ashley Holman
|
||||
- Benedict Chan
|
||||
- Ben Holden-Crowther
|
||||
- Bryan Bishop
|
||||
- BtcDrak
|
||||
- Christian von Roques
|
||||
- Clinton Christian
|
||||
- Cory Fields
|
||||
- Cozz Lovan
|
||||
- daniel
|
||||
- Daniel Kraft
|
||||
- David Hill
|
||||
- Derek701
|
||||
- dexX7
|
||||
- dllud
|
||||
- Dominyk Tiller
|
||||
- Doug
|
||||
- elichai
|
||||
- elkingtowa
|
||||
- ENikS
|
||||
- Eric Shaw
|
||||
- Federico Bond
|
||||
- Francis GASCHET
|
||||
- Gavin Andresen
|
||||
- Giuseppe Mazzotta
|
||||
- Glenn Willen
|
||||
- Gregory Maxwell
|
||||
- gubatron
|
||||
- HarryWu
|
||||
- himynameismartin
|
||||
- Huang Le
|
||||
- Ian Carroll
|
||||
- imharrywu
|
||||
- Jameson Lopp
|
||||
- Janusz Lenar
|
||||
- JaSK
|
||||
- Jeff Garzik
|
||||
- JL2035
|
||||
- Johnathan Corgan
|
||||
- Jonas Schnelli
|
||||
- jtimon
|
||||
- Julian Haight
|
||||
- Kamil Domanski
|
||||
- kazcw
|
||||
- kevin
|
||||
- kiwigb
|
||||
- Kosta Zertsekel
|
||||
- LongShao007
|
||||
- Luke Dashjr
|
||||
- Mark Friedenbach
|
||||
- Mathy Vanvoorden
|
||||
- Matt Corallo
|
||||
- Matthew Bogosian
|
||||
- Micha
|
||||
- Michael Ford
|
||||
- Mike Hearn
|
||||
- mrbandrews
|
||||
- mruddy
|
||||
- ntrgn
|
||||
- Otto Allmendinger
|
||||
- paveljanik
|
||||
- Pavel Vasin
|
||||
- Peter Todd
|
||||
- phantomcircuit
|
||||
- Philip Kaufmann
|
||||
- Pieter Wuille
|
||||
- pryds
|
||||
- randy-waterhouse
|
||||
- R E Broadley
|
||||
- Rose Toomey
|
||||
- Ross Nicoll
|
||||
- Roy Badami
|
||||
- Ruben Dario Ponticelli
|
||||
- Rune K. Svendsen
|
||||
- Ryan X. Charles
|
||||
- Saivann
|
||||
- sandakersmann
|
||||
- SergioDemianLerner
|
||||
- shshshsh
|
||||
- sinetek
|
||||
- Stuart Cardall
|
||||
- Suhas Daftuar
|
||||
- Tawanda Kembo
|
||||
- Teran McKinney
|
||||
- tm314159
|
||||
- Tom Harding
|
||||
- Trevin Hofmann
|
||||
- Whit J
|
||||
- Wladimir J. van der Laan
|
||||
- Yoichi Hirai
|
||||
- Zak Wilcox
|
||||
|
||||
As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
|
||||
|
||||
143
doc/release-notes/release-notes-0.10.1.md
Normal file
143
doc/release-notes/release-notes-0.10.1.md
Normal file
@@ -0,0 +1,143 @@
|
||||
Bitcoin Core version 0.10.1 is now available from:
|
||||
|
||||
<https://bitcoin.org/bin/bitcoin-core-0.10.1/>
|
||||
|
||||
This is a new minor version release, bringing bug fixes and translation
|
||||
updates. It is recommended to upgrade to this version.
|
||||
|
||||
Please report bugs using the issue tracker at github:
|
||||
|
||||
<https://github.com/bitcoin/bitcoin/issues>
|
||||
|
||||
Upgrading and downgrading
|
||||
=========================
|
||||
|
||||
How to Upgrade
|
||||
--------------
|
||||
|
||||
If you are running an older version, shut it down. Wait until it has completely
|
||||
shut down (which might take a few minutes for older versions), then run the
|
||||
installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
|
||||
bitcoind/bitcoin-qt (on Linux).
|
||||
|
||||
Downgrade warning
|
||||
------------------
|
||||
|
||||
Because release 0.10.0 and later makes use of headers-first synchronization and
|
||||
parallel block download (see further), the block files and databases are not
|
||||
backwards-compatible with pre-0.10 versions of Bitcoin Core or other software:
|
||||
|
||||
* Blocks will be stored on disk out of order (in the order they are
|
||||
received, really), which makes it incompatible with some tools or
|
||||
other programs. Reindexing using earlier versions will also not work
|
||||
anymore as a result of this.
|
||||
|
||||
* The block index database will now hold headers for which no block is
|
||||
stored on disk, which earlier versions won't support.
|
||||
|
||||
If you want to be able to downgrade smoothly, make a backup of your entire data
|
||||
directory. Without this your node will need start syncing (or importing from
|
||||
bootstrap.dat) anew afterwards. It is possible that the data from a completely
|
||||
synchronised 0.10 node may be usable in older versions as-is, but this is not
|
||||
supported and may break as soon as the older version attempts to reindex.
|
||||
|
||||
This does not affect wallet forward or backward compatibility.
|
||||
|
||||
Notable changes
|
||||
===============
|
||||
|
||||
This is a minor release and hence there are no notable changes.
|
||||
For the notable changes in 0.10, refer to the release notes for the
|
||||
0.10.0 release at https://github.com/bitcoin/bitcoin/blob/v0.10.0/doc/release-notes.md
|
||||
|
||||
0.10.1 Change log
|
||||
=================
|
||||
|
||||
Detailed release notes follow. This overview includes changes that affect external
|
||||
behavior, not code moves, refactors or string updates.
|
||||
|
||||
RPC:
|
||||
- `7f502be` fix crash: createmultisig and addmultisigaddress
|
||||
- `eae305f` Fix missing lock in submitblock
|
||||
|
||||
Block (database) and transaction handling:
|
||||
- `1d2cdd2` Fix InvalidateBlock to add chainActive.Tip to setBlockIndexCandidates
|
||||
- `c91c660` fix InvalidateBlock to repopulate setBlockIndexCandidates
|
||||
- `002c8a2` fix possible block db breakage during re-index
|
||||
- `a1f425b` Add (optional) consistency check for the block chain data structures
|
||||
- `1c62e84` Keep mempool consistent during block-reorgs
|
||||
- `57d1f46` Fix CheckBlockIndex for reindex
|
||||
- `bac6fca` Set nSequenceId when a block is fully linked
|
||||
|
||||
P2P protocol and network code:
|
||||
- `78f64ef` don't trickle for whitelisted nodes
|
||||
- `ca301bf` Reduce fingerprinting through timestamps in 'addr' messages.
|
||||
- `200f293` Ignore getaddr messages on Outbound connections.
|
||||
- `d5d8998` Limit message sizes before transfer
|
||||
- `aeb9279` Better fingerprinting protection for non-main-chain getdatas.
|
||||
- `cf0218f` Make addrman's bucket placement deterministic (countermeasure 1 against eclipse attacks, see http://cs-people.bu.edu/heilman/eclipse/)
|
||||
- `0c6f334` Always use a 50% chance to choose between tried and new entries (countermeasure 2 against eclipse attacks)
|
||||
- `214154e` Do not bias outgoing connections towards fresh addresses (countermeasure 2 against eclipse attacks)
|
||||
- `aa587d4` Scale up addrman (countermeasure 6 against eclipse attacks)
|
||||
- `139cd81` Cap nAttempts penalty at 8 and switch to pow instead of a division loop
|
||||
|
||||
Validation:
|
||||
- `d148f62` Acquire CCheckQueue's lock to avoid race condition
|
||||
|
||||
Build system:
|
||||
- `8752b5c` 0.10 fix for crashes on OSX 10.6
|
||||
|
||||
Wallet:
|
||||
- N/A
|
||||
|
||||
GUI:
|
||||
- `2c08406` some mac specifiy cleanup (memory handling, unnecessary code)
|
||||
- `81145a6` fix OSX dock icon window reopening
|
||||
- `786cf72` fix a issue where "command line options"-action overwrite "Preference"-action (on OSX)
|
||||
|
||||
Tests:
|
||||
- `1117378` add RPC test for InvalidateBlock
|
||||
|
||||
Miscellaneous:
|
||||
- `c9e022b` Initialization: set Boost path locale in main thread
|
||||
- `23126a0` Sanitize command strings before logging them.
|
||||
- `323de27` Initialization: setup environment before starting Qt tests
|
||||
- `7494e09` Initialization: setup environment before starting tests
|
||||
- `df45564` Initialization: set fallback locale as environment variable
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Thanks to everyone who directly contributed to this release:
|
||||
|
||||
- Alex Morcos
|
||||
- Cory Fields
|
||||
- dexX7
|
||||
- fsb4000
|
||||
- Gavin Andresen
|
||||
- Gregory Maxwell
|
||||
- Ivan Pustogarov
|
||||
- Jonas Schnelli
|
||||
- Matt Corallo
|
||||
- mrbandrews
|
||||
- Pieter Wuille
|
||||
- Ruben de Vries
|
||||
- Suhas Daftuar
|
||||
- Wladimir J. van der Laan
|
||||
|
||||
And all those who contributed additional code review and/or security research:
|
||||
- 21E14
|
||||
- Alison Kendler
|
||||
- Aviv Zohar
|
||||
- Ethan Heilman
|
||||
- Evil-Knievel
|
||||
- fanquake
|
||||
- Jeff Garzik
|
||||
- Jonas Nick
|
||||
- Luke Dashjr
|
||||
- Patrick Strateman
|
||||
- Philip Kaufmann
|
||||
- Sergio Demian Lerner
|
||||
- Sharon Goldberg
|
||||
|
||||
As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
|
||||
86
doc/release-notes/release-notes-0.10.2.md
Normal file
86
doc/release-notes/release-notes-0.10.2.md
Normal file
@@ -0,0 +1,86 @@
|
||||
Bitcoin Core version 0.10.2 is now available from:
|
||||
|
||||
<https://bitcoin.org/bin/bitcoin-core-0.10.2/>
|
||||
|
||||
This is a new minor version release, bringing minor bug fixes and translation
|
||||
updates. It is recommended to upgrade to this version.
|
||||
|
||||
Please report bugs using the issue tracker at github:
|
||||
|
||||
<https://github.com/bitcoin/bitcoin/issues>
|
||||
|
||||
Upgrading and downgrading
|
||||
=========================
|
||||
|
||||
How to Upgrade
|
||||
--------------
|
||||
|
||||
If you are running an older version, shut it down. Wait until it has completely
|
||||
shut down (which might take a few minutes for older versions), then run the
|
||||
installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
|
||||
bitcoind/bitcoin-qt (on Linux).
|
||||
|
||||
Downgrade warning
|
||||
------------------
|
||||
|
||||
Because release 0.10.0 and later makes use of headers-first synchronization and
|
||||
parallel block download (see further), the block files and databases are not
|
||||
backwards-compatible with pre-0.10 versions of Bitcoin Core or other software:
|
||||
|
||||
* Blocks will be stored on disk out of order (in the order they are
|
||||
received, really), which makes it incompatible with some tools or
|
||||
other programs. Reindexing using earlier versions will also not work
|
||||
anymore as a result of this.
|
||||
|
||||
* The block index database will now hold headers for which no block is
|
||||
stored on disk, which earlier versions won't support.
|
||||
|
||||
If you want to be able to downgrade smoothly, make a backup of your entire data
|
||||
directory. Without this your node will need start syncing (or importing from
|
||||
bootstrap.dat) anew afterwards. It is possible that the data from a completely
|
||||
synchronised 0.10 node may be usable in older versions as-is, but this is not
|
||||
supported and may break as soon as the older version attempts to reindex.
|
||||
|
||||
This does not affect wallet forward or backward compatibility.
|
||||
|
||||
Notable changes
|
||||
===============
|
||||
|
||||
This fixes a serious problem on Windows with data directories that have non-ASCII
|
||||
characters (https://github.com/bitcoin/bitcoin/issues/6078).
|
||||
|
||||
For other platforms there are no notable changes.
|
||||
|
||||
For the notable changes in 0.10, refer to the release notes
|
||||
at https://github.com/bitcoin/bitcoin/blob/v0.10.0/doc/release-notes.md
|
||||
|
||||
0.10.2 Change log
|
||||
=================
|
||||
|
||||
Detailed release notes follow. This overview includes changes that affect external
|
||||
behavior, not code moves, refactors or string updates.
|
||||
|
||||
Wallet:
|
||||
- `824c011` fix boost::get usage with boost 1.58
|
||||
|
||||
Miscellaneous:
|
||||
- `da65606` Avoid crash on start in TestBlockValidity with gen=1.
|
||||
- `424ae66` don't imbue boost::filesystem::path with locale "C" on windows (fixes #6078)
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Thanks to everyone who directly contributed to this release:
|
||||
|
||||
- Cory Fields
|
||||
- Gregory Maxwell
|
||||
- Jonas Schnelli
|
||||
- Wladimir J. van der Laan
|
||||
|
||||
And all those who contributed additional code review and/or security research:
|
||||
|
||||
- dexX7
|
||||
- Pieter Wuille
|
||||
- vayvanne
|
||||
|
||||
As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
|
||||
165
doc/release-notes/release-notes-0.10.3.md
Normal file
165
doc/release-notes/release-notes-0.10.3.md
Normal file
@@ -0,0 +1,165 @@
|
||||
Bitcoin Core version 0.10.3 is now available from:
|
||||
|
||||
<https://bitcoin.org/bin/bitcoin-core-0.10.3/>
|
||||
|
||||
This is a new minor version release, bringing security fixes and translation
|
||||
updates. It is recommended to upgrade to this version as soon as possible.
|
||||
|
||||
Please report bugs using the issue tracker at github:
|
||||
|
||||
<https://github.com/bitcoin/bitcoin/issues>
|
||||
|
||||
Upgrading and downgrading
|
||||
=========================
|
||||
|
||||
How to Upgrade
|
||||
--------------
|
||||
|
||||
If you are running an older version, shut it down. Wait until it has completely
|
||||
shut down (which might take a few minutes for older versions), then run the
|
||||
installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
|
||||
bitcoind/bitcoin-qt (on Linux).
|
||||
|
||||
Downgrade warning
|
||||
------------------
|
||||
|
||||
Because release 0.10.0 and later makes use of headers-first synchronization and
|
||||
parallel block download (see further), the block files and databases are not
|
||||
backwards-compatible with pre-0.10 versions of Bitcoin Core or other software:
|
||||
|
||||
* Blocks will be stored on disk out of order (in the order they are
|
||||
received, really), which makes it incompatible with some tools or
|
||||
other programs. Reindexing using earlier versions will also not work
|
||||
anymore as a result of this.
|
||||
|
||||
* The block index database will now hold headers for which no block is
|
||||
stored on disk, which earlier versions won't support.
|
||||
|
||||
If you want to be able to downgrade smoothly, make a backup of your entire data
|
||||
directory. Without this your node will need start syncing (or importing from
|
||||
bootstrap.dat) anew afterwards. It is possible that the data from a completely
|
||||
synchronised 0.10 node may be usable in older versions as-is, but this is not
|
||||
supported and may break as soon as the older version attempts to reindex.
|
||||
|
||||
This does not affect wallet forward or backward compatibility.
|
||||
|
||||
Notable changes
|
||||
===============
|
||||
|
||||
Fix buffer overflow in bundled upnp
|
||||
------------------------------------
|
||||
|
||||
Bundled miniupnpc was updated to 1.9.20151008. This fixes a buffer overflow in
|
||||
the XML parser during initial network discovery.
|
||||
|
||||
Details can be found here: http://talosintel.com/reports/TALOS-2015-0035/
|
||||
|
||||
This applies to the distributed executables only, not when building from source or
|
||||
using distribution provided packages.
|
||||
|
||||
Additionally, upnp has been disabled by default. This may result in a lower
|
||||
number of reachable nodes on IPv4, however this prevents future libupnpc
|
||||
vulnerabilities from being a structural risk to the network
|
||||
(see https://github.com/bitcoin/bitcoin/pull/6795).
|
||||
|
||||
Test for LowS signatures before relaying
|
||||
-----------------------------------------
|
||||
|
||||
Make the node require the canonical 'low-s' encoding for ECDSA signatures when
|
||||
relaying or mining. This removes a nuisance malleability vector.
|
||||
|
||||
Consensus behavior is unchanged.
|
||||
|
||||
If widely deployed this change would eliminate the last remaining known vector
|
||||
for nuisance malleability on SIGHASH_ALL P2PKH transactions. On the down-side
|
||||
it will block most transactions made by sufficiently out of date software.
|
||||
|
||||
Unlike the other avenues to change txids on transactions this
|
||||
one was randomly violated by all deployed bitcoin software prior to
|
||||
its discovery. So, while other malleability vectors where made
|
||||
non-standard as soon as they were discovered, this one has remained
|
||||
permitted. Even BIP62 did not propose applying this rule to
|
||||
old version transactions, but conforming implementations have become
|
||||
much more common since BIP62 was initially written.
|
||||
|
||||
Bitcoin Core has produced compatible signatures since a28fb70e in
|
||||
September 2013, but this didn't make it into a release until 0.9
|
||||
in March 2014; Bitcoinj has done so for a similar span of time.
|
||||
Bitcoinjs and electrum have been more recently updated.
|
||||
|
||||
This does not replace the need for BIP62 or similar, as miners can
|
||||
still cooperate to break transactions. Nor does it replace the
|
||||
need for wallet software to handle malleability sanely[1]. This
|
||||
only eliminates the cheap and irritating DOS attack.
|
||||
|
||||
[1] On the Malleability of Bitcoin Transactions
|
||||
Marcin Andrychowicz, Stefan Dziembowski, Daniel Malinowski, Łukasz Mazurek
|
||||
http://fc15.ifca.ai/preproceedings/bitcoin/paper_9.pdf
|
||||
|
||||
Minimum relay fee default increase
|
||||
-----------------------------------
|
||||
|
||||
The default for the `-minrelaytxfee` setting has been increased from `0.00001`
|
||||
to `0.00005`.
|
||||
|
||||
This is necessitated by the current transaction flooding, causing
|
||||
outrageous memory usage on nodes due to the mempool ballooning. This is a
|
||||
temporary measure, bridging the time until a dynamic method for determining
|
||||
this fee is merged (which will be in 0.12).
|
||||
|
||||
(see https://github.com/bitcoin/bitcoin/pull/6793, as well as the 0.11.0
|
||||
release notes, in which this value was suggested)
|
||||
|
||||
0.10.3 Change log
|
||||
=================
|
||||
|
||||
Detailed release notes follow. This overview includes changes that affect external
|
||||
behavior, not code moves, refactors or string updates.
|
||||
|
||||
- #6186 `e4a7d51` Fix two problems in CSubnet parsing
|
||||
- #6153 `ebd7d8d` Parameter interaction: disable upnp if -proxy set
|
||||
- #6203 `ecc96f5` Remove P2SH coinbase flag, no longer interesting
|
||||
- #6226 `181771b` json: fail read_string if string contains trailing garbage
|
||||
- #6244 `09334e0` configure: Detect (and reject) LibreSSL
|
||||
- #6276 `0fd8464` Fix getbalance * 0
|
||||
- #6274 `be64204` Add option `-alerts` to opt out of alert system
|
||||
- #6319 `3f55638` doc: update mailing list address
|
||||
- #6438 `7e66e9c` openssl: avoid config file load/race
|
||||
- #6439 `255eced` Updated URL location of netinstall for Debian
|
||||
- #6412 `0739e6e` Test whether created sockets are select()able
|
||||
- #6694 `f696ea1` [QT] fix thin space word wrap line brake issue
|
||||
- #6704 `743cc9e` Backport bugfixes to 0.10
|
||||
- #6769 `1cea6b0` Test LowS in standardness, removes nuisance malleability vector.
|
||||
- #6789 `093d7b5` Update miniupnpc to 1.9.20151008
|
||||
- #6795 `f2778e0` net: Disable upnp by default
|
||||
- #6797 `91ef4d9` Do not store more than 200 timedata samples
|
||||
- #6793 `842c48d` Bump minrelaytxfee default
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Thanks to everyone who directly contributed to this release:
|
||||
|
||||
- Adam Weiss
|
||||
- Alex Morcos
|
||||
- Casey Rodarmor
|
||||
- Cory Fields
|
||||
- fanquake
|
||||
- Gregory Maxwell
|
||||
- Jonas Schnelli
|
||||
- J Ross Nicoll
|
||||
- Luke Dashjr
|
||||
- Pavel Vasin
|
||||
- Pieter Wuille
|
||||
- randy-waterhouse
|
||||
- ฿tcDrak
|
||||
- Tom Harding
|
||||
- Veres Lajos
|
||||
- Wladimir J. van der Laan
|
||||
|
||||
And all those who contributed additional code review and/or security research:
|
||||
|
||||
- timothy on IRC for reporting the issue
|
||||
- Vulnerability in miniupnp discovered by Aleksandar Nikolic of Cisco Talos
|
||||
|
||||
As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
|
||||
95
doc/release-notes/release-notes-0.9.4.md
Normal file
95
doc/release-notes/release-notes-0.9.4.md
Normal file
@@ -0,0 +1,95 @@
|
||||
Bitcoin Core version 0.9.4 is now available from:
|
||||
|
||||
https://bitcoin.org/bin/0.9.4/
|
||||
|
||||
This is a new minor version release, bringing only bug fixes and updated
|
||||
translations. Upgrading to this release is recommended.
|
||||
|
||||
Please report bugs using the issue tracker at github:
|
||||
|
||||
https://github.com/bitcoin/bitcoin/issues
|
||||
|
||||
How to Upgrade
|
||||
===============
|
||||
|
||||
If you are running an older version, shut it down. Wait until it has completely
|
||||
shut down (which might take a few minutes for older versions), then run the
|
||||
installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
|
||||
bitcoind/bitcoin-qt (on Linux).
|
||||
|
||||
OpenSSL Warning
|
||||
================
|
||||
|
||||
OpenSSL 1.0.0p / 1.0.1k was recently released and is being pushed out by
|
||||
various operating system maintainers. Review by Gregory Maxwell determined that
|
||||
this update is incompatible with the Bitcoin system and could lead to consensus
|
||||
forks.
|
||||
|
||||
Bitcoin Core released binaries from https://bitcoin.org are unaffected,
|
||||
as are any built with the gitian deterministic build system.
|
||||
|
||||
However, if you are running either
|
||||
|
||||
- The Ubuntu PPA from https://launchpad.net/~bitcoin/+archive/ubuntu/bitcoin
|
||||
- A third-party or self-compiled Bitcoin Core
|
||||
|
||||
upgrade to Bitcoin Core 0.9.4, which includes a workaround, **before** updating
|
||||
OpenSSL.
|
||||
|
||||
The incompatibility is due to the OpenSSL update changing the
|
||||
behavior of ECDSA validation to reject any signature which is
|
||||
not encoded in a very rigid manner. This was a result of
|
||||
OpenSSL's change for CVE-2014-8275 "Certificate fingerprints
|
||||
can be modified".
|
||||
|
||||
We are specifically aware of potential hard-forks due to signature
|
||||
encoding handling and had been hoping to close them via BIP62 in 0.10.
|
||||
BIP62's purpose is to improve transaction malleability handling and
|
||||
as a side effect rigidly defines the encoding for signatures, but the
|
||||
overall scope of BIP62 has made it take longer than we'd like to
|
||||
deploy.
|
||||
|
||||
0.9.4 changelog
|
||||
================
|
||||
|
||||
Validation:
|
||||
- `b8e81b7` consensus: guard against openssl's new strict DER checks
|
||||
- `60c51f1` fail immediately on an empty signature
|
||||
- `037bfef` Improve robustness of DER recoding code
|
||||
|
||||
Command-line options:
|
||||
- `cd5164a` Make -proxy set all network types, avoiding a connect leak.
|
||||
|
||||
P2P:
|
||||
- `bb424e4` Limit the number of new addressses to accumulate
|
||||
|
||||
RPC:
|
||||
- `0a94661` Disable SSLv3 (in favor of TLS) for the RPC client and server.
|
||||
|
||||
Build system:
|
||||
- `f047dfa` gitian: openssl-1.0.1i.tar.gz -> openssl-1.0.1k.tar.gz
|
||||
- `5b9f78d` build: Fix OSX build when using Homebrew and qt5
|
||||
- `ffab1dd` Keep symlinks when copying into .app bundle
|
||||
- `613247f` osx: fix signing to make Gatekeeper happy (again)
|
||||
|
||||
Miscellaneous:
|
||||
- `25b49b5` Refactor -alertnotify code
|
||||
- `2743529` doc: Add instructions for consistent Mac OS X build names
|
||||
|
||||
Credits
|
||||
--------
|
||||
|
||||
Thanks to who contributed to this release, at least:
|
||||
|
||||
- Cory Fields
|
||||
- Gavin Andresen
|
||||
- Gregory Maxwell
|
||||
- Jeff Garzik
|
||||
- Luke Dashjr
|
||||
- Matt Corallo
|
||||
- Pieter Wuille
|
||||
- Saivann
|
||||
- Sergio Demian Lerner
|
||||
- Wladimir J. van der Laan
|
||||
|
||||
As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
|
||||
60
doc/release-notes/release-notes-0.9.5.md
Normal file
60
doc/release-notes/release-notes-0.9.5.md
Normal file
@@ -0,0 +1,60 @@
|
||||
Bitcoin Core version 0.9.5 is now available from:
|
||||
|
||||
https://bitcoin.org/bin/0.9.5/
|
||||
|
||||
This is a new minor version release, with the goal of backporting BIP66. There
|
||||
are also a few bug fixes and updated translations. Upgrading to this release is
|
||||
recommended.
|
||||
|
||||
Please report bugs using the issue tracker at github:
|
||||
|
||||
https://github.com/bitcoin/bitcoin/issues
|
||||
|
||||
How to Upgrade
|
||||
===============
|
||||
|
||||
If you are running an older version, shut it down. Wait until it has completely
|
||||
shut down (which might take a few minutes for older versions), then run the
|
||||
installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
|
||||
bitcoind/bitcoin-qt (on Linux).
|
||||
|
||||
Notable changes
|
||||
================
|
||||
|
||||
Mining and relay policy enhancements
|
||||
------------------------------------
|
||||
|
||||
Bitcoin Core's block templates are now for version 3 blocks only, and any mining
|
||||
software relying on its `getblocktemplate` must be updated in parallel to use
|
||||
libblkmaker either version 0.4.2 or any version from 0.5.1 onward.
|
||||
If you are solo mining, this will affect you the moment you upgrade Bitcoin
|
||||
Core, which must be done prior to BIP66 achieving its 951/1001 status.
|
||||
If you are mining with the stratum mining protocol: this does not affect you.
|
||||
If you are mining with the getblocktemplate protocol to a pool: this will affect
|
||||
you at the pool operator's discretion, which must be no later than BIP66
|
||||
achieving its 951/1001 status.
|
||||
|
||||
0.9.5 changelog
|
||||
================
|
||||
|
||||
- `74f29c2` Check pindexBestForkBase for null
|
||||
- `9cd1dd9` Fix priority calculation in CreateTransaction
|
||||
- `6b4163b` Sanitize command strings before logging them.
|
||||
- `3230b32` Raise version of created blocks, and enforce DERSIG in mempool
|
||||
- `989d499` Backport of some of BIP66's tests
|
||||
- `ab03660` Implement BIP 66 validation rules and switchover logic
|
||||
- `8438074` build: fix dynamic boost check when --with-boost= is used
|
||||
|
||||
Credits
|
||||
--------
|
||||
|
||||
Thanks to who contributed to this release, at least:
|
||||
|
||||
- 21E14
|
||||
- Alex Morcos
|
||||
- Cory Fields
|
||||
- Gregory Maxwell
|
||||
- Pieter Wuille
|
||||
- Wladimir J. van der Laan
|
||||
|
||||
As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
|
||||
@@ -23,15 +23,15 @@ Release Process
|
||||
|
||||
* * *
|
||||
|
||||
###update gitian
|
||||
###update Gitian
|
||||
|
||||
In order to take advantage of the new caching features in gitian, be sure to update to a recent version (e9741525c or higher is recommended)
|
||||
In order to take advantage of the new caching features in Gitian, be sure to update to a recent version (e9741525c or higher is recommended)
|
||||
|
||||
###perform gitian builds
|
||||
###perform Gitian builds
|
||||
|
||||
From a directory containing the bitcoin source, gitian-builder and gitian.sigs
|
||||
|
||||
export SIGNER=(your gitian key, ie bluematt, sipa, etc)
|
||||
export SIGNER=(your Gitian key, ie bluematt, sipa, etc)
|
||||
export VERSION=(new version, e.g. 0.8.0)
|
||||
pushd ./bitcoin
|
||||
git checkout v${VERSION}
|
||||
@@ -39,19 +39,27 @@ Release Process
|
||||
pushd ./gitian-builder
|
||||
|
||||
###fetch and build inputs: (first time, or when dependency versions change)
|
||||
|
||||
mkdir -p inputs; cd inputs/
|
||||
|
||||
Register and download the Apple SDK: (see OSX Readme for details)
|
||||
|
||||
mkdir -p inputs
|
||||
|
||||
Register and download the Apple SDK: (see OS X Readme for details)
|
||||
|
||||
https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6.3/xcode4630916281a.dmg
|
||||
|
||||
|
||||
Using a Mac, create a tarball for the 10.7 SDK and copy it to the inputs directory:
|
||||
|
||||
|
||||
tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.7.sdk.tar.gz MacOSX10.7.sdk
|
||||
|
||||
Build Bitcoin Core for Linux, Windows, and OS X:
|
||||
|
||||
###Optional: Seed the Gitian sources cache
|
||||
|
||||
By default, Gitian will fetch source files as needed. For offline builds, they can be fetched ahead of time:
|
||||
|
||||
make -C ../bitcoin/depends download SOURCES_PATH=`pwd`/cache/common
|
||||
|
||||
Only missing files will be fetched, so this is safe to re-run for each build.
|
||||
|
||||
###Build Bitcoin Core for Linux, Windows, and OS X:
|
||||
|
||||
./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
|
||||
./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
|
||||
mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../
|
||||
@@ -60,17 +68,16 @@ Release Process
|
||||
mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../
|
||||
./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
|
||||
./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
|
||||
mv build/out/bitcoin-*-unsigned.tar.gz inputs
|
||||
mv build/out/bitcoin-*-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz
|
||||
mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../
|
||||
popd
|
||||
bitcoin-0.9.99-osx-unsigned.tar.gz
|
||||
Build output expected:
|
||||
|
||||
1. source tarball (bitcoin-${VERSION}.tar.gz)
|
||||
2. linux 32-bit and 64-bit binaries dist tarballs (bitcoin-${VERSION}-linux[32|64].tar.gz)
|
||||
3. windows 32-bit and 64-bit installers and dist zips (bitcoin-${VERSION}-win[32|64]-setup.exe, bitcoin-${VERSION}-win[32|64].zip)
|
||||
4. OSX unsigned installer (bitcoin-${VERSION}-osx-unsigned.dmg)
|
||||
5. Gitian signatures (in gitian.sigs/${VERSION}-<linux|win|osx-unsigned>/(your gitian key)/
|
||||
4. OS X unsigned installer (bitcoin-${VERSION}-osx-unsigned.dmg)
|
||||
5. Gitian signatures (in gitian.sigs/${VERSION}-<linux|win|osx-unsigned>/(your Gitian key)/
|
||||
|
||||
###Next steps:
|
||||
|
||||
@@ -84,20 +91,21 @@ Commit your signature to gitian.sigs:
|
||||
git push # Assuming you can push to the gitian.sigs tree
|
||||
popd
|
||||
|
||||
Wait for OSX detached signature:
|
||||
Once the OSX build has 3 matching signatures, Gavin will sign it with the apple App-Store key.
|
||||
Wait for OS X detached signature:
|
||||
Once the OS X build has 3 matching signatures, Gavin will sign it with the apple App-Store key.
|
||||
He will then upload a detached signature to be combined with the unsigned app to create a signed binary.
|
||||
|
||||
Create the signed OSX binary:
|
||||
Create the signed OS X binary:
|
||||
|
||||
pushd ./gitian-builder
|
||||
# Fetch the signature as instructed by Gavin
|
||||
cp signature.tar.gz inputs/
|
||||
./bin/gbuild -i ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml
|
||||
./bin/gsign --signer $SIGNER --release ${VERSION}-osx-signed --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx-signer.yml
|
||||
mv build/out/bitcoin-${VERSION}-osx.dmg ../
|
||||
mv build/out/bitcoin-osx-signed.dmg ../bitcoin-${VERSION}-osx.dmg
|
||||
popd
|
||||
|
||||
Commit your signature for the signed OSX binary:
|
||||
Commit your signature for the signed OS X binary:
|
||||
|
||||
pushd gitian.sigs
|
||||
git add ${VERSION}-osx-signed/${SIGNER}
|
||||
@@ -124,15 +132,22 @@ 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
|
||||
into `/var/www/bin/bitcoin-core-${VERSION}`
|
||||
|
||||
- Update bitcoin.org version
|
||||
|
||||
- Make a pull request to add a file named `YYYY-MM-DD-vX.Y.Z.md` with the release notes
|
||||
to https://github.com/bitcoin/bitcoin.org/tree/master/_releases
|
||||
([Example for 0.9.2.1](https://raw.githubusercontent.com/bitcoin/bitcoin.org/master/_releases/2014-06-19-v0.9.2.1.md)).
|
||||
- First, check to see if the Bitcoin.org maintainers have prepared a
|
||||
release: https://github.com/bitcoin/bitcoin.org/labels/Releases
|
||||
|
||||
- After the pull request is merged, the website will automatically show the newest version, as well
|
||||
as update the OS download links. Ping Saivann in case anything goes wrong
|
||||
- If they have, it will have previously failed their Travis CI
|
||||
checks because the final release files weren't uploaded.
|
||||
Trigger a Travis CI rebuild---if it passes, merge.
|
||||
|
||||
- If they have not prepared a release, follow the Bitcoin.org release
|
||||
instructions: https://github.com/bitcoin/bitcoin.org#release-notes
|
||||
|
||||
- After the pull request is merged, the website will automatically show the newest version within 15 minutes, as well
|
||||
as update the OS download links. Ping @saivann/@harding (saivann/harding on Freenode) in case anything goes wrong
|
||||
|
||||
- Announce the release:
|
||||
|
||||
|
||||
11
doc/tor.md
11
doc/tor.md
@@ -15,15 +15,15 @@ outgoing connections be anonymized, but more is possible.
|
||||
|
||||
-proxy=ip:port Set the proxy server. If SOCKS5 is selected (default), this proxy
|
||||
server will be used to try to reach .onion addresses as well.
|
||||
|
||||
|
||||
-onion=ip:port Set the proxy server to use for tor hidden services. You do not
|
||||
need to set this if it's the same as -proxy. You can use -noonion
|
||||
to explicitly disable access to hidden service.
|
||||
|
||||
|
||||
-listen When using -proxy, listening is disabled by default. If you want
|
||||
to run a hidden service (see next section), you'll need to enable
|
||||
it explicitly.
|
||||
|
||||
|
||||
-connect=X When behind a Tor proxy, you can specify .onion addresses instead
|
||||
-addnode=X of IP addresses or hostnames in these parameters. It requires
|
||||
-seednode=X SOCKS5. In Tor mode, such addresses can also be exchanged with
|
||||
@@ -55,10 +55,10 @@ your bitcoind's P2P listen port (8333 by default).
|
||||
preference for your node to advertize itself with, for connections
|
||||
coming from unroutable addresses (such as 127.0.0.1, where the
|
||||
Tor proxy typically runs).
|
||||
|
||||
|
||||
-listen You'll need to enable listening for incoming connections, as this
|
||||
is off by default behind a proxy.
|
||||
|
||||
|
||||
-discover When -externalip is specified, no attempt is made to discover local
|
||||
IPv4 or IPv6 addresses. If you want to run a dual stack, reachable
|
||||
from both Tor and IPv4 (or IPv6), you'll need to either pass your
|
||||
@@ -82,4 +82,3 @@ If you only want to use Tor to reach onion addresses, but not use it as a proxy
|
||||
for normal IPv4/IPv6 communication, use:
|
||||
|
||||
./bitcoin -onion=127.0.0.1:9050 -externalip=57qr3yd1nyntf5k.onion -discover
|
||||
|
||||
|
||||
@@ -8,11 +8,6 @@ CURDIR=$(cd $(dirname "$0"); pwd)
|
||||
export BITCOINCLI=${BUILDDIR}/qa/pull-tester/run-bitcoin-cli
|
||||
export BITCOIND=${REAL_BITCOIND}
|
||||
|
||||
if [ "x${EXEEXT}" = "x.exe" ]; then
|
||||
echo "Win tests currently disabled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#Run the tests
|
||||
|
||||
if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then
|
||||
|
||||
@@ -10,7 +10,7 @@ touch "$DATADIR/regtest/debug.log"
|
||||
tail -q -n 1 -F "$DATADIR/regtest/debug.log" | grep -m 1 -q "Done loading" &
|
||||
WAITER=$!
|
||||
PORT=`expr 10000 + $$ % 55536`
|
||||
"@abs_top_builddir@/src/bitcoind@EXEEXT@" -connect=0.0.0.0 -datadir="$DATADIR" -rpcuser=user -rpcpassword=pass -listen -keypool=3 -debug -debug=net -logtimestamps -checkmempool=0 -port=$PORT -whitelist=127.0.0.1 -regtest -rpcport=`expr $PORT + 1` &
|
||||
"@abs_top_builddir@/src/bitcoind@EXEEXT@" -connect=0.0.0.0 -datadir="$DATADIR" -rpcuser=user -rpcpassword=pass -listen -keypool=3 -debug -debug=net -logtimestamps -checkmempool=0 -relaypriority=0 -port=$PORT -whitelist=127.0.0.1 -regtest -rpcport=`expr $PORT + 1` &
|
||||
BITCOIND=$!
|
||||
|
||||
#Install a watchdog.
|
||||
|
||||
175
qa/rpc-tests/bip65-cltv-p2p.py
Executable file
175
qa/rpc-tests/bip65-cltv-p2p.py
Executable file
@@ -0,0 +1,175 @@
|
||||
#!/usr/bin/env python2
|
||||
#
|
||||
# Distributed under the MIT/X11 software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#
|
||||
|
||||
from test_framework.test_framework import ComparisonTestFramework
|
||||
from test_framework.util import *
|
||||
from test_framework.mininode import CTransaction, NetworkThread
|
||||
from test_framework.blocktools import create_coinbase, create_block
|
||||
from test_framework.comptool import TestInstance, TestManager
|
||||
from test_framework.script import CScript, OP_1NEGATE, OP_NOP2, OP_DROP
|
||||
from binascii import hexlify, unhexlify
|
||||
import cStringIO
|
||||
import time
|
||||
|
||||
def cltv_invalidate(tx):
|
||||
'''Modify the signature in vin 0 of the tx to fail CLTV
|
||||
|
||||
Prepends -1 CLTV DROP in the scriptSig itself.
|
||||
'''
|
||||
tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_NOP2, OP_DROP] +
|
||||
list(CScript(tx.vin[0].scriptSig)))
|
||||
|
||||
'''
|
||||
This test is meant to exercise BIP65 (CHECKLOCKTIMEVERIFY)
|
||||
Connect to a single node.
|
||||
Mine 2 (version 3) blocks (save the coinbases for later).
|
||||
Generate 98 more version 3 blocks, verify the node accepts.
|
||||
Mine 749 version 4 blocks, verify the node accepts.
|
||||
Check that the new CLTV rules are not enforced on the 750th version 4 block.
|
||||
Check that the new CLTV rules are enforced on the 751st version 4 block.
|
||||
Mine 199 new version blocks.
|
||||
Mine 1 old-version block.
|
||||
Mine 1 new version block.
|
||||
Mine 1 old version block, see that the node rejects.
|
||||
'''
|
||||
|
||||
class BIP65Test(ComparisonTestFramework):
|
||||
|
||||
def __init__(self):
|
||||
self.num_nodes = 1
|
||||
|
||||
def setup_network(self):
|
||||
# Must set the blockversion for this test
|
||||
self.nodes = start_nodes(1, self.options.tmpdir,
|
||||
extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=3']],
|
||||
binary=[self.options.testbinary])
|
||||
|
||||
def run_test(self):
|
||||
test = TestManager(self, self.options.tmpdir)
|
||||
test.add_all_connections(self.nodes)
|
||||
NetworkThread().start() # Start up network handling in another thread
|
||||
test.run()
|
||||
|
||||
def create_transaction(self, node, coinbase, to_address, amount):
|
||||
from_txid = node.getblock(coinbase)['tx'][0]
|
||||
inputs = [{ "txid" : from_txid, "vout" : 0}]
|
||||
outputs = { to_address : amount }
|
||||
rawtx = node.createrawtransaction(inputs, outputs)
|
||||
signresult = node.signrawtransaction(rawtx)
|
||||
tx = CTransaction()
|
||||
f = cStringIO.StringIO(unhexlify(signresult['hex']))
|
||||
tx.deserialize(f)
|
||||
return tx
|
||||
|
||||
def get_tests(self):
|
||||
|
||||
self.coinbase_blocks = self.nodes[0].setgenerate(True, 2)
|
||||
self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
|
||||
self.nodeaddress = self.nodes[0].getnewaddress()
|
||||
self.last_block_time = time.time()
|
||||
|
||||
''' 98 more version 3 blocks '''
|
||||
test_blocks = []
|
||||
for i in xrange(98):
|
||||
block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1)
|
||||
block.nVersion = 3
|
||||
block.rehash()
|
||||
block.solve()
|
||||
test_blocks.append([block, True])
|
||||
self.last_block_time += 1
|
||||
self.tip = block.sha256
|
||||
yield TestInstance(test_blocks, sync_every_block=False)
|
||||
|
||||
''' Mine 749 version 4 blocks '''
|
||||
test_blocks = []
|
||||
for i in xrange(749):
|
||||
block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1)
|
||||
block.nVersion = 4
|
||||
block.rehash()
|
||||
block.solve()
|
||||
test_blocks.append([block, True])
|
||||
self.last_block_time += 1
|
||||
self.tip = block.sha256
|
||||
yield TestInstance(test_blocks, sync_every_block=False)
|
||||
|
||||
'''
|
||||
Check that the new CLTV rules are not enforced in the 750th
|
||||
version 3 block.
|
||||
'''
|
||||
spendtx = self.create_transaction(self.nodes[0],
|
||||
self.coinbase_blocks[0], self.nodeaddress, 1.0)
|
||||
cltv_invalidate(spendtx)
|
||||
spendtx.rehash()
|
||||
|
||||
block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1)
|
||||
block.nVersion = 4
|
||||
block.vtx.append(spendtx)
|
||||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
block.rehash()
|
||||
block.solve()
|
||||
|
||||
self.last_block_time += 1
|
||||
self.tip = block.sha256
|
||||
yield TestInstance([[block, True]])
|
||||
|
||||
'''
|
||||
Check that the new CLTV rules are enforced in the 751st version 4
|
||||
block.
|
||||
'''
|
||||
spendtx = self.create_transaction(self.nodes[0],
|
||||
self.coinbase_blocks[1], self.nodeaddress, 1.0)
|
||||
cltv_invalidate(spendtx)
|
||||
spendtx.rehash()
|
||||
|
||||
block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
|
||||
block.nVersion = 4
|
||||
block.vtx.append(spendtx)
|
||||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
block.rehash()
|
||||
block.solve()
|
||||
self.last_block_time += 1
|
||||
yield TestInstance([[block, False]])
|
||||
|
||||
''' Mine 199 new version blocks on last valid tip '''
|
||||
test_blocks = []
|
||||
for i in xrange(199):
|
||||
block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
|
||||
block.nVersion = 4
|
||||
block.rehash()
|
||||
block.solve()
|
||||
test_blocks.append([block, True])
|
||||
self.last_block_time += 1
|
||||
self.tip = block.sha256
|
||||
yield TestInstance(test_blocks, sync_every_block=False)
|
||||
|
||||
''' Mine 1 old version block '''
|
||||
block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
|
||||
block.nVersion = 3
|
||||
block.rehash()
|
||||
block.solve()
|
||||
self.last_block_time += 1
|
||||
self.tip = block.sha256
|
||||
yield TestInstance([[block, True]])
|
||||
|
||||
''' Mine 1 new version block '''
|
||||
block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
|
||||
block.nVersion = 4
|
||||
block.rehash()
|
||||
block.solve()
|
||||
self.last_block_time += 1
|
||||
self.tip = block.sha256
|
||||
yield TestInstance([[block, True]])
|
||||
|
||||
''' Mine 1 old version block, should be invalid '''
|
||||
block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1)
|
||||
block.nVersion = 3
|
||||
block.rehash()
|
||||
block.solve()
|
||||
self.last_block_time += 1
|
||||
yield TestInstance([[block, False]])
|
||||
|
||||
if __name__ == '__main__':
|
||||
BIP65Test().main()
|
||||
89
qa/rpc-tests/bip65-cltv.py
Executable file
89
qa/rpc-tests/bip65-cltv.py
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2015 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#
|
||||
# Test the CHECKLOCKTIMEVERIFY (BIP65) soft-fork logic
|
||||
#
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import *
|
||||
import os
|
||||
import shutil
|
||||
|
||||
class BIP65Test(BitcoinTestFramework):
|
||||
|
||||
def setup_network(self):
|
||||
self.nodes = []
|
||||
self.nodes.append(start_node(0, self.options.tmpdir, []))
|
||||
self.nodes.append(start_node(1, self.options.tmpdir, ["-blockversion=3"]))
|
||||
self.nodes.append(start_node(2, self.options.tmpdir, ["-blockversion=4"]))
|
||||
connect_nodes(self.nodes[1], 0)
|
||||
connect_nodes(self.nodes[2], 0)
|
||||
self.is_network_split = False
|
||||
self.sync_all()
|
||||
|
||||
def run_test(self):
|
||||
cnt = self.nodes[0].getblockcount()
|
||||
|
||||
# Mine some old-version blocks
|
||||
self.nodes[1].setgenerate(True, 100)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 100):
|
||||
raise AssertionError("Failed to mine 100 version=3 blocks")
|
||||
|
||||
# Mine 750 new-version blocks
|
||||
for i in xrange(15):
|
||||
self.nodes[2].setgenerate(True, 50)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 850):
|
||||
raise AssertionError("Failed to mine 750 version=4 blocks")
|
||||
|
||||
# TODO: check that new CHECKLOCKTIMEVERIFY rules are not enforced
|
||||
|
||||
# Mine 1 new-version block
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 851):
|
||||
raise AssertionFailure("Failed to mine a version=4 blocks")
|
||||
|
||||
# TODO: check that new CHECKLOCKTIMEVERIFY rules are enforced
|
||||
|
||||
# Mine 198 new-version blocks
|
||||
for i in xrange(2):
|
||||
self.nodes[2].setgenerate(True, 99)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1049):
|
||||
raise AssertionError("Failed to mine 198 version=4 blocks")
|
||||
|
||||
# Mine 1 old-version block
|
||||
self.nodes[1].setgenerate(True, 1)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1050):
|
||||
raise AssertionError("Failed to mine a version=3 block after 949 version=4 blocks")
|
||||
|
||||
# Mine 1 new-version blocks
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1051):
|
||||
raise AssertionError("Failed to mine a version=4 block")
|
||||
|
||||
# Mine 1 old-version blocks
|
||||
try:
|
||||
self.nodes[1].setgenerate(True, 1)
|
||||
raise AssertionError("Succeeded to mine a version=3 block after 950 version=4 blocks")
|
||||
except JSONRPCException:
|
||||
pass
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1051):
|
||||
raise AssertionError("Accepted a version=3 block after 950 version=4 blocks")
|
||||
|
||||
# Mine 1 new-version blocks
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1052):
|
||||
raise AssertionError("Failed to mine a version=4 block")
|
||||
|
||||
if __name__ == '__main__':
|
||||
BIP65Test().main()
|
||||
90
qa/rpc-tests/bipdersig.py
Executable file
90
qa/rpc-tests/bipdersig.py
Executable file
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#
|
||||
# Test the BIP66 changeover logic
|
||||
#
|
||||
|
||||
from test_framework import BitcoinTestFramework
|
||||
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
|
||||
from util import *
|
||||
import os
|
||||
import shutil
|
||||
|
||||
class BIP66Test(BitcoinTestFramework):
|
||||
|
||||
def setup_network(self):
|
||||
self.nodes = []
|
||||
self.nodes.append(start_node(0, self.options.tmpdir, []))
|
||||
self.nodes.append(start_node(1, self.options.tmpdir, ["-blockversion=2"]))
|
||||
self.nodes.append(start_node(2, self.options.tmpdir, ["-blockversion=3"]))
|
||||
connect_nodes(self.nodes[1], 0)
|
||||
connect_nodes(self.nodes[2], 0)
|
||||
self.is_network_split = False
|
||||
self.sync_all()
|
||||
|
||||
def run_test(self):
|
||||
cnt = self.nodes[0].getblockcount()
|
||||
|
||||
# Mine some old-version blocks
|
||||
self.nodes[1].setgenerate(True, 100)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 100):
|
||||
raise AssertionError("Failed to mine 100 version=2 blocks")
|
||||
|
||||
# Mine 750 new-version blocks
|
||||
for i in xrange(15):
|
||||
self.nodes[2].setgenerate(True, 50)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 850):
|
||||
raise AssertionError("Failed to mine 750 version=3 blocks")
|
||||
|
||||
# TODO: check that new DERSIG rules are not enforced
|
||||
|
||||
# Mine 1 new-version block
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 851):
|
||||
raise AssertionFailure("Failed to mine a version=3 blocks")
|
||||
|
||||
# TODO: check that new DERSIG rules are enforced
|
||||
|
||||
# Mine 198 new-version blocks
|
||||
for i in xrange(2):
|
||||
self.nodes[2].setgenerate(True, 99)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1049):
|
||||
raise AssertionError("Failed to mine 198 version=3 blocks")
|
||||
|
||||
# Mine 1 old-version block
|
||||
self.nodes[1].setgenerate(True, 1)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1050):
|
||||
raise AssertionError("Failed to mine a version=2 block after 949 version=3 blocks")
|
||||
|
||||
# Mine 1 new-version blocks
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1051):
|
||||
raise AssertionError("Failed to mine a version=3 block")
|
||||
|
||||
# Mine 1 old-version blocks
|
||||
try:
|
||||
self.nodes[1].setgenerate(True, 1)
|
||||
raise AssertionError("Succeeded to mine a version=2 block after 950 version=3 blocks")
|
||||
except JSONRPCException:
|
||||
pass
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1051):
|
||||
raise AssertionError("Accepted a version=2 block after 950 version=3 blocks")
|
||||
|
||||
# Mine 1 new-version blocks
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
self.sync_all()
|
||||
if (self.nodes[0].getblockcount() != cnt + 1052):
|
||||
raise AssertionError("Failed to mine a version=3 block")
|
||||
|
||||
if __name__ == '__main__':
|
||||
BIP66Test().main()
|
||||
@@ -20,7 +20,10 @@ try:
|
||||
except ImportError:
|
||||
import urlparse
|
||||
|
||||
class RESTTest (BitcoinTestFramework):
|
||||
class HTTPBasicsTest (BitcoinTestFramework):
|
||||
def setup_nodes(self):
|
||||
return start_nodes(4, self.options.tmpdir, extra_args=[['-rpckeepalive=1'], ['-rpckeepalive=0'], [], []])
|
||||
|
||||
def run_test(self):
|
||||
|
||||
#################################################
|
||||
@@ -32,13 +35,13 @@ class RESTTest (BitcoinTestFramework):
|
||||
|
||||
conn = httplib.HTTPConnection(url.hostname, url.port)
|
||||
conn.connect()
|
||||
conn.request('GET', '/', '{"method": "getbestblockhash"}', headers)
|
||||
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
|
||||
out1 = conn.getresponse().read();
|
||||
assert_equal('"error":null' in out1, True)
|
||||
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
|
||||
|
||||
#send 2nd request without closing connection
|
||||
conn.request('GET', '/', '{"method": "getchaintips"}', headers)
|
||||
conn.request('POST', '/', '{"method": "getchaintips"}', headers)
|
||||
out2 = conn.getresponse().read();
|
||||
assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message
|
||||
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
|
||||
@@ -49,13 +52,13 @@ class RESTTest (BitcoinTestFramework):
|
||||
|
||||
conn = httplib.HTTPConnection(url.hostname, url.port)
|
||||
conn.connect()
|
||||
conn.request('GET', '/', '{"method": "getbestblockhash"}', headers)
|
||||
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
|
||||
out1 = conn.getresponse().read();
|
||||
assert_equal('"error":null' in out1, True)
|
||||
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
|
||||
|
||||
#send 2nd request without closing connection
|
||||
conn.request('GET', '/', '{"method": "getchaintips"}', headers)
|
||||
conn.request('POST', '/', '{"method": "getchaintips"}', headers)
|
||||
out2 = conn.getresponse().read();
|
||||
assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message
|
||||
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
|
||||
@@ -66,11 +69,34 @@ class RESTTest (BitcoinTestFramework):
|
||||
|
||||
conn = httplib.HTTPConnection(url.hostname, url.port)
|
||||
conn.connect()
|
||||
conn.request('GET', '/', '{"method": "getbestblockhash"}', headers)
|
||||
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
|
||||
out1 = conn.getresponse().read();
|
||||
assert_equal('"error":null' in out1, True)
|
||||
assert_equal(conn.sock!=None, False) #now the connection must be closed after the response
|
||||
|
||||
#node1 (2nd node) is running with disabled keep-alive option
|
||||
urlNode1 = urlparse.urlparse(self.nodes[1].url)
|
||||
authpair = urlNode1.username + ':' + urlNode1.password
|
||||
headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
|
||||
|
||||
conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port)
|
||||
conn.connect()
|
||||
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
|
||||
out1 = conn.getresponse().read();
|
||||
assert_equal('"error":null' in out1, True)
|
||||
assert_equal(conn.sock!=None, False) #connection must be closed because keep-alive was set to false
|
||||
|
||||
#node2 (third node) is running with standard keep-alive parameters which means keep-alive is off
|
||||
urlNode2 = urlparse.urlparse(self.nodes[2].url)
|
||||
authpair = urlNode2.username + ':' + urlNode2.password
|
||||
headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
|
||||
|
||||
conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)
|
||||
conn.connect()
|
||||
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
|
||||
out1 = conn.getresponse().read();
|
||||
assert_equal('"error":null' in out1, True)
|
||||
assert_equal(conn.sock!=None, True) #connection must be closed because bitcoind should use keep-alive by default
|
||||
|
||||
if __name__ == '__main__':
|
||||
RESTTest ().main ()
|
||||
HTTPBasicsTest ().main ()
|
||||
|
||||
76
qa/rpc-tests/invalidateblock.py
Executable file
76
qa/rpc-tests/invalidateblock.py
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#
|
||||
# Test InvalidateBlock code
|
||||
#
|
||||
|
||||
from test_framework import BitcoinTestFramework
|
||||
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
|
||||
from util import *
|
||||
|
||||
class InvalidateTest(BitcoinTestFramework):
|
||||
|
||||
|
||||
def setup_chain(self):
|
||||
print("Initializing test directory "+self.options.tmpdir)
|
||||
initialize_chain_clean(self.options.tmpdir, 3)
|
||||
|
||||
def setup_network(self):
|
||||
self.nodes = []
|
||||
self.is_network_split = False
|
||||
self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"]))
|
||||
self.nodes.append(start_node(1, self.options.tmpdir, ["-debug"]))
|
||||
self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"]))
|
||||
|
||||
def run_test(self):
|
||||
print "Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:"
|
||||
print "Mine 4 blocks on Node 0"
|
||||
self.nodes[0].setgenerate(True, 4)
|
||||
assert(self.nodes[0].getblockcount() == 4)
|
||||
besthash = self.nodes[0].getbestblockhash()
|
||||
|
||||
print "Mine competing 6 blocks on Node 1"
|
||||
self.nodes[1].setgenerate(True, 6)
|
||||
assert(self.nodes[1].getblockcount() == 6)
|
||||
|
||||
print "Connect nodes to force a reorg"
|
||||
connect_nodes_bi(self.nodes,0,1)
|
||||
sync_blocks(self.nodes[0:2])
|
||||
assert(self.nodes[0].getblockcount() == 6)
|
||||
badhash = self.nodes[1].getblockhash(2)
|
||||
|
||||
print "Invalidate block 2 on node 0 and verify we reorg to node 0's original chain"
|
||||
self.nodes[0].invalidateblock(badhash)
|
||||
newheight = self.nodes[0].getblockcount()
|
||||
newhash = self.nodes[0].getbestblockhash()
|
||||
if (newheight != 4 or newhash != besthash):
|
||||
raise AssertionError("Wrong tip for node0, hash %s, height %d"%(newhash,newheight))
|
||||
|
||||
print "\nMake sure we won't reorg to a lower work chain:"
|
||||
connect_nodes_bi(self.nodes,1,2)
|
||||
print "Sync node 2 to node 1 so both have 6 blocks"
|
||||
sync_blocks(self.nodes[1:3])
|
||||
assert(self.nodes[2].getblockcount() == 6)
|
||||
print "Invalidate block 5 on node 1 so its tip is now at 4"
|
||||
self.nodes[1].invalidateblock(self.nodes[1].getblockhash(5))
|
||||
assert(self.nodes[1].getblockcount() == 4)
|
||||
print "Invalidate block 3 on node 2, so its tip is now 2"
|
||||
self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3))
|
||||
assert(self.nodes[2].getblockcount() == 2)
|
||||
print "..and then mine a block"
|
||||
self.nodes[2].setgenerate(True, 1)
|
||||
print "Verify all nodes are at the right height"
|
||||
time.sleep(5)
|
||||
for i in xrange(3):
|
||||
print i,self.nodes[i].getblockcount()
|
||||
assert(self.nodes[2].getblockcount() == 3)
|
||||
assert(self.nodes[0].getblockcount() == 4)
|
||||
node1height = self.nodes[1].getblockcount()
|
||||
if node1height < 4:
|
||||
raise AssertionError("Node 1 reorged to a lower height: %d"%node1height)
|
||||
|
||||
if __name__ == '__main__':
|
||||
InvalidateTest().main()
|
||||
34
qa/rpc-tests/reindex.py
Executable file
34
qa/rpc-tests/reindex.py
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#
|
||||
# Test -reindex with CheckBlockIndex
|
||||
#
|
||||
from test_framework import BitcoinTestFramework
|
||||
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
|
||||
from util import *
|
||||
import os.path
|
||||
|
||||
class ReindexTest(BitcoinTestFramework):
|
||||
|
||||
def setup_chain(self):
|
||||
print("Initializing test directory "+self.options.tmpdir)
|
||||
initialize_chain_clean(self.options.tmpdir, 1)
|
||||
|
||||
def setup_network(self):
|
||||
self.nodes = []
|
||||
self.is_network_split = False
|
||||
self.nodes.append(start_node(0, self.options.tmpdir))
|
||||
|
||||
def run_test(self):
|
||||
self.nodes[0].generate(3)
|
||||
stop_node(self.nodes[0], 0)
|
||||
wait_bitcoinds()
|
||||
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex", "-checkblockindex=1"])
|
||||
assert_equal(self.nodes[0].getblockcount(), 3)
|
||||
print "Success"
|
||||
|
||||
if __name__ == '__main__':
|
||||
ReindexTest().main()
|
||||
@@ -16,20 +16,20 @@ class EstimateFeeTest(BitcoinTestFramework):
|
||||
def setup_network(self):
|
||||
self.nodes = []
|
||||
self.nodes.append(start_node(0, self.options.tmpdir,
|
||||
["-debug=mempool", "-debug=estimatefee"]))
|
||||
["-debug=mempool", "-debug=estimatefee", "-relaypriority=0"]))
|
||||
# Node1 mines small-but-not-tiny blocks, and allows free transactions.
|
||||
# NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes,
|
||||
# so blockmaxsize of 2,000 is really just 1,000 bytes (room enough for
|
||||
# 6 or 7 transactions)
|
||||
self.nodes.append(start_node(1, self.options.tmpdir,
|
||||
["-blockprioritysize=1500", "-blockmaxsize=2000",
|
||||
"-debug=mempool", "-debug=estimatefee"]))
|
||||
"-debug=mempool", "-debug=estimatefee", "-relaypriority=0"]))
|
||||
connect_nodes(self.nodes[1], 0)
|
||||
|
||||
# Node2 is a stingy miner, that
|
||||
# produces very small blocks (room for only 3 or so transactions)
|
||||
node2args = [ "-blockprioritysize=0", "-blockmaxsize=1500",
|
||||
"-debug=mempool", "-debug=estimatefee"]
|
||||
"-debug=mempool", "-debug=estimatefee", "-relaypriority=0"]
|
||||
self.nodes.append(start_node(2, self.options.tmpdir, node2args))
|
||||
connect_nodes(self.nodes[2], 0)
|
||||
|
||||
|
||||
@@ -33,8 +33,11 @@ class BitcoinTestFramework(object):
|
||||
print("Initializing test directory "+self.options.tmpdir)
|
||||
initialize_chain(self.options.tmpdir)
|
||||
|
||||
def setup_nodes(self):
|
||||
return start_nodes(4, self.options.tmpdir)
|
||||
|
||||
def setup_network(self, split = False):
|
||||
self.nodes = start_nodes(4, self.options.tmpdir)
|
||||
self.nodes = self.setup_nodes()
|
||||
|
||||
# Connect the nodes as a "chain". This allows us
|
||||
# to split the network between nodes 1 and 2 to get
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,8 @@ EXTRA_DIST += \
|
||||
test/data/tt-locktime317000-out.hex \
|
||||
test/data/tx394b54bb.hex \
|
||||
test/data/txcreate1.hex \
|
||||
test/data/txcreate2.hex
|
||||
test/data/txcreate2.hex \
|
||||
test/data/txcreatesign.hex
|
||||
|
||||
JSON_TEST_FILES = \
|
||||
test/data/script_valid.json \
|
||||
@@ -50,12 +51,14 @@ BITCOIN_TESTS =\
|
||||
test/hash_tests.cpp \
|
||||
test/key_tests.cpp \
|
||||
test/main_tests.cpp \
|
||||
test/mempool_tests.cpp \
|
||||
test/miner_tests.cpp \
|
||||
test/mruset_tests.cpp \
|
||||
test/multisig_tests.cpp \
|
||||
test/netbase_tests.cpp \
|
||||
test/pmt_tests.cpp \
|
||||
test/rpc_tests.cpp \
|
||||
test/sanity_tests.cpp \
|
||||
test/script_P2SH_tests.cpp \
|
||||
test/script_tests.cpp \
|
||||
test/scriptnum_tests.cpp \
|
||||
|
||||
301
src/addrman.cpp
301
src/addrman.cpp
@@ -10,34 +10,27 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
int CAddrInfo::GetTriedBucket(const std::vector<unsigned char>& nKey) const
|
||||
int CAddrInfo::GetTriedBucket(const uint256& nKey) const
|
||||
{
|
||||
CDataStream ss1(SER_GETHASH, 0);
|
||||
std::vector<unsigned char> vchKey = GetKey();
|
||||
ss1 << nKey << vchKey;
|
||||
uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetLow64();
|
||||
|
||||
CDataStream ss2(SER_GETHASH, 0);
|
||||
std::vector<unsigned char> vchGroupKey = GetGroup();
|
||||
ss2 << nKey << vchGroupKey << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP);
|
||||
uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetLow64();
|
||||
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetKey()).GetHash().GetLow64();
|
||||
uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP)).GetHash().GetLow64();
|
||||
return hash2 % ADDRMAN_TRIED_BUCKET_COUNT;
|
||||
}
|
||||
|
||||
int CAddrInfo::GetNewBucket(const std::vector<unsigned char>& nKey, const CNetAddr& src) const
|
||||
int CAddrInfo::GetNewBucket(const uint256& nKey, const CNetAddr& src) const
|
||||
{
|
||||
CDataStream ss1(SER_GETHASH, 0);
|
||||
std::vector<unsigned char> vchGroupKey = GetGroup();
|
||||
std::vector<unsigned char> vchSourceGroupKey = src.GetGroup();
|
||||
ss1 << nKey << vchGroupKey << vchSourceGroupKey;
|
||||
uint64_t hash1 = Hash(ss1.begin(), ss1.end()).GetLow64();
|
||||
|
||||
CDataStream ss2(SER_GETHASH, 0);
|
||||
ss2 << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP);
|
||||
uint64_t hash2 = Hash(ss2.begin(), ss2.end()).GetLow64();
|
||||
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << vchSourceGroupKey).GetHash().GetLow64();
|
||||
uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP)).GetHash().GetLow64();
|
||||
return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
|
||||
}
|
||||
|
||||
int CAddrInfo::GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const
|
||||
{
|
||||
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << (fNew ? 'N' : 'K') << nBucket << GetKey()).GetHash().GetLow64();
|
||||
return hash1 % ADDRMAN_BUCKET_SIZE;
|
||||
}
|
||||
|
||||
bool CAddrInfo::IsTerrible(int64_t nNow) const
|
||||
{
|
||||
if (nLastTry && nLastTry >= nNow - 60) // never remove things tried in the last minute
|
||||
@@ -70,15 +63,12 @@ double CAddrInfo::GetChance(int64_t nNow) const
|
||||
if (nSinceLastTry < 0)
|
||||
nSinceLastTry = 0;
|
||||
|
||||
fChance *= 600.0 / (600.0 + nSinceLastSeen);
|
||||
|
||||
// deprioritize very recent attempts away
|
||||
if (nSinceLastTry < 60 * 10)
|
||||
fChance *= 0.01;
|
||||
|
||||
// deprioritize 50% after each failed attempt
|
||||
for (int n = 0; n < nAttempts; n++)
|
||||
fChance /= 1.5;
|
||||
// deprioritize 66% after each failed attempt, but at most 1/28th to avoid the search taking forever or overly penalizing outages.
|
||||
fChance *= pow(0.66, min(nAttempts, 8));
|
||||
|
||||
return fChance;
|
||||
}
|
||||
@@ -128,85 +118,44 @@ void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2)
|
||||
vRandom[nRndPos2] = nId1;
|
||||
}
|
||||
|
||||
int CAddrMan::SelectTried(int nKBucket)
|
||||
void CAddrMan::Delete(int nId)
|
||||
{
|
||||
std::vector<int>& vTried = vvTried[nKBucket];
|
||||
assert(mapInfo.count(nId) != 0);
|
||||
CAddrInfo& info = mapInfo[nId];
|
||||
assert(!info.fInTried);
|
||||
assert(info.nRefCount == 0);
|
||||
|
||||
// randomly shuffle the first few elements (using the entire list)
|
||||
// find the least recently tried among them
|
||||
int64_t nOldest = -1;
|
||||
int nOldestPos = -1;
|
||||
for (unsigned int i = 0; i < ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i < vTried.size(); i++) {
|
||||
int nPos = GetRandInt(vTried.size() - i) + i;
|
||||
int nTemp = vTried[nPos];
|
||||
vTried[nPos] = vTried[i];
|
||||
vTried[i] = nTemp;
|
||||
assert(nOldest == -1 || mapInfo.count(nTemp) == 1);
|
||||
if (nOldest == -1 || mapInfo[nTemp].nLastSuccess < mapInfo[nOldest].nLastSuccess) {
|
||||
nOldest = nTemp;
|
||||
nOldestPos = nPos;
|
||||
}
|
||||
}
|
||||
|
||||
return nOldestPos;
|
||||
SwapRandom(info.nRandomPos, vRandom.size() - 1);
|
||||
vRandom.pop_back();
|
||||
mapAddr.erase(info);
|
||||
mapInfo.erase(nId);
|
||||
nNew--;
|
||||
}
|
||||
|
||||
int CAddrMan::ShrinkNew(int nUBucket)
|
||||
void CAddrMan::ClearNew(int nUBucket, int nUBucketPos)
|
||||
{
|
||||
assert(nUBucket >= 0 && (unsigned int)nUBucket < vvNew.size());
|
||||
std::set<int>& vNew = vvNew[nUBucket];
|
||||
|
||||
// first look for deletable items
|
||||
for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) {
|
||||
assert(mapInfo.count(*it));
|
||||
CAddrInfo& info = mapInfo[*it];
|
||||
if (info.IsTerrible()) {
|
||||
if (--info.nRefCount == 0) {
|
||||
SwapRandom(info.nRandomPos, vRandom.size() - 1);
|
||||
vRandom.pop_back();
|
||||
mapAddr.erase(info);
|
||||
mapInfo.erase(*it);
|
||||
nNew--;
|
||||
}
|
||||
vNew.erase(it);
|
||||
return 0;
|
||||
// if there is an entry in the specified bucket, delete it.
|
||||
if (vvNew[nUBucket][nUBucketPos] != -1) {
|
||||
int nIdDelete = vvNew[nUBucket][nUBucketPos];
|
||||
CAddrInfo& infoDelete = mapInfo[nIdDelete];
|
||||
assert(infoDelete.nRefCount > 0);
|
||||
infoDelete.nRefCount--;
|
||||
vvNew[nUBucket][nUBucketPos] = -1;
|
||||
if (infoDelete.nRefCount == 0) {
|
||||
Delete(nIdDelete);
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise, select four randomly, and pick the oldest of those to replace
|
||||
int n[4] = {GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size())};
|
||||
int nI = 0;
|
||||
int nOldest = -1;
|
||||
for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) {
|
||||
if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3]) {
|
||||
assert(nOldest == -1 || mapInfo.count(*it) == 1);
|
||||
if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime)
|
||||
nOldest = *it;
|
||||
}
|
||||
nI++;
|
||||
}
|
||||
assert(mapInfo.count(nOldest) == 1);
|
||||
CAddrInfo& info = mapInfo[nOldest];
|
||||
if (--info.nRefCount == 0) {
|
||||
SwapRandom(info.nRandomPos, vRandom.size() - 1);
|
||||
vRandom.pop_back();
|
||||
mapAddr.erase(info);
|
||||
mapInfo.erase(nOldest);
|
||||
nNew--;
|
||||
}
|
||||
vNew.erase(nOldest);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
|
||||
void CAddrMan::MakeTried(CAddrInfo& info, int nId)
|
||||
{
|
||||
assert(vvNew[nOrigin].count(nId) == 1);
|
||||
|
||||
// remove the entry from all new buckets
|
||||
for (std::vector<std::set<int> >::iterator it = vvNew.begin(); it != vvNew.end(); it++) {
|
||||
if ((*it).erase(nId))
|
||||
for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
|
||||
int pos = info.GetBucketPosition(nKey, true, bucket);
|
||||
if (vvNew[bucket][pos] == nId) {
|
||||
vvNew[bucket][pos] = -1;
|
||||
info.nRefCount--;
|
||||
}
|
||||
}
|
||||
nNew--;
|
||||
|
||||
@@ -214,44 +163,36 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
|
||||
|
||||
// which tried bucket to move the entry to
|
||||
int nKBucket = info.GetTriedBucket(nKey);
|
||||
std::vector<int>& vTried = vvTried[nKBucket];
|
||||
int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
|
||||
|
||||
// first check whether there is place to just add it
|
||||
if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) {
|
||||
vTried.push_back(nId);
|
||||
nTried++;
|
||||
info.fInTried = true;
|
||||
return;
|
||||
// first make space to add it (the existing tried entry there is moved to new, deleting whatever is there).
|
||||
if (vvTried[nKBucket][nKBucketPos] != -1) {
|
||||
// find an item to evict
|
||||
int nIdEvict = vvTried[nKBucket][nKBucketPos];
|
||||
assert(mapInfo.count(nIdEvict) == 1);
|
||||
CAddrInfo& infoOld = mapInfo[nIdEvict];
|
||||
|
||||
// Remove the to-be-evicted item from the tried set.
|
||||
infoOld.fInTried = false;
|
||||
vvTried[nKBucket][nKBucketPos] = -1;
|
||||
nTried--;
|
||||
|
||||
// find which new bucket it belongs to
|
||||
int nUBucket = infoOld.GetNewBucket(nKey);
|
||||
int nUBucketPos = infoOld.GetBucketPosition(nKey, true, nUBucket);
|
||||
ClearNew(nUBucket, nUBucketPos);
|
||||
assert(vvNew[nUBucket][nUBucketPos] == -1);
|
||||
|
||||
// Enter it into the new set again.
|
||||
infoOld.nRefCount = 1;
|
||||
vvNew[nUBucket][nUBucketPos] = nIdEvict;
|
||||
nNew++;
|
||||
}
|
||||
assert(vvTried[nKBucket][nKBucketPos] == -1);
|
||||
|
||||
// otherwise, find an item to evict
|
||||
int nPos = SelectTried(nKBucket);
|
||||
|
||||
// find which new bucket it belongs to
|
||||
assert(mapInfo.count(vTried[nPos]) == 1);
|
||||
int nUBucket = mapInfo[vTried[nPos]].GetNewBucket(nKey);
|
||||
std::set<int>& vNew = vvNew[nUBucket];
|
||||
|
||||
// remove the to-be-replaced tried entry from the tried set
|
||||
CAddrInfo& infoOld = mapInfo[vTried[nPos]];
|
||||
infoOld.fInTried = false;
|
||||
infoOld.nRefCount = 1;
|
||||
// do not update nTried, as we are going to move something else there immediately
|
||||
|
||||
// check whether there is place in that one,
|
||||
if (vNew.size() < ADDRMAN_NEW_BUCKET_SIZE) {
|
||||
// if so, move it back there
|
||||
vNew.insert(vTried[nPos]);
|
||||
} else {
|
||||
// otherwise, move it to the new bucket nId came from (there is certainly place there)
|
||||
vvNew[nOrigin].insert(vTried[nPos]);
|
||||
}
|
||||
nNew++;
|
||||
|
||||
vTried[nPos] = nId;
|
||||
// we just overwrote an entry in vTried; no need to update nTried
|
||||
vvTried[nKBucket][nKBucketPos] = nId;
|
||||
nTried++;
|
||||
info.fInTried = true;
|
||||
return;
|
||||
}
|
||||
|
||||
void CAddrMan::Good_(const CService& addr, int64_t nTime)
|
||||
@@ -272,20 +213,21 @@ void CAddrMan::Good_(const CService& addr, int64_t nTime)
|
||||
// update info
|
||||
info.nLastSuccess = nTime;
|
||||
info.nLastTry = nTime;
|
||||
info.nTime = nTime;
|
||||
info.nAttempts = 0;
|
||||
// nTime is not updated here, to avoid leaking information about
|
||||
// currently-connected peers.
|
||||
|
||||
// if it is already in the tried set, don't do anything else
|
||||
if (info.fInTried)
|
||||
return;
|
||||
|
||||
// find a bucket it is in now
|
||||
int nRnd = GetRandInt(vvNew.size());
|
||||
int nRnd = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT);
|
||||
int nUBucket = -1;
|
||||
for (unsigned int n = 0; n < vvNew.size(); n++) {
|
||||
int nB = (n + nRnd) % vvNew.size();
|
||||
std::set<int>& vNew = vvNew[nB];
|
||||
if (vNew.count(nId)) {
|
||||
for (unsigned int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
|
||||
int nB = (n + nRnd) % ADDRMAN_NEW_BUCKET_COUNT;
|
||||
int nBpos = info.GetBucketPosition(nKey, true, nB);
|
||||
if (vvNew[nB][nBpos] == nId) {
|
||||
nUBucket = nB;
|
||||
break;
|
||||
}
|
||||
@@ -299,7 +241,7 @@ void CAddrMan::Good_(const CService& addr, int64_t nTime)
|
||||
LogPrint("addrman", "Moving %s to tried\n", addr.ToString());
|
||||
|
||||
// move nId to the tried tables
|
||||
MakeTried(info, nId, nUBucket);
|
||||
MakeTried(info, nId);
|
||||
}
|
||||
|
||||
bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty)
|
||||
@@ -347,12 +289,25 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP
|
||||
}
|
||||
|
||||
int nUBucket = pinfo->GetNewBucket(nKey, source);
|
||||
std::set<int>& vNew = vvNew[nUBucket];
|
||||
if (!vNew.count(nId)) {
|
||||
pinfo->nRefCount++;
|
||||
if (vNew.size() == ADDRMAN_NEW_BUCKET_SIZE)
|
||||
ShrinkNew(nUBucket);
|
||||
vvNew[nUBucket].insert(nId);
|
||||
int nUBucketPos = pinfo->GetBucketPosition(nKey, true, nUBucket);
|
||||
if (vvNew[nUBucket][nUBucketPos] != nId) {
|
||||
bool fInsert = vvNew[nUBucket][nUBucketPos] == -1;
|
||||
if (!fInsert) {
|
||||
CAddrInfo& infoExisting = mapInfo[vvNew[nUBucket][nUBucketPos]];
|
||||
if (infoExisting.IsTerrible() || (infoExisting.nRefCount > 1 && pinfo->nRefCount == 0)) {
|
||||
// Overwrite the existing new table entry.
|
||||
fInsert = true;
|
||||
}
|
||||
}
|
||||
if (fInsert) {
|
||||
ClearNew(nUBucket, nUBucketPos);
|
||||
pinfo->nRefCount++;
|
||||
vvNew[nUBucket][nUBucketPos] = nId;
|
||||
} else {
|
||||
if (pinfo->nRefCount == 0) {
|
||||
Delete(nId);
|
||||
}
|
||||
}
|
||||
}
|
||||
return fNew;
|
||||
}
|
||||
@@ -376,24 +331,23 @@ void CAddrMan::Attempt_(const CService& addr, int64_t nTime)
|
||||
info.nAttempts++;
|
||||
}
|
||||
|
||||
CAddress CAddrMan::Select_(int nUnkBias)
|
||||
CAddress CAddrMan::Select_()
|
||||
{
|
||||
if (size() == 0)
|
||||
return CAddress();
|
||||
|
||||
double nCorTried = sqrt(nTried) * (100.0 - nUnkBias);
|
||||
double nCorNew = sqrt(nNew) * nUnkBias;
|
||||
if ((nCorTried + nCorNew) * GetRandInt(1 << 30) / (1 << 30) < nCorTried) {
|
||||
// Use a 50% chance for choosing between tried and new table entries.
|
||||
if (nTried > 0 && (nNew == 0 || GetRandInt(2) == 0)) {
|
||||
// use a tried node
|
||||
double fChanceFactor = 1.0;
|
||||
while (1) {
|
||||
int nKBucket = GetRandInt(vvTried.size());
|
||||
std::vector<int>& vTried = vvTried[nKBucket];
|
||||
if (vTried.size() == 0)
|
||||
int nKBucket = GetRandInt(ADDRMAN_TRIED_BUCKET_COUNT);
|
||||
int nKBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
|
||||
if (vvTried[nKBucket][nKBucketPos] == -1)
|
||||
continue;
|
||||
int nPos = GetRandInt(vTried.size());
|
||||
assert(mapInfo.count(vTried[nPos]) == 1);
|
||||
CAddrInfo& info = mapInfo[vTried[nPos]];
|
||||
int nId = vvTried[nKBucket][nKBucketPos];
|
||||
assert(mapInfo.count(nId) == 1);
|
||||
CAddrInfo& info = mapInfo[nId];
|
||||
if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
|
||||
return info;
|
||||
fChanceFactor *= 1.2;
|
||||
@@ -402,16 +356,13 @@ CAddress CAddrMan::Select_(int nUnkBias)
|
||||
// use a new node
|
||||
double fChanceFactor = 1.0;
|
||||
while (1) {
|
||||
int nUBucket = GetRandInt(vvNew.size());
|
||||
std::set<int>& vNew = vvNew[nUBucket];
|
||||
if (vNew.size() == 0)
|
||||
int nUBucket = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT);
|
||||
int nUBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE);
|
||||
if (vvNew[nUBucket][nUBucketPos] == -1)
|
||||
continue;
|
||||
int nPos = GetRandInt(vNew.size());
|
||||
std::set<int>::iterator it = vNew.begin();
|
||||
while (nPos--)
|
||||
it++;
|
||||
assert(mapInfo.count(*it) == 1);
|
||||
CAddrInfo& info = mapInfo[*it];
|
||||
int nId = vvNew[nUBucket][nUBucketPos];
|
||||
assert(mapInfo.count(nId) == 1);
|
||||
CAddrInfo& info = mapInfo[nId];
|
||||
if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30))
|
||||
return info;
|
||||
fChanceFactor *= 1.2;
|
||||
@@ -459,22 +410,30 @@ int CAddrMan::Check_()
|
||||
if (mapNew.size() != nNew)
|
||||
return -10;
|
||||
|
||||
for (int n = 0; n < vvTried.size(); n++) {
|
||||
std::vector<int>& vTried = vvTried[n];
|
||||
for (std::vector<int>::iterator it = vTried.begin(); it != vTried.end(); it++) {
|
||||
if (!setTried.count(*it))
|
||||
return -11;
|
||||
setTried.erase(*it);
|
||||
for (int n = 0; n < ADDRMAN_TRIED_BUCKET_COUNT; n++) {
|
||||
for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
|
||||
if (vvTried[n][i] != -1) {
|
||||
if (!setTried.count(vvTried[n][i]))
|
||||
return -11;
|
||||
if (mapInfo[vvTried[n][i]].GetTriedBucket(nKey) != n)
|
||||
return -17;
|
||||
if (mapInfo[vvTried[n][i]].GetBucketPosition(nKey, false, n) != i)
|
||||
return -18;
|
||||
setTried.erase(vvTried[n][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int n = 0; n < vvNew.size(); n++) {
|
||||
std::set<int>& vNew = vvNew[n];
|
||||
for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++) {
|
||||
if (!mapNew.count(*it))
|
||||
return -12;
|
||||
if (--mapNew[*it] == 0)
|
||||
mapNew.erase(*it);
|
||||
for (int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) {
|
||||
for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
|
||||
if (vvNew[n][i] != -1) {
|
||||
if (!mapNew.count(vvNew[n][i]))
|
||||
return -12;
|
||||
if (mapInfo[vvNew[n][i]].GetBucketPosition(nKey, true, n) != i)
|
||||
return -19;
|
||||
if (--mapNew[vvNew[n][i]] == 0)
|
||||
mapNew.erase(vvNew[n][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,6 +441,8 @@ int CAddrMan::Check_()
|
||||
return -13;
|
||||
if (mapNew.size())
|
||||
return -15;
|
||||
if (nKey.IsNull())
|
||||
return -16;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
210
src/addrman.h
210
src/addrman.h
@@ -79,17 +79,20 @@ public:
|
||||
}
|
||||
|
||||
//! Calculate in which "tried" bucket this entry belongs
|
||||
int GetTriedBucket(const std::vector<unsigned char> &nKey) const;
|
||||
int GetTriedBucket(const uint256 &nKey) const;
|
||||
|
||||
//! Calculate in which "new" bucket this entry belongs, given a certain source
|
||||
int GetNewBucket(const std::vector<unsigned char> &nKey, const CNetAddr& src) const;
|
||||
int GetNewBucket(const uint256 &nKey, const CNetAddr& src) const;
|
||||
|
||||
//! Calculate in which "new" bucket this entry belongs, using its default source
|
||||
int GetNewBucket(const std::vector<unsigned char> &nKey) const
|
||||
int GetNewBucket(const uint256 &nKey) const
|
||||
{
|
||||
return GetNewBucket(nKey, source);
|
||||
}
|
||||
|
||||
//! Calculate in which position of a bucket to store this entry.
|
||||
int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const;
|
||||
|
||||
//! Determine whether the statistics about this entry are bad enough so that it can just be deleted
|
||||
bool IsTerrible(int64_t nNow = GetAdjustedTime()) const;
|
||||
|
||||
@@ -106,15 +109,15 @@ public:
|
||||
*
|
||||
* To that end:
|
||||
* * Addresses are organized into buckets.
|
||||
* * Address that have not yet been tried go into 256 "new" buckets.
|
||||
* * Based on the address range (/16 for IPv4) of source of the information, 32 buckets are selected at random
|
||||
* * Address that have not yet been tried go into 1024 "new" buckets.
|
||||
* * Based on the address range (/16 for IPv4) of source of the information, 64 buckets are selected at random
|
||||
* * The actual bucket is chosen from one of these, based on the range the address itself is located.
|
||||
* * One single address can occur in up to 4 different buckets, to increase selection chances for addresses that
|
||||
* * One single address can occur in up to 8 different buckets, to increase selection chances for addresses that
|
||||
* are seen frequently. The chance for increasing this multiplicity decreases exponentially.
|
||||
* * When adding a new address to a full bucket, a randomly chosen entry (with a bias favoring less recently seen
|
||||
* ones) is removed from it first.
|
||||
* * Addresses of nodes that are known to be accessible go into 64 "tried" buckets.
|
||||
* * Each address range selects at random 4 of these buckets.
|
||||
* * Addresses of nodes that are known to be accessible go into 256 "tried" buckets.
|
||||
* * Each address range selects at random 8 of these buckets.
|
||||
* * The actual bucket is chosen from one of these, based on the full address.
|
||||
* * When adding a new good address to a full bucket, a randomly chosen entry (with a bias favoring less recently
|
||||
* tried ones) is evicted from it, back to the "new" buckets.
|
||||
@@ -125,28 +128,22 @@ public:
|
||||
*/
|
||||
|
||||
//! total number of buckets for tried addresses
|
||||
#define ADDRMAN_TRIED_BUCKET_COUNT 64
|
||||
|
||||
//! maximum allowed number of entries in buckets for tried addresses
|
||||
#define ADDRMAN_TRIED_BUCKET_SIZE 64
|
||||
#define ADDRMAN_TRIED_BUCKET_COUNT 256
|
||||
|
||||
//! total number of buckets for new addresses
|
||||
#define ADDRMAN_NEW_BUCKET_COUNT 256
|
||||
#define ADDRMAN_NEW_BUCKET_COUNT 1024
|
||||
|
||||
//! maximum allowed number of entries in buckets for new addresses
|
||||
#define ADDRMAN_NEW_BUCKET_SIZE 64
|
||||
//! maximum allowed number of entries in buckets for new and tried addresses
|
||||
#define ADDRMAN_BUCKET_SIZE 64
|
||||
|
||||
//! over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread
|
||||
#define ADDRMAN_TRIED_BUCKETS_PER_GROUP 4
|
||||
#define ADDRMAN_TRIED_BUCKETS_PER_GROUP 8
|
||||
|
||||
//! over how many buckets entries with new addresses originating from a single group are spread
|
||||
#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 32
|
||||
#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 64
|
||||
|
||||
//! in how many buckets for entries with new addresses a single address may occur
|
||||
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 4
|
||||
|
||||
//! how many entries in a bucket with tried addresses are inspected, when selecting one to replace
|
||||
#define ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT 4
|
||||
#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 8
|
||||
|
||||
//! how old addresses can maximally be
|
||||
#define ADDRMAN_HORIZON_DAYS 30
|
||||
@@ -176,7 +173,7 @@ private:
|
||||
mutable CCriticalSection cs;
|
||||
|
||||
//! secret key to randomize bucket select with
|
||||
std::vector<unsigned char> nKey;
|
||||
uint256 nKey;
|
||||
|
||||
//! last used nId
|
||||
int nIdCount;
|
||||
@@ -194,13 +191,13 @@ private:
|
||||
int nTried;
|
||||
|
||||
//! list of "tried" buckets
|
||||
std::vector<std::vector<int> > vvTried;
|
||||
int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE];
|
||||
|
||||
//! number of (unique) "new" entries
|
||||
int nNew;
|
||||
|
||||
//! list of "new" buckets
|
||||
std::vector<std::set<int> > vvNew;
|
||||
int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE];
|
||||
|
||||
protected:
|
||||
|
||||
@@ -214,17 +211,14 @@ protected:
|
||||
//! Swap two elements in vRandom.
|
||||
void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2);
|
||||
|
||||
//! Return position in given bucket to replace.
|
||||
int SelectTried(int nKBucket);
|
||||
|
||||
//! Remove an element from a "new" bucket.
|
||||
//! This is the only place where actual deletions occur.
|
||||
//! Elements are never deleted while in the "tried" table, only possibly evicted back to the "new" table.
|
||||
int ShrinkNew(int nUBucket);
|
||||
|
||||
//! Move an entry from the "new" table(s) to the "tried" table
|
||||
//! @pre vvUnkown[nOrigin].count(nId) != 0
|
||||
void MakeTried(CAddrInfo& info, int nId, int nOrigin);
|
||||
void MakeTried(CAddrInfo& info, int nId);
|
||||
|
||||
//! Delete an entry. It must not be in tried, and have refcount 0.
|
||||
void Delete(int nId);
|
||||
|
||||
//! Clear a position in a "new" table. This is the only place where entries are actually deleted.
|
||||
void ClearNew(int nUBucket, int nUBucketPos);
|
||||
|
||||
//! Mark an entry "good", possibly moving it from "new" to "tried".
|
||||
void Good_(const CService &addr, int64_t nTime);
|
||||
@@ -237,7 +231,7 @@ protected:
|
||||
|
||||
//! Select an address to connect to.
|
||||
//! nUnkBias determines how much to favor new addresses over tried ones (min=0, max=100)
|
||||
CAddress Select_(int nUnkBias);
|
||||
CAddress Select_();
|
||||
|
||||
#ifdef DEBUG_ADDRMAN
|
||||
//! Perform consistency check. Returns an error code or zero.
|
||||
@@ -253,21 +247,25 @@ protected:
|
||||
public:
|
||||
/**
|
||||
* serialized format:
|
||||
* * version byte (currently 0)
|
||||
* * nKey
|
||||
* * version byte (currently 1)
|
||||
* * 0x20 + nKey (serialized as if it were a vector, for backward compatibility)
|
||||
* * nNew
|
||||
* * nTried
|
||||
* * number of "new" buckets
|
||||
* * number of "new" buckets XOR 2**30
|
||||
* * all nNew addrinfos in vvNew
|
||||
* * all nTried addrinfos in vvTried
|
||||
* * for each bucket:
|
||||
* * number of elements
|
||||
* * for each element: index
|
||||
*
|
||||
* 2**30 is xorred with the number of buckets to make addrman deserializer v0 detect it
|
||||
* as incompatible. This is necessary because it did not check the version number on
|
||||
* deserialization.
|
||||
*
|
||||
* Notice that vvTried, mapAddr and vVector are never encoded explicitly;
|
||||
* they are instead reconstructed from the other information.
|
||||
*
|
||||
* vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change,
|
||||
* vvNew is serialized, but only used if ADDRMAN_UNKNOWN_BUCKET_COUNT didn't change,
|
||||
* otherwise it is reconstructed as well.
|
||||
*
|
||||
* This format is more complex, but significantly smaller (at most 1.5 MiB), and supports
|
||||
@@ -275,48 +273,53 @@ public:
|
||||
*
|
||||
* We don't use ADD_SERIALIZE_METHODS since the serialization and deserialization code has
|
||||
* very little in common.
|
||||
*
|
||||
*/
|
||||
template<typename Stream>
|
||||
void Serialize(Stream &s, int nType, int nVersionDummy) const
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
unsigned char nVersion = 0;
|
||||
unsigned char nVersion = 1;
|
||||
s << nVersion;
|
||||
s << ((unsigned char)32);
|
||||
s << nKey;
|
||||
s << nNew;
|
||||
s << nTried;
|
||||
|
||||
int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT;
|
||||
int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
|
||||
s << nUBuckets;
|
||||
std::map<int, int> mapUnkIds;
|
||||
int nIds = 0;
|
||||
for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) {
|
||||
if (nIds == nNew) break; // this means nNew was wrong, oh ow
|
||||
mapUnkIds[(*it).first] = nIds;
|
||||
const CAddrInfo &info = (*it).second;
|
||||
if (info.nRefCount) {
|
||||
assert(nIds != nNew); // this means nNew was wrong, oh ow
|
||||
s << info;
|
||||
nIds++;
|
||||
}
|
||||
}
|
||||
nIds = 0;
|
||||
for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) {
|
||||
if (nIds == nTried) break; // this means nTried was wrong, oh ow
|
||||
const CAddrInfo &info = (*it).second;
|
||||
if (info.fInTried) {
|
||||
assert(nIds != nTried); // this means nTried was wrong, oh ow
|
||||
s << info;
|
||||
nIds++;
|
||||
}
|
||||
}
|
||||
for (std::vector<std::set<int> >::const_iterator it = vvNew.begin(); it != vvNew.end(); it++) {
|
||||
const std::set<int> &vNew = (*it);
|
||||
int nSize = vNew.size();
|
||||
for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
|
||||
int nSize = 0;
|
||||
for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
|
||||
if (vvNew[bucket][i] != -1)
|
||||
nSize++;
|
||||
}
|
||||
s << nSize;
|
||||
for (std::set<int>::const_iterator it2 = vNew.begin(); it2 != vNew.end(); it2++) {
|
||||
int nIndex = mapUnkIds[*it2];
|
||||
s << nIndex;
|
||||
for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) {
|
||||
if (vvNew[bucket][i] != -1) {
|
||||
int nIndex = mapUnkIds[vvNew[bucket][i]];
|
||||
s << nIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -326,64 +329,97 @@ public:
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
Clear();
|
||||
|
||||
unsigned char nVersion;
|
||||
s >> nVersion;
|
||||
unsigned char nKeySize;
|
||||
s >> nKeySize;
|
||||
if (nKeySize != 32) throw std::ios_base::failure("Incorrect keysize in addrman deserialization");
|
||||
s >> nKey;
|
||||
s >> nNew;
|
||||
s >> nTried;
|
||||
|
||||
int nUBuckets = 0;
|
||||
s >> nUBuckets;
|
||||
nIdCount = 0;
|
||||
mapInfo.clear();
|
||||
mapAddr.clear();
|
||||
vRandom.clear();
|
||||
vvTried = std::vector<std::vector<int> >(ADDRMAN_TRIED_BUCKET_COUNT, std::vector<int>(0));
|
||||
vvNew = std::vector<std::set<int> >(ADDRMAN_NEW_BUCKET_COUNT, std::set<int>());
|
||||
if (nVersion != 0) {
|
||||
nUBuckets ^= (1 << 30);
|
||||
}
|
||||
|
||||
// Deserialize entries from the new table.
|
||||
for (int n = 0; n < nNew; n++) {
|
||||
CAddrInfo &info = mapInfo[n];
|
||||
s >> info;
|
||||
mapAddr[info] = n;
|
||||
info.nRandomPos = vRandom.size();
|
||||
vRandom.push_back(n);
|
||||
if (nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) {
|
||||
vvNew[info.GetNewBucket(nKey)].insert(n);
|
||||
info.nRefCount++;
|
||||
if (nVersion != 1 || nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) {
|
||||
// In case the new table data cannot be used (nVersion unknown, or bucket count wrong),
|
||||
// immediately try to give them a reference based on their primary source address.
|
||||
int nUBucket = info.GetNewBucket(nKey);
|
||||
int nUBucketPos = info.GetBucketPosition(nKey, true, nUBucket);
|
||||
if (vvNew[nUBucket][nUBucketPos] == -1) {
|
||||
vvNew[nUBucket][nUBucketPos] = n;
|
||||
info.nRefCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
nIdCount = nNew;
|
||||
|
||||
// Deserialize entries from the tried table.
|
||||
int nLost = 0;
|
||||
for (int n = 0; n < nTried; n++) {
|
||||
CAddrInfo info;
|
||||
s >> info;
|
||||
std::vector<int> &vTried = vvTried[info.GetTriedBucket(nKey)];
|
||||
if (vTried.size() < ADDRMAN_TRIED_BUCKET_SIZE) {
|
||||
int nKBucket = info.GetTriedBucket(nKey);
|
||||
int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket);
|
||||
if (vvTried[nKBucket][nKBucketPos] == -1) {
|
||||
info.nRandomPos = vRandom.size();
|
||||
info.fInTried = true;
|
||||
vRandom.push_back(nIdCount);
|
||||
mapInfo[nIdCount] = info;
|
||||
mapAddr[info] = nIdCount;
|
||||
vTried.push_back(nIdCount);
|
||||
vvTried[nKBucket][nKBucketPos] = nIdCount;
|
||||
nIdCount++;
|
||||
} else {
|
||||
nLost++;
|
||||
}
|
||||
}
|
||||
nTried -= nLost;
|
||||
for (int b = 0; b < nUBuckets; b++) {
|
||||
std::set<int> &vNew = vvNew[b];
|
||||
|
||||
// Deserialize positions in the new table (if possible).
|
||||
for (int bucket = 0; bucket < nUBuckets; bucket++) {
|
||||
int nSize = 0;
|
||||
s >> nSize;
|
||||
for (int n = 0; n < nSize; n++) {
|
||||
int nIndex = 0;
|
||||
s >> nIndex;
|
||||
CAddrInfo &info = mapInfo[nIndex];
|
||||
if (nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) {
|
||||
info.nRefCount++;
|
||||
vNew.insert(nIndex);
|
||||
if (nIndex >= 0 && nIndex < nNew) {
|
||||
CAddrInfo &info = mapInfo[nIndex];
|
||||
int nUBucketPos = info.GetBucketPosition(nKey, true, bucket);
|
||||
if (nVersion == 1 && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket][nUBucketPos] == -1 && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) {
|
||||
info.nRefCount++;
|
||||
vvNew[bucket][nUBucketPos] = nIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prune new entries with refcount 0 (as a result of collisions).
|
||||
int nLostUnk = 0;
|
||||
for (std::map<int, CAddrInfo>::const_iterator it = mapInfo.begin(); it != mapInfo.end(); ) {
|
||||
if (it->second.fInTried == false && it->second.nRefCount == 0) {
|
||||
std::map<int, CAddrInfo>::const_iterator itCopy = it++;
|
||||
Delete(itCopy->first);
|
||||
nLostUnk++;
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
if (nLost + nLostUnk > 0) {
|
||||
LogPrint("addrman", "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost);
|
||||
}
|
||||
|
||||
Check();
|
||||
}
|
||||
|
||||
unsigned int GetSerializeSize(int nType, int nVersion) const
|
||||
@@ -391,14 +427,34 @@ public:
|
||||
return (CSizeComputer(nType, nVersion) << *this).size();
|
||||
}
|
||||
|
||||
CAddrMan() : vRandom(0), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector<int>(0)), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set<int>())
|
||||
void Clear()
|
||||
{
|
||||
nKey.resize(32);
|
||||
GetRandBytes(&nKey[0], 32);
|
||||
std::vector<int>().swap(vRandom);
|
||||
nKey = GetRandHash();
|
||||
for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) {
|
||||
for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
|
||||
vvNew[bucket][entry] = -1;
|
||||
}
|
||||
}
|
||||
for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) {
|
||||
for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) {
|
||||
vvTried[bucket][entry] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
nIdCount = 0;
|
||||
nTried = 0;
|
||||
nNew = 0;
|
||||
nIdCount = 0;
|
||||
nTried = 0;
|
||||
nNew = 0;
|
||||
}
|
||||
|
||||
CAddrMan()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
~CAddrMan()
|
||||
{
|
||||
nKey = uint256(0);
|
||||
}
|
||||
|
||||
//! Return the number of (unique) addresses in all tables.
|
||||
@@ -477,13 +533,13 @@ public:
|
||||
* Choose an address to connect to.
|
||||
* nUnkBias determines how much "new" entries are favored over "tried" ones (0-100).
|
||||
*/
|
||||
CAddress Select(int nUnkBias = 50)
|
||||
CAddress Select()
|
||||
{
|
||||
CAddress addrRet;
|
||||
{
|
||||
LOCK(cs);
|
||||
Check();
|
||||
addrRet = Select_(nUnkBias);
|
||||
addrRet = Select_();
|
||||
Check();
|
||||
}
|
||||
return addrRet;
|
||||
|
||||
@@ -66,7 +66,7 @@ static bool AppInitRPC(int argc, char* argv[])
|
||||
// Parameters
|
||||
//
|
||||
ParseParameters(argc, argv);
|
||||
if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version")) {
|
||||
if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) {
|
||||
std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n";
|
||||
if (!mapArgs.count("-version")) {
|
||||
strUsage += "\n" + _("Usage:") + "\n" +
|
||||
|
||||
@@ -44,7 +44,7 @@ static bool AppInitRawTx(int argc, char* argv[])
|
||||
|
||||
fCreateBlank = GetBoolArg("-create", false);
|
||||
|
||||
if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help"))
|
||||
if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help"))
|
||||
{
|
||||
// First part of help message is specific to this utility
|
||||
std::string strUsage = _("Bitcoin Core bitcoin-tx utility version") + " " + FormatFullVersion() + "\n\n" +
|
||||
@@ -149,13 +149,14 @@ static void RegisterLoad(const string& strInput)
|
||||
valStr.insert(valStr.size(), buf, bread);
|
||||
}
|
||||
|
||||
if (ferror(f)) {
|
||||
int error = ferror(f);
|
||||
fclose(f);
|
||||
|
||||
if (error) {
|
||||
string strErr = "Error reading file " + filename;
|
||||
throw runtime_error(strErr);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
// evaluate as JSON buffer register
|
||||
RegisterSetJson(key, valStr);
|
||||
}
|
||||
@@ -368,7 +369,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
|
||||
// Add previous txouts given in the RPC call:
|
||||
if (!registers.count("prevtxs"))
|
||||
throw runtime_error("prevtxs register variable must be set.");
|
||||
UniValue prevtxsObj = registers["privatekeys"];
|
||||
UniValue prevtxsObj = registers["prevtxs"];
|
||||
{
|
||||
for (unsigned int previdx = 0; previdx < prevtxsObj.count(); previdx++) {
|
||||
UniValue prevOut = prevtxsObj[previdx];
|
||||
@@ -379,13 +380,13 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
|
||||
if (!prevOut.checkObject(types))
|
||||
throw runtime_error("prevtxs internal object typecheck fail");
|
||||
|
||||
uint256 txid = ParseHashUV(prevOut, "txid");
|
||||
uint256 txid = ParseHashUV(prevOut["txid"], "txid");
|
||||
|
||||
int nOut = atoi(prevOut["vout"].getValStr());
|
||||
if (nOut < 0)
|
||||
throw runtime_error("vout must be positive");
|
||||
|
||||
vector<unsigned char> pkData(ParseHexUV(prevOut, "scriptPubKey"));
|
||||
vector<unsigned char> pkData(ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey"));
|
||||
CScript scriptPubKey(pkData.begin(), pkData.end());
|
||||
|
||||
{
|
||||
@@ -437,7 +438,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
|
||||
BOOST_FOREACH(const CTransaction& txv, txVariants) {
|
||||
txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
|
||||
}
|
||||
if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i)))
|
||||
if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i)))
|
||||
fComplete = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ bool AppInit(int argc, char* argv[])
|
||||
ParseParameters(argc, argv);
|
||||
|
||||
// Process help and version before taking care about datadir
|
||||
if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version"))
|
||||
if (mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version"))
|
||||
{
|
||||
std::string strUsage = _("Bitcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n";
|
||||
|
||||
|
||||
@@ -122,6 +122,7 @@ public:
|
||||
nMinerThreads = 0;
|
||||
nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
|
||||
nTargetSpacing = 10 * 60;
|
||||
nMaxTipAge = 24 * 60 * 60;
|
||||
|
||||
/**
|
||||
* Build the genesis block. Note that the output of the genesis coinbase cannot
|
||||
@@ -156,7 +157,6 @@ public:
|
||||
vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me"));
|
||||
vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org"));
|
||||
vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com"));
|
||||
vSeeds.push_back(CDNSSeedData("bitnodes.io", "seed.bitnodes.io"));
|
||||
vSeeds.push_back(CDNSSeedData("xf2.org", "bitseed.xf2.org"));
|
||||
|
||||
base58Prefixes[PUBKEY_ADDRESS] = list_of(0);
|
||||
@@ -169,8 +169,8 @@ public:
|
||||
|
||||
fRequireRPCPassword = true;
|
||||
fMiningRequiresPeers = true;
|
||||
fDefaultCheckMemPool = false;
|
||||
fAllowMinDifficultyBlocks = false;
|
||||
fDefaultConsistencyChecks = false;
|
||||
fRequireStandard = true;
|
||||
fMineBlocksOnDemand = false;
|
||||
fSkipProofOfWorkCheck = false;
|
||||
@@ -204,6 +204,7 @@ public:
|
||||
nMinerThreads = 0;
|
||||
nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks
|
||||
nTargetSpacing = 10 * 60;
|
||||
nMaxTipAge = 0x7fffffff;
|
||||
|
||||
//! Modify the testnet genesis block so the timestamp is valid for a later start.
|
||||
genesis.nTime = 1296688602;
|
||||
@@ -228,8 +229,8 @@ public:
|
||||
|
||||
fRequireRPCPassword = true;
|
||||
fMiningRequiresPeers = true;
|
||||
fDefaultCheckMemPool = false;
|
||||
fAllowMinDifficultyBlocks = true;
|
||||
fDefaultConsistencyChecks = false;
|
||||
fRequireStandard = false;
|
||||
fMineBlocksOnDemand = false;
|
||||
fTestnetToBeDeprecatedFieldRPC = true;
|
||||
@@ -261,6 +262,7 @@ public:
|
||||
nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks
|
||||
nTargetSpacing = 10 * 60;
|
||||
bnProofOfWorkLimit = ~uint256(0) >> 1;
|
||||
nMaxTipAge = 24 * 60 * 60;
|
||||
genesis.nTime = 1296688602;
|
||||
genesis.nBits = 0x207fffff;
|
||||
genesis.nNonce = 2;
|
||||
@@ -273,8 +275,8 @@ public:
|
||||
|
||||
fRequireRPCPassword = false;
|
||||
fMiningRequiresPeers = false;
|
||||
fDefaultCheckMemPool = true;
|
||||
fAllowMinDifficultyBlocks = true;
|
||||
fDefaultConsistencyChecks = true;
|
||||
fRequireStandard = false;
|
||||
fMineBlocksOnDemand = true;
|
||||
fTestnetToBeDeprecatedFieldRPC = false;
|
||||
@@ -300,7 +302,7 @@ public:
|
||||
|
||||
fRequireRPCPassword = false;
|
||||
fMiningRequiresPeers = false;
|
||||
fDefaultCheckMemPool = true;
|
||||
fDefaultConsistencyChecks = true;
|
||||
fAllowMinDifficultyBlocks = false;
|
||||
fMineBlocksOnDemand = true;
|
||||
}
|
||||
@@ -316,7 +318,7 @@ public:
|
||||
virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) { nEnforceBlockUpgradeMajority=anEnforceBlockUpgradeMajority; }
|
||||
virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) { nRejectBlockOutdatedMajority=anRejectBlockOutdatedMajority; }
|
||||
virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) { nToCheckBlockUpgradeMajority=anToCheckBlockUpgradeMajority; }
|
||||
virtual void setDefaultCheckMemPool(bool afDefaultCheckMemPool) { fDefaultCheckMemPool=afDefaultCheckMemPool; }
|
||||
virtual void setDefaultConsistencyChecks(bool afDefaultConsistencyChecks) { fDefaultConsistencyChecks=afDefaultConsistencyChecks; }
|
||||
virtual void setAllowMinDifficultyBlocks(bool afAllowMinDifficultyBlocks) { fAllowMinDifficultyBlocks=afAllowMinDifficultyBlocks; }
|
||||
virtual void setSkipProofOfWorkCheck(bool afSkipProofOfWorkCheck) { fSkipProofOfWorkCheck = afSkipProofOfWorkCheck; }
|
||||
};
|
||||
|
||||
@@ -58,8 +58,8 @@ public:
|
||||
bool RequireRPCPassword() const { return fRequireRPCPassword; }
|
||||
/** Make miner wait to have peers to avoid wasting work */
|
||||
bool MiningRequiresPeers() const { return fMiningRequiresPeers; }
|
||||
/** Default value for -checkmempool argument */
|
||||
bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; }
|
||||
/** Default value for -checkmempool and -checkblockindex argument */
|
||||
bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; }
|
||||
/** Allow mining of a min-difficulty block */
|
||||
bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; }
|
||||
/** Skip proof-of-work check: allow mining of any difficulty block */
|
||||
@@ -69,6 +69,7 @@ public:
|
||||
int64_t TargetTimespan() const { return nTargetTimespan; }
|
||||
int64_t TargetSpacing() const { return nTargetSpacing; }
|
||||
int64_t Interval() const { return nTargetTimespan / nTargetSpacing; }
|
||||
int64_t MaxTipAge() const { return nMaxTipAge; }
|
||||
/** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */
|
||||
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
|
||||
/** In the future use NetworkIDString() for RPC fields */
|
||||
@@ -95,6 +96,7 @@ protected:
|
||||
int64_t nTargetTimespan;
|
||||
int64_t nTargetSpacing;
|
||||
int nMinerThreads;
|
||||
long nMaxTipAge;
|
||||
std::vector<CDNSSeedData> vSeeds;
|
||||
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
|
||||
CBaseChainParams::Network networkID;
|
||||
@@ -103,8 +105,8 @@ protected:
|
||||
std::vector<CAddress> vFixedSeeds;
|
||||
bool fRequireRPCPassword;
|
||||
bool fMiningRequiresPeers;
|
||||
bool fDefaultCheckMemPool;
|
||||
bool fAllowMinDifficultyBlocks;
|
||||
bool fDefaultConsistencyChecks;
|
||||
bool fRequireStandard;
|
||||
bool fMineBlocksOnDemand;
|
||||
bool fSkipProofOfWorkCheck;
|
||||
@@ -124,7 +126,7 @@ public:
|
||||
virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority)=0;
|
||||
virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority)=0;
|
||||
virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority)=0;
|
||||
virtual void setDefaultCheckMemPool(bool aDefaultCheckMemPool)=0;
|
||||
virtual void setDefaultConsistencyChecks(bool aDefaultConsistencyChecks)=0;
|
||||
virtual void setAllowMinDifficultyBlocks(bool aAllowMinDifficultyBlocks)=0;
|
||||
virtual void setSkipProofOfWorkCheck(bool aSkipProofOfWorkCheck)=0;
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -161,7 +161,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
friend class CCheckQueueControl<T>;
|
||||
bool IsIdle()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(mutex);
|
||||
return (nTotal == nIdle && nTodo == 0 && fAllOk == true);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -180,9 +185,8 @@ public:
|
||||
{
|
||||
// passed queue is supposed to be unused, or NULL
|
||||
if (pqueue != NULL) {
|
||||
assert(pqueue->nTotal == pqueue->nIdle);
|
||||
assert(pqueue->nTodo == 0);
|
||||
assert(pqueue->fAllOk == true);
|
||||
bool isIdle = pqueue->IsIdle();
|
||||
assert(isIdle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,18 +15,18 @@
|
||||
|
||||
//! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it
|
||||
#define CLIENT_VERSION_MAJOR 0
|
||||
#define CLIENT_VERSION_MINOR 9
|
||||
#define CLIENT_VERSION_REVISION 99
|
||||
#define CLIENT_VERSION_MINOR 10
|
||||
#define CLIENT_VERSION_REVISION 4
|
||||
#define CLIENT_VERSION_BUILD 0
|
||||
|
||||
//! Set to true for release, false for prerelease or test build
|
||||
#define CLIENT_VERSION_IS_RELEASE false
|
||||
#define CLIENT_VERSION_IS_RELEASE true
|
||||
|
||||
/**
|
||||
* Copyright year (2009-this)
|
||||
* Todo: update this when changing our copyright comments in the source
|
||||
*/
|
||||
#define COPYRIGHT_YEAR 2014
|
||||
#define COPYRIGHT_YEAR 2015
|
||||
|
||||
#endif //HAVE_CONFIG_H
|
||||
|
||||
|
||||
@@ -106,7 +106,6 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const {
|
||||
|
||||
CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) {
|
||||
assert(!hasModifier);
|
||||
hasModifier = true;
|
||||
std::pair<CCoinsMap::iterator, bool> ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry()));
|
||||
if (ret.second) {
|
||||
if (!base->GetCoins(txid, ret.first->second.coins)) {
|
||||
@@ -247,7 +246,10 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
|
||||
return tx.ComputePriority(dResult);
|
||||
}
|
||||
|
||||
CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_) {}
|
||||
CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_) : cache(cache_), it(it_) {
|
||||
assert(!cache.hasModifier);
|
||||
cache.hasModifier = true;
|
||||
}
|
||||
|
||||
CCoinsModifier::~CCoinsModifier()
|
||||
{
|
||||
|
||||
13
src/compat.h
13
src/compat.h
@@ -38,6 +38,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <limits.h>
|
||||
@@ -88,8 +89,14 @@ typedef u_int SOCKET;
|
||||
#define THREAD_PRIORITY_ABOVE_NORMAL (-2)
|
||||
#endif
|
||||
|
||||
#if HAVE_DECL_STRNLEN == 0
|
||||
size_t strnlen( const char *start, size_t max_len);
|
||||
#endif // HAVE_DECL_STRNLEN
|
||||
size_t strnlen_int( const char *start, size_t max_len);
|
||||
|
||||
bool static inline IsSelectableSocket(SOCKET s) {
|
||||
#ifdef WIN32
|
||||
return true;
|
||||
#else
|
||||
return (s < FD_SETSIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // BITCOIN_COMPAT_H
|
||||
|
||||
@@ -7,12 +7,11 @@
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#if HAVE_DECL_STRNLEN == 0
|
||||
size_t strnlen( const char *start, size_t max_len)
|
||||
// OSX 10.6 is missing strnlen at runtime, but builds targetting it will still
|
||||
// succeed. Define our own version here to avoid a crash.
|
||||
size_t strnlen_int( const char *start, size_t max_len)
|
||||
{
|
||||
const char *end = (const char *)memchr(start, '\0', max_len);
|
||||
|
||||
return end ? (size_t)(end - start) : max_len;
|
||||
}
|
||||
#endif // HAVE_DECL_STRNLEN
|
||||
|
||||
@@ -19,6 +19,7 @@ extern CScript ParseScript(std::string s);
|
||||
extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx);
|
||||
extern bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
|
||||
extern uint256 ParseHashUV(const UniValue& v, const std::string& strName);
|
||||
extern uint256 ParseHashStr(const std::string&, const std::string& strName);
|
||||
extern std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
|
||||
|
||||
// core_write.cpp
|
||||
|
||||
@@ -131,6 +131,11 @@ uint256 ParseHashUV(const UniValue& v, const string& strName)
|
||||
string strHex;
|
||||
if (v.isStr())
|
||||
strHex = v.getValStr();
|
||||
return ParseHashStr(strHex, strName); // Note: ParseHashStr("") throws a runtime_error
|
||||
}
|
||||
|
||||
uint256 ParseHashStr(const std::string& strHex, const std::string& strName)
|
||||
{
|
||||
if (!IsHex(strHex)) // Note: IsHex("") is false
|
||||
throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ bool CDBEnv::Salvage(std::string strFile, bool fAggressive, std::vector<CDBEnv::
|
||||
std::string keyHex, valueHex;
|
||||
while (!strDump.eof() && keyHex != "DATA=END") {
|
||||
getline(strDump, keyHex);
|
||||
if (keyHex != "DATA_END") {
|
||||
if (keyHex != "DATA=END") {
|
||||
getline(strDump, valueHex);
|
||||
vResult.push_back(make_pair(ParseHex(keyHex), ParseHex(valueHex)));
|
||||
}
|
||||
|
||||
@@ -117,10 +117,34 @@ bool CECKey::SetPubKey(const unsigned char* pubkey, size_t size) {
|
||||
}
|
||||
|
||||
bool CECKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
|
||||
// -1 = error, 0 = bad sig, 1 = good
|
||||
if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
|
||||
if (vchSig.empty())
|
||||
return false;
|
||||
return true;
|
||||
|
||||
// New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first.
|
||||
unsigned char *norm_der = NULL;
|
||||
ECDSA_SIG *norm_sig = ECDSA_SIG_new();
|
||||
const unsigned char* sigptr = &vchSig[0];
|
||||
assert(norm_sig);
|
||||
if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL)
|
||||
{
|
||||
/* As of OpenSSL 1.0.0p d2i_ECDSA_SIG frees and nulls the pointer on
|
||||
* error. But OpenSSL's own use of this function redundantly frees the
|
||||
* result. As ECDSA_SIG_free(NULL) is a no-op, and in the absence of a
|
||||
* clear contract for the function behaving the same way is more
|
||||
* conservative.
|
||||
*/
|
||||
ECDSA_SIG_free(norm_sig);
|
||||
return false;
|
||||
}
|
||||
int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
|
||||
ECDSA_SIG_free(norm_sig);
|
||||
if (derlen <= 0)
|
||||
return false;
|
||||
|
||||
// -1 = error, 0 = bad sig, 1 = good
|
||||
bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1;
|
||||
OPENSSL_free(norm_der);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CECKey::Recover(const uint256 &hash, const unsigned char *p64, int rec)
|
||||
|
||||
72
src/init.cpp
72
src/init.cpp
@@ -112,7 +112,28 @@ bool ShutdownRequested()
|
||||
return fRequestShutdown;
|
||||
}
|
||||
|
||||
class CCoinsViewErrorCatcher : public CCoinsViewBacked
|
||||
{
|
||||
public:
|
||||
CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {}
|
||||
bool GetCoins(const uint256 &txid, CCoins &coins) const {
|
||||
try {
|
||||
return CCoinsViewBacked::GetCoins(txid, coins);
|
||||
} catch(const std::runtime_error& e) {
|
||||
uiInterface.ThreadSafeMessageBox(_("Error reading from database, shutting down."), "", CClientUIInterface::MSG_ERROR);
|
||||
LogPrintf("Error reading from database: %s\n", e.what());
|
||||
// Starting the shutdown sequence and returning false to the caller would be
|
||||
// interpreted as 'entry not found' (as opposed to unable to read data), and
|
||||
// could lead to invalid interpration. Just exit immediately, as we can't
|
||||
// continue anyway, and all writes should be atomic.
|
||||
abort();
|
||||
}
|
||||
}
|
||||
// Writes do not need similar protection, as failure to write is handled by the caller.
|
||||
};
|
||||
|
||||
static CCoinsViewDB *pcoinsdbview = NULL;
|
||||
static CCoinsViewErrorCatcher *pcoinscatcher = NULL;
|
||||
|
||||
void Shutdown()
|
||||
{
|
||||
@@ -155,6 +176,8 @@ void Shutdown()
|
||||
}
|
||||
delete pcoinsTip;
|
||||
pcoinsTip = NULL;
|
||||
delete pcoinscatcher;
|
||||
pcoinscatcher = NULL;
|
||||
delete pcoinsdbview;
|
||||
pcoinsdbview = NULL;
|
||||
delete pblocktree;
|
||||
@@ -218,6 +241,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
string strUsage = _("Options:") + "\n";
|
||||
strUsage += " -? " + _("This help message") + "\n";
|
||||
strUsage += " -alertnotify=<cmd> " + _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)") + "\n";
|
||||
strUsage += " -alerts " + strprintf(_("Receive and display P2P network alerts (default: %u)"), DEFAULT_ALERTS);
|
||||
strUsage += " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n";
|
||||
strUsage += " -checkblocks=<n> " + strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288) + "\n";
|
||||
strUsage += " -checklevel=<n> " + strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3) + "\n";
|
||||
@@ -231,7 +255,6 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
|
||||
strUsage += " -dbcache=<n> " + strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache) + "\n";
|
||||
strUsage += " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + " " + _("on startup") + "\n";
|
||||
strUsage += " -maxorphanblocks=<n> " + strprintf(_("Keep at most <n> unconnectable blocks in memory (default: %u)"), DEFAULT_MAX_ORPHAN_BLOCKS) + "\n";
|
||||
strUsage += " -maxorphantx=<n> " + strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "\n";
|
||||
strUsage += " -par=<n> " + strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS) + "\n";
|
||||
#ifndef WIN32
|
||||
@@ -287,7 +310,8 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n";
|
||||
strUsage += " -sendfreetransactions " + strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0) + "\n";
|
||||
strUsage += " -spendzeroconfchange " + strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1) + "\n";
|
||||
strUsage += " -txconfirmtarget=<n> " + strprintf(_("If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: %u)"), 1) + "\n";
|
||||
strUsage += " -txconfirmtarget=<n> " + strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1) + "\n";
|
||||
strUsage += " -maxtxfee=<amt> " + strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), FormatMoney(maxTxFee)) + "\n";
|
||||
strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n";
|
||||
strUsage += " -wallet=<file> " + _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat") + "\n";
|
||||
strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n";
|
||||
@@ -324,6 +348,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
if (GetBoolArg("-help-debug", false))
|
||||
{
|
||||
strUsage += " -limitfreerelay=<n> " + strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15) + "\n";
|
||||
strUsage += " -relaypriority " + strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1) + "\n";
|
||||
strUsage += " -maxsigcachesize=<n> " + strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000) + "\n";
|
||||
}
|
||||
strUsage += " -minrelaytxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())) + "\n";
|
||||
@@ -357,6 +382,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
strUsage += " -rpcport=<port> " + strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n";
|
||||
strUsage += " -rpcallowip=<ip> " + _("Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times") + "\n";
|
||||
strUsage += " -rpcthreads=<n> " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n";
|
||||
strUsage += " -rpckeepalive " + strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1) + "\n";
|
||||
|
||||
strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
|
||||
strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
|
||||
@@ -568,7 +594,11 @@ bool AppInit2(boost::thread_group& threadGroup)
|
||||
if (mapArgs.count("-proxy")) {
|
||||
// to protect privacy, do not listen by default if a default proxy server is specified
|
||||
if (SoftSetBoolArg("-listen", false))
|
||||
LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -listen=0\n");
|
||||
LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__);
|
||||
// to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1
|
||||
// to listen locally, so don't rely on this happening through -listen below.
|
||||
if (SoftSetBoolArg("-upnp", false))
|
||||
LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__);
|
||||
// to protect privacy, do not discover addresses by default
|
||||
if (SoftSetBoolArg("-discover", false))
|
||||
LogPrintf("AppInit2 : parameter interaction: -proxy set -> setting -discover=0\n");
|
||||
@@ -631,8 +661,9 @@ bool AppInit2(boost::thread_group& threadGroup)
|
||||
if (GetBoolArg("-benchmark", false))
|
||||
InitWarning(_("Warning: Unsupported argument -benchmark ignored, use -debug=bench."));
|
||||
|
||||
// Checkmempool defaults to true in regtest mode
|
||||
mempool.setSanityCheck(GetBoolArg("-checkmempool", Params().DefaultCheckMemPool()));
|
||||
// Checkmempool and checkblockindex default to true in regtest mode
|
||||
mempool.setSanityCheck(GetBoolArg("-checkmempool", Params().DefaultConsistencyChecks()));
|
||||
fCheckBlockIndex = GetBoolArg("-checkblockindex", Params().DefaultConsistencyChecks());
|
||||
Checkpoints::fEnabled = GetBoolArg("-checkpoints", true);
|
||||
|
||||
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
|
||||
@@ -653,12 +684,6 @@ bool AppInit2(boost::thread_group& threadGroup)
|
||||
if (nConnectTimeout <= 0)
|
||||
nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
|
||||
|
||||
// Continue to put "/P2SH/" in the coinbase to monitor
|
||||
// BIP16 support.
|
||||
// This can be removed eventually...
|
||||
const char* pszP2SH = "/P2SH/";
|
||||
COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
|
||||
|
||||
// Fee-per-kilobyte amount considered the same as "free"
|
||||
// If you are mining, be careful setting this:
|
||||
// if you set it to zero then
|
||||
@@ -697,6 +722,20 @@ bool AppInit2(boost::thread_group& threadGroup)
|
||||
mapArgs["-paytxfee"], ::minRelayTxFee.ToString()));
|
||||
}
|
||||
}
|
||||
if (mapArgs.count("-maxtxfee"))
|
||||
{
|
||||
CAmount nMaxFee = 0;
|
||||
if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee))
|
||||
return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s'"), mapArgs["-maptxfee"]));
|
||||
if (nMaxFee > nHighTransactionMaxFeeWarning)
|
||||
InitWarning(_("Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction."));
|
||||
maxTxFee = nMaxFee;
|
||||
if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee)
|
||||
{
|
||||
return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
|
||||
mapArgs["-maxtxfee"], ::minRelayTxFee.ToString()));
|
||||
}
|
||||
}
|
||||
nTxConfirmTarget = GetArg("-txconfirmtarget", 1);
|
||||
bSpendZeroConfChange = GetArg("-spendzeroconfchange", true);
|
||||
fSendFreeTransactions = GetArg("-sendfreetransactions", false);
|
||||
@@ -707,6 +746,8 @@ bool AppInit2(boost::thread_group& threadGroup)
|
||||
fIsBareMultisigStd = GetArg("-permitbaremultisig", true) != 0;
|
||||
nMaxDatacarrierBytes = GetArg("-datacarriersize", nMaxDatacarrierBytes);
|
||||
|
||||
fAlerts = GetBoolArg("-alerts", DEFAULT_ALERTS);
|
||||
|
||||
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
|
||||
|
||||
// Sanity check
|
||||
@@ -971,11 +1012,13 @@ bool AppInit2(boost::thread_group& threadGroup)
|
||||
UnloadBlockIndex();
|
||||
delete pcoinsTip;
|
||||
delete pcoinsdbview;
|
||||
delete pcoinscatcher;
|
||||
delete pblocktree;
|
||||
|
||||
pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
|
||||
pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
|
||||
pcoinsTip = new CCoinsViewCache(pcoinsdbview);
|
||||
pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview);
|
||||
pcoinsTip = new CCoinsViewCache(pcoinscatcher);
|
||||
|
||||
if (fReindex)
|
||||
pblocktree->WriteReindexing(true);
|
||||
@@ -1207,6 +1250,11 @@ bool AppInit2(boost::thread_group& threadGroup)
|
||||
vImportFiles.push_back(strFile);
|
||||
}
|
||||
threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles));
|
||||
if (chainActive.Tip() == NULL) {
|
||||
LogPrintf("Waiting for genesis block to be imported...\n");
|
||||
while (!fRequestShutdown && chainActive.Tip() == NULL)
|
||||
MilliSleep(10);
|
||||
}
|
||||
|
||||
// ********************************************************* Step 10: start node
|
||||
|
||||
|
||||
@@ -521,12 +521,11 @@ namespace json_spirit
|
||||
|
||||
const spirit_namespace::parse_info< Iter_type > info =
|
||||
spirit_namespace::parse( begin, end,
|
||||
Json_grammer< Value_type, Iter_type >( semantic_actions ),
|
||||
Json_grammer< Value_type, Iter_type >( semantic_actions ) >> spirit_namespace::end_p,
|
||||
spirit_namespace::space_p );
|
||||
|
||||
if( !info.hit )
|
||||
{
|
||||
assert( false ); // in theory exception should already have been thrown
|
||||
throw_error( info.stop, "error" );
|
||||
}
|
||||
|
||||
@@ -570,7 +569,8 @@ namespace json_spirit
|
||||
{
|
||||
typename String_type::const_iterator begin = s.begin();
|
||||
|
||||
return read_range( begin, s.end(), value );
|
||||
bool success = read_range( begin, s.end(), value );
|
||||
return success && begin == s.end();
|
||||
}
|
||||
|
||||
template< class Istream_type >
|
||||
|
||||
@@ -103,39 +103,20 @@ private:
|
||||
DISALLOW_COPY_AND_ASSIGN(Win32RandomAccessFile);
|
||||
};
|
||||
|
||||
class Win32MapFile : public WritableFile
|
||||
class Win32WritableFile : public WritableFile
|
||||
{
|
||||
public:
|
||||
Win32MapFile(const std::string& fname);
|
||||
Win32WritableFile(const std::string& fname);
|
||||
~Win32WritableFile();
|
||||
|
||||
~Win32MapFile();
|
||||
virtual Status Append(const Slice& data);
|
||||
virtual Status Close();
|
||||
virtual Status Flush();
|
||||
virtual Status Sync();
|
||||
BOOL isEnable();
|
||||
private:
|
||||
std::string _filename;
|
||||
HANDLE _hFile;
|
||||
size_t _page_size;
|
||||
size_t _map_size; // How much extra memory to map at a time
|
||||
char* _base; // The mapped region
|
||||
HANDLE _base_handle;
|
||||
char* _limit; // Limit of the mapped region
|
||||
char* _dst; // Where to write next (in range [base_,limit_])
|
||||
char* _last_sync; // Where have we synced up to
|
||||
uint64_t _file_offset; // Offset of base_ in file
|
||||
//LARGE_INTEGER file_offset_;
|
||||
// Have we done an munmap of unsynced data?
|
||||
bool _pending_sync;
|
||||
|
||||
// Roundup x to a multiple of y
|
||||
static size_t _Roundup(size_t x, size_t y);
|
||||
size_t _TruncateToPageBoundary(size_t s);
|
||||
bool _UnmapCurrentRegion();
|
||||
bool _MapNewRegion();
|
||||
DISALLOW_COPY_AND_ASSIGN(Win32MapFile);
|
||||
BOOL _Init(LPCWSTR Path);
|
||||
std::string filename_;
|
||||
::HANDLE _hFile;
|
||||
};
|
||||
|
||||
class Win32FileLock : public FileLock
|
||||
@@ -442,202 +423,63 @@ void Win32RandomAccessFile::_CleanUp()
|
||||
}
|
||||
}
|
||||
|
||||
size_t Win32MapFile::_Roundup( size_t x, size_t y )
|
||||
Win32WritableFile::Win32WritableFile(const std::string& fname)
|
||||
: filename_(fname)
|
||||
{
|
||||
return ((x + y - 1) / y) * y;
|
||||
}
|
||||
|
||||
size_t Win32MapFile::_TruncateToPageBoundary( size_t s )
|
||||
{
|
||||
s -= (s & (_page_size - 1));
|
||||
assert((s % _page_size) == 0);
|
||||
return s;
|
||||
}
|
||||
|
||||
bool Win32MapFile::_UnmapCurrentRegion()
|
||||
{
|
||||
bool result = true;
|
||||
if (_base != NULL) {
|
||||
if (_last_sync < _limit) {
|
||||
// Defer syncing this data until next Sync() call, if any
|
||||
_pending_sync = true;
|
||||
}
|
||||
if (!UnmapViewOfFile(_base) || !CloseHandle(_base_handle))
|
||||
result = false;
|
||||
_file_offset += _limit - _base;
|
||||
_base = NULL;
|
||||
_base_handle = NULL;
|
||||
_limit = NULL;
|
||||
_last_sync = NULL;
|
||||
_dst = NULL;
|
||||
// Increase the amount we map the next time, but capped at 1MB
|
||||
if (_map_size < (1<<20)) {
|
||||
_map_size *= 2;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Win32MapFile::_MapNewRegion()
|
||||
{
|
||||
assert(_base == NULL);
|
||||
//LONG newSizeHigh = (LONG)((file_offset_ + map_size_) >> 32);
|
||||
//LONG newSizeLow = (LONG)((file_offset_ + map_size_) & 0xFFFFFFFF);
|
||||
DWORD off_hi = (DWORD)(_file_offset >> 32);
|
||||
DWORD off_lo = (DWORD)(_file_offset & 0xFFFFFFFF);
|
||||
LARGE_INTEGER newSize;
|
||||
newSize.QuadPart = _file_offset + _map_size;
|
||||
SetFilePointerEx(_hFile, newSize, NULL, FILE_BEGIN);
|
||||
SetEndOfFile(_hFile);
|
||||
|
||||
_base_handle = CreateFileMappingA(
|
||||
_hFile,
|
||||
NULL,
|
||||
PAGE_READWRITE,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
if (_base_handle != NULL) {
|
||||
_base = (char*) MapViewOfFile(_base_handle,
|
||||
FILE_MAP_ALL_ACCESS,
|
||||
off_hi,
|
||||
off_lo,
|
||||
_map_size);
|
||||
if (_base != NULL) {
|
||||
_limit = _base + _map_size;
|
||||
_dst = _base;
|
||||
_last_sync = _base;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Win32MapFile::Win32MapFile( const std::string& fname) :
|
||||
_filename(fname),
|
||||
_hFile(NULL),
|
||||
_page_size(Win32::g_PageSize),
|
||||
_map_size(_Roundup(65536, Win32::g_PageSize)),
|
||||
_base(NULL),
|
||||
_base_handle(NULL),
|
||||
_limit(NULL),
|
||||
_dst(NULL),
|
||||
_last_sync(NULL),
|
||||
_file_offset(0),
|
||||
_pending_sync(false)
|
||||
{
|
||||
std::wstring path;
|
||||
ToWidePath(fname, path);
|
||||
_Init(path.c_str());
|
||||
assert((Win32::g_PageSize & (Win32::g_PageSize - 1)) == 0);
|
||||
}
|
||||
|
||||
Status Win32MapFile::Append( const Slice& data )
|
||||
{
|
||||
const char* src = data.data();
|
||||
size_t left = data.size();
|
||||
Status s;
|
||||
while (left > 0) {
|
||||
assert(_base <= _dst);
|
||||
assert(_dst <= _limit);
|
||||
size_t avail = _limit - _dst;
|
||||
if (avail == 0) {
|
||||
if (!_UnmapCurrentRegion() ||
|
||||
!_MapNewRegion()) {
|
||||
return Status::IOError("WinMmapFile.Append::UnmapCurrentRegion or MapNewRegion: ", Win32::GetLastErrSz());
|
||||
}
|
||||
}
|
||||
size_t n = (left <= avail) ? left : avail;
|
||||
memcpy(_dst, src, n);
|
||||
_dst += n;
|
||||
src += n;
|
||||
left -= n;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
Status Win32MapFile::Close()
|
||||
{
|
||||
Status s;
|
||||
size_t unused = _limit - _dst;
|
||||
if (!_UnmapCurrentRegion()) {
|
||||
s = Status::IOError("WinMmapFile.Close::UnmapCurrentRegion: ",Win32::GetLastErrSz());
|
||||
} else if (unused > 0) {
|
||||
// Trim the extra space at the end of the file
|
||||
LARGE_INTEGER newSize;
|
||||
newSize.QuadPart = _file_offset - unused;
|
||||
if (!SetFilePointerEx(_hFile, newSize, NULL, FILE_BEGIN)) {
|
||||
s = Status::IOError("WinMmapFile.Close::SetFilePointer: ",Win32::GetLastErrSz());
|
||||
} else
|
||||
SetEndOfFile(_hFile);
|
||||
}
|
||||
if (!CloseHandle(_hFile)) {
|
||||
if (s.ok()) {
|
||||
s = Status::IOError("WinMmapFile.Close::CloseHandle: ", Win32::GetLastErrSz());
|
||||
}
|
||||
}
|
||||
_hFile = INVALID_HANDLE_VALUE;
|
||||
_base = NULL;
|
||||
_base_handle = NULL;
|
||||
_limit = NULL;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
Status Win32MapFile::Sync()
|
||||
{
|
||||
Status s;
|
||||
if (_pending_sync) {
|
||||
// Some unmapped data was not synced
|
||||
_pending_sync = false;
|
||||
if (!FlushFileBuffers(_hFile)) {
|
||||
s = Status::IOError("WinMmapFile.Sync::FlushFileBuffers: ",Win32::GetLastErrSz());
|
||||
}
|
||||
}
|
||||
if (_dst > _last_sync) {
|
||||
// Find the beginnings of the pages that contain the first and last
|
||||
// bytes to be synced.
|
||||
size_t p1 = _TruncateToPageBoundary(_last_sync - _base);
|
||||
size_t p2 = _TruncateToPageBoundary(_dst - _base - 1);
|
||||
_last_sync = _dst;
|
||||
if (!FlushViewOfFile(_base + p1, p2 - p1 + _page_size)) {
|
||||
s = Status::IOError("WinMmapFile.Sync::FlushViewOfFile: ",Win32::GetLastErrSz());
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
Status Win32MapFile::Flush()
|
||||
{
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Win32MapFile::~Win32MapFile()
|
||||
{
|
||||
if (_hFile != INVALID_HANDLE_VALUE) {
|
||||
Win32MapFile::Close();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL Win32MapFile::_Init( LPCWSTR Path )
|
||||
{
|
||||
DWORD Flag = PathFileExistsW(Path) ? OPEN_EXISTING : CREATE_ALWAYS;
|
||||
_hFile = CreateFileW(Path,
|
||||
std::wstring path;
|
||||
ToWidePath(fname, path);
|
||||
DWORD Flag = PathFileExistsW(path.c_str()) ? OPEN_EXISTING : CREATE_ALWAYS;
|
||||
_hFile = CreateFileW(path.c_str(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
Flag,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
if(!_hFile || _hFile == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
// CreateFileW returns INVALID_HANDLE_VALUE in case of error, always check isEnable() before use
|
||||
}
|
||||
|
||||
BOOL Win32MapFile::isEnable()
|
||||
Win32WritableFile::~Win32WritableFile()
|
||||
{
|
||||
return _hFile ? TRUE : FALSE;
|
||||
if (_hFile != INVALID_HANDLE_VALUE)
|
||||
Close();
|
||||
}
|
||||
|
||||
Status Win32WritableFile::Append(const Slice& data)
|
||||
{
|
||||
DWORD r = 0;
|
||||
if (!WriteFile(_hFile, data.data(), data.size(), &r, NULL) || r != data.size()) {
|
||||
return Status::IOError("Win32WritableFile.Append::WriteFile: "+filename_, Win32::GetLastErrSz());
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status Win32WritableFile::Close()
|
||||
{
|
||||
if (!CloseHandle(_hFile)) {
|
||||
return Status::IOError("Win32WritableFile.Close::CloseHandle: "+filename_, Win32::GetLastErrSz());
|
||||
}
|
||||
_hFile = INVALID_HANDLE_VALUE;
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status Win32WritableFile::Flush()
|
||||
{
|
||||
// Nothing to do here, there are no application-side buffers
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status Win32WritableFile::Sync()
|
||||
{
|
||||
if (!FlushFileBuffers(_hFile)) {
|
||||
return Status::IOError("Win32WritableFile.Sync::FlushFileBuffers "+filename_, Win32::GetLastErrSz());
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
BOOL Win32WritableFile::isEnable()
|
||||
{
|
||||
return _hFile != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
Win32FileLock::Win32FileLock( const std::string& fname ) :
|
||||
@@ -981,7 +823,7 @@ Status Win32Env::NewLogger( const std::string& fname, Logger** result )
|
||||
{
|
||||
Status sRet;
|
||||
std::string path = fname;
|
||||
Win32MapFile* pMapFile = new Win32MapFile(ModifyPath(path));
|
||||
Win32WritableFile* pMapFile = new Win32WritableFile(ModifyPath(path));
|
||||
if(!pMapFile->isEnable()){
|
||||
delete pMapFile;
|
||||
*result = NULL;
|
||||
@@ -995,7 +837,7 @@ Status Win32Env::NewWritableFile( const std::string& fname, WritableFile** resul
|
||||
{
|
||||
Status sRet;
|
||||
std::string path = fname;
|
||||
Win32MapFile* pFile = new Win32MapFile(ModifyPath(path));
|
||||
Win32WritableFile* pFile = new Win32WritableFile(ModifyPath(path));
|
||||
if(!pFile->isEnable()){
|
||||
*result = NULL;
|
||||
sRet = Status::IOError(fname,Win32::GetLastErrSz());
|
||||
|
||||
@@ -58,7 +58,8 @@ CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path& path, size_t nCa
|
||||
} else {
|
||||
if (fWipe) {
|
||||
LogPrintf("Wiping LevelDB in %s\n", path.string());
|
||||
leveldb::DestroyDB(path.string(), options);
|
||||
leveldb::Status result = leveldb::DestroyDB(path.string(), options);
|
||||
HandleError(result);
|
||||
}
|
||||
TryCreateDirectory(path);
|
||||
LogPrintf("Opening LevelDB in %s\n", path.string());
|
||||
|
||||
440
src/main.cpp
440
src/main.cpp
@@ -51,11 +51,12 @@ bool fImporting = false;
|
||||
bool fReindex = false;
|
||||
bool fTxIndex = false;
|
||||
bool fIsBareMultisigStd = true;
|
||||
bool fCheckBlockIndex = false;
|
||||
unsigned int nCoinCacheSize = 5000;
|
||||
|
||||
bool fAlerts = DEFAULT_ALERTS;
|
||||
|
||||
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
|
||||
CFeeRate minRelayTxFee = CFeeRate(1000);
|
||||
CFeeRate minRelayTxFee = CFeeRate(5000);
|
||||
|
||||
CTxMemPool mempool(::minRelayTxFee);
|
||||
|
||||
@@ -67,6 +68,8 @@ map<uint256, COrphanTx> mapOrphanTransactions;
|
||||
map<uint256, set<uint256> > mapOrphanTransactionsByPrev;
|
||||
void EraseOrphansFor(NodeId peer);
|
||||
|
||||
static void CheckBlockIndex();
|
||||
|
||||
/** Constant stuff for coinbase transactions we create: */
|
||||
CScript COINBASE_FLAGS;
|
||||
|
||||
@@ -77,7 +80,7 @@ namespace {
|
||||
|
||||
struct CBlockIndexWorkComparator
|
||||
{
|
||||
bool operator()(CBlockIndex *pa, CBlockIndex *pb) {
|
||||
bool operator()(CBlockIndex *pa, CBlockIndex *pb) const {
|
||||
// First sort by most total work, ...
|
||||
if (pa->nChainWork > pb->nChainWork) return false;
|
||||
if (pa->nChainWork < pb->nChainWork) return true;
|
||||
@@ -99,8 +102,8 @@ namespace {
|
||||
CBlockIndex *pindexBestInvalid;
|
||||
|
||||
/**
|
||||
* The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS or better that are at least
|
||||
* as good as our current tip. Entries may be failed, though.
|
||||
* The set of all CBlockIndex entries with BLOCK_VALID_TRANSACTIONS (for itself and all ancestors) and
|
||||
* as good as our current tip or better. Entries may be failed, though.
|
||||
*/
|
||||
set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
|
||||
/** Number of nodes with fSyncStarted. */
|
||||
@@ -131,9 +134,14 @@ namespace {
|
||||
uint256 hash;
|
||||
CBlockIndex *pindex; //! Optional.
|
||||
int64_t nTime; //! Time of "getdata" request in microseconds.
|
||||
int nValidatedQueuedBefore; //! Number of blocks queued with validated headers (globally) at the time this one is requested.
|
||||
bool fValidatedHeaders; //! Whether this block has validated headers at the time of request.
|
||||
};
|
||||
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
|
||||
|
||||
/** Number of blocks in flight with validated headers. */
|
||||
int nQueuedValidatedHeaders = 0;
|
||||
|
||||
/** Number of preferable block download peers. */
|
||||
int nPreferredDownload = 0;
|
||||
|
||||
@@ -226,6 +234,10 @@ struct CBlockReject {
|
||||
* and we're no longer holding the node's locks.
|
||||
*/
|
||||
struct CNodeState {
|
||||
//! The peer's address
|
||||
CService address;
|
||||
//! Whether we have a fully established connection.
|
||||
bool fCurrentlyConnected;
|
||||
//! Accumulated misbehaviour score for this peer.
|
||||
int nMisbehavior;
|
||||
//! Whether this peer should be disconnected and banned (unless whitelisted).
|
||||
@@ -250,6 +262,7 @@ struct CNodeState {
|
||||
bool fPreferredDownload;
|
||||
|
||||
CNodeState() {
|
||||
fCurrentlyConnected = false;
|
||||
nMisbehavior = 0;
|
||||
fShouldBan = false;
|
||||
pindexBestKnownBlock = NULL;
|
||||
@@ -293,6 +306,7 @@ void InitializeNode(NodeId nodeid, const CNode *pnode) {
|
||||
LOCK(cs_main);
|
||||
CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
|
||||
state.name = pnode->addrName;
|
||||
state.address = pnode->addr;
|
||||
}
|
||||
|
||||
void FinalizeNode(NodeId nodeid) {
|
||||
@@ -302,6 +316,10 @@ void FinalizeNode(NodeId nodeid) {
|
||||
if (state->fSyncStarted)
|
||||
nSyncStarted--;
|
||||
|
||||
if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
|
||||
AddressCurrentlyConnected(state->address);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
|
||||
mapBlocksInFlight.erase(entry.hash);
|
||||
EraseOrphansFor(nodeid);
|
||||
@@ -315,6 +333,7 @@ void MarkBlockAsReceived(const uint256& hash) {
|
||||
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
|
||||
if (itInFlight != mapBlocksInFlight.end()) {
|
||||
CNodeState *state = State(itInFlight->second.first);
|
||||
nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
|
||||
state->vBlocksInFlight.erase(itInFlight->second.second);
|
||||
state->nBlocksInFlight--;
|
||||
state->nStallingSince = 0;
|
||||
@@ -330,7 +349,8 @@ void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex *pindex
|
||||
// Make sure it's not listed somewhere already.
|
||||
MarkBlockAsReceived(hash);
|
||||
|
||||
QueuedBlock newentry = {hash, pindex, GetTimeMicros()};
|
||||
QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != NULL};
|
||||
nQueuedValidatedHeaders += newentry.fValidatedHeaders;
|
||||
list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
|
||||
state->nBlocksInFlight++;
|
||||
mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
|
||||
@@ -442,6 +462,10 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBl
|
||||
// are not yet downloaded and not in flight to vBlocks. In the mean time, update
|
||||
// pindexLastCommonBlock as long as all ancestors are already downloaded.
|
||||
BOOST_FOREACH(CBlockIndex* pindex, vToFetch) {
|
||||
if (!pindex->IsValid(BLOCK_VALID_TREE)) {
|
||||
// We consider the chain that this peer is on invalid.
|
||||
return;
|
||||
}
|
||||
if (pindex->nStatus & BLOCK_HAVE_DATA) {
|
||||
if (pindex->nChainTx)
|
||||
state->pindexLastCommonBlock = pindex;
|
||||
@@ -1018,7 +1042,12 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
hash.ToString(), nFees, txMinFee),
|
||||
REJECT_INSUFFICIENTFEE, "insufficient fee");
|
||||
|
||||
// Continuously rate-limit free (really, very-low-fee)transactions
|
||||
// Require that free transactions have sufficient priority to be mined in the next block.
|
||||
if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) {
|
||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority");
|
||||
}
|
||||
|
||||
// Continuously rate-limit free (really, very-low-fee) transactions
|
||||
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
|
||||
// be annoying or make others' transactions take longer to confirm.
|
||||
if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize))
|
||||
@@ -1037,7 +1066,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
// At default rate it would take over a month to fill 1GB
|
||||
if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
|
||||
return state.DoS(0, error("AcceptToMemoryPool : free transaction rejected by rate limiter"),
|
||||
REJECT_INSUFFICIENTFEE, "insufficient priority");
|
||||
REJECT_INSUFFICIENTFEE, "rate limited free transaction");
|
||||
LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
|
||||
dFreeCount += nSize;
|
||||
}
|
||||
@@ -1053,6 +1082,21 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
{
|
||||
return error("AcceptToMemoryPool: : ConnectInputs failed %s", hash.ToString());
|
||||
}
|
||||
|
||||
// Check again against just the consensus-critical mandatory script
|
||||
// verification flags, in case of bugs in the standard flags that cause
|
||||
// transactions to pass as valid when they're actually invalid. For
|
||||
// instance the STRICTENC flag was incorrectly allowing certain
|
||||
// CHECKSIG NOT scripts to pass, even though they were invalid.
|
||||
//
|
||||
// There is a similar check in CreateNewBlock() to prevent creating
|
||||
// invalid blocks, however allowing such transactions into the mempool
|
||||
// can be exploited as a DoS attack.
|
||||
if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
|
||||
{
|
||||
return error("AcceptToMemoryPool: : BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString());
|
||||
}
|
||||
|
||||
// Store transaction in memory
|
||||
pool.addUnchecked(hash, entry);
|
||||
}
|
||||
@@ -1066,45 +1110,45 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
|
||||
{
|
||||
CBlockIndex *pindexSlow = NULL;
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
if (mempool.lookup(hash, txOut))
|
||||
{
|
||||
LOCK(cs_main);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fTxIndex) {
|
||||
CDiskTxPos postx;
|
||||
if (pblocktree->ReadTxIndex(hash, postx)) {
|
||||
CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
|
||||
if (file.IsNull())
|
||||
return error("%s: OpenBlockFile failed", __func__);
|
||||
CBlockHeader header;
|
||||
try {
|
||||
file >> header;
|
||||
fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
|
||||
file >> txOut;
|
||||
} catch (std::exception &e) {
|
||||
return error("%s : Deserialize or I/O error - %s", __func__, e.what());
|
||||
}
|
||||
hashBlock = header.GetHash();
|
||||
if (txOut.GetHash() != hash)
|
||||
return error("%s : txid mismatch", __func__);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
|
||||
int nHeight = -1;
|
||||
{
|
||||
if (mempool.lookup(hash, txOut))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fTxIndex) {
|
||||
CDiskTxPos postx;
|
||||
if (pblocktree->ReadTxIndex(hash, postx)) {
|
||||
CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
|
||||
CBlockHeader header;
|
||||
try {
|
||||
file >> header;
|
||||
fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
|
||||
file >> txOut;
|
||||
} catch (std::exception &e) {
|
||||
return error("%s : Deserialize or I/O error - %s", __func__, e.what());
|
||||
}
|
||||
hashBlock = header.GetHash();
|
||||
if (txOut.GetHash() != hash)
|
||||
return error("%s : txid mismatch", __func__);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
|
||||
int nHeight = -1;
|
||||
{
|
||||
CCoinsViewCache &view = *pcoinsTip;
|
||||
const CCoins* coins = view.AccessCoins(hash);
|
||||
if (coins)
|
||||
nHeight = coins->nHeight;
|
||||
}
|
||||
if (nHeight > 0)
|
||||
pindexSlow = chainActive[nHeight];
|
||||
CCoinsViewCache &view = *pcoinsTip;
|
||||
const CCoins* coins = view.AccessCoins(hash);
|
||||
if (coins)
|
||||
nHeight = coins->nHeight;
|
||||
}
|
||||
if (nHeight > 0)
|
||||
pindexSlow = chainActive[nHeight];
|
||||
}
|
||||
|
||||
if (pindexSlow) {
|
||||
@@ -1204,6 +1248,7 @@ CAmount GetBlockValue(int nHeight, const CAmount& nFees)
|
||||
|
||||
bool IsInitialBlockDownload()
|
||||
{
|
||||
const CChainParams& chainParams = Params();
|
||||
LOCK(cs_main);
|
||||
if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate())
|
||||
return true;
|
||||
@@ -1211,7 +1256,7 @@ bool IsInitialBlockDownload()
|
||||
if (lockIBDState)
|
||||
return false;
|
||||
bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 ||
|
||||
pindexBestHeader->GetBlockTime() < GetTime() - 24 * 60 * 60);
|
||||
pindexBestHeader->GetBlockTime() < GetTime() - chainParams.MaxTipAge());
|
||||
if (!state)
|
||||
lockIBDState = true;
|
||||
return state;
|
||||
@@ -1367,8 +1412,8 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
|
||||
|
||||
bool CScriptCheck::operator()() {
|
||||
const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
|
||||
if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingSignatureChecker(*ptxTo, nIn, cacheStore), &error)) {
|
||||
return ::error("CScriptCheck() : %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
|
||||
if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) {
|
||||
return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1652,6 +1697,18 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
|
||||
unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE;
|
||||
|
||||
// Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks,
|
||||
// when 75% of the network has upgraded:
|
||||
if (block.nVersion >= 3 && CBlockIndex::IsSuperMajority(3, pindex->pprev, Params().EnforceBlockUpgradeMajority())) {
|
||||
flags |= SCRIPT_VERIFY_DERSIG;
|
||||
}
|
||||
|
||||
// Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4
|
||||
// blocks, when 75% of the network has upgraded:
|
||||
if (block.nVersion >= 4 && CBlockIndex::IsSuperMajority(4, pindex->pprev, Params().EnforceBlockUpgradeMajority())) {
|
||||
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
|
||||
}
|
||||
|
||||
CBlockUndo blockundo;
|
||||
|
||||
CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
|
||||
@@ -1779,6 +1836,7 @@ enum FlushStateMode {
|
||||
bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
|
||||
LOCK(cs_main);
|
||||
static int64_t nLastWrite = 0;
|
||||
try {
|
||||
if ((mode == FLUSH_STATE_ALWAYS) ||
|
||||
((mode == FLUSH_STATE_PERIODIC || mode == FLUSH_STATE_IF_NEEDED) && pcoinsTip->GetCacheSize() > nCoinCacheSize) ||
|
||||
(mode == FLUSH_STATE_PERIODIC && GetTimeMicros() > nLastWrite + DATABASE_WRITE_INTERVAL * 1000000)) {
|
||||
@@ -1819,6 +1877,9 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
|
||||
}
|
||||
nLastWrite = GetTimeMicros();
|
||||
}
|
||||
} catch (const std::runtime_error& e) {
|
||||
return state.Abort(std::string("System error while flushing: ") + e.what());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2143,6 +2204,7 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
|
||||
uiInterface.NotifyBlockTip(hashNewTip);
|
||||
}
|
||||
} while(pindexMostWork != chainActive.Tip());
|
||||
CheckBlockIndex();
|
||||
|
||||
// Write changes periodically to disk, after relay.
|
||||
if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) {
|
||||
@@ -2176,8 +2238,8 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
|
||||
// add them again.
|
||||
BlockMap::iterator it = mapBlockIndex.begin();
|
||||
while (it != mapBlockIndex.end()) {
|
||||
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
|
||||
setBlockIndexCandidates.insert(pindex);
|
||||
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
|
||||
setBlockIndexCandidates.insert(it->second);
|
||||
}
|
||||
it++;
|
||||
}
|
||||
@@ -2263,10 +2325,6 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
pindexNew->nUndoPos = 0;
|
||||
pindexNew->nStatus |= BLOCK_HAVE_DATA;
|
||||
pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
|
||||
{
|
||||
LOCK(cs_nBlockSequenceId);
|
||||
pindexNew->nSequenceId = nBlockSequenceId++;
|
||||
}
|
||||
setDirtyBlockIndex.insert(pindexNew);
|
||||
|
||||
if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
|
||||
@@ -2279,7 +2337,13 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
CBlockIndex *pindex = queue.front();
|
||||
queue.pop_front();
|
||||
pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
|
||||
setBlockIndexCandidates.insert(pindex);
|
||||
{
|
||||
LOCK(cs_nBlockSequenceId);
|
||||
pindex->nSequenceId = nBlockSequenceId++;
|
||||
}
|
||||
if (chainActive.Tip() == NULL || !setBlockIndexCandidates.value_comp()(pindex, chainActive.Tip())) {
|
||||
setBlockIndexCandidates.insert(pindex);
|
||||
}
|
||||
std::pair<std::multimap<CBlockIndex*, CBlockIndex*>::iterator, std::multimap<CBlockIndex*, CBlockIndex*>::iterator> range = mapBlocksUnlinked.equal_range(pindex);
|
||||
while (range.first != range.second) {
|
||||
std::multimap<CBlockIndex*, CBlockIndex*>::iterator it = range.first;
|
||||
@@ -2320,8 +2384,11 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd
|
||||
}
|
||||
|
||||
nLastBlockFile = nFile;
|
||||
vinfoBlockFile[nFile].nSize += nAddSize;
|
||||
vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
|
||||
if (fKnown)
|
||||
vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
|
||||
else
|
||||
vinfoBlockFile[nFile].nSize += nAddSize;
|
||||
|
||||
if (!fKnown) {
|
||||
unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
|
||||
@@ -2487,6 +2554,18 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
|
||||
REJECT_OBSOLETE, "bad-version");
|
||||
}
|
||||
|
||||
// Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded:
|
||||
if (block.nVersion < 3 && CBlockIndex::IsSuperMajority(3, pindexPrev, Params().RejectBlockOutdatedMajority()))
|
||||
{
|
||||
return state.Invalid(error("%s : rejected nVersion=2 block", __func__),
|
||||
REJECT_OBSOLETE, "bad-version");
|
||||
}
|
||||
|
||||
// Reject block.nVersion=3 blocks when 95% (75% on testnet) of the network has upgraded:
|
||||
if (block.nVersion < 4 && CBlockIndex::IsSuperMajority(4, pindexPrev, Params().RejectBlockOutdatedMajority()))
|
||||
return state.Invalid(error("%s : rejected nVersion=3 block", __func__),
|
||||
REJECT_OBSOLETE, "bad-version");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2542,6 +2621,8 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc
|
||||
if (mi == mapBlockIndex.end())
|
||||
return state.DoS(10, error("%s : prev block not found", __func__), 0, "bad-prevblk");
|
||||
pindexPrev = (*mi).second;
|
||||
if (pindexPrev->nStatus & BLOCK_FAILED_MASK)
|
||||
return state.DoS(100, error("%s : prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
|
||||
}
|
||||
|
||||
if (!ContextualCheckBlockHeader(block, state, pindexPrev))
|
||||
@@ -2681,6 +2762,7 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis
|
||||
if (pindex && pfrom) {
|
||||
mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId();
|
||||
}
|
||||
CheckBlockIndex();
|
||||
if (!ret)
|
||||
return error("%s : AcceptBlock FAILED", __func__);
|
||||
}
|
||||
@@ -2726,7 +2808,7 @@ bool AbortNode(const std::string &strMessage, const std::string &userMessage) {
|
||||
strMiscWarning = strMessage;
|
||||
LogPrintf("*** %s\n", strMessage);
|
||||
uiInterface.ThreadSafeMessageBox(
|
||||
userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage,
|
||||
userMessage.empty() ? _("Error: A fatal internal error occurred, see debug.log for details") : userMessage,
|
||||
"", CClientUIInterface::MSG_ERROR);
|
||||
StartShutdown();
|
||||
return false;
|
||||
@@ -2963,6 +3045,8 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
|
||||
} else
|
||||
nGoodTransactions += block.vtx.size();
|
||||
}
|
||||
if (ShutdownRequested())
|
||||
return true;
|
||||
}
|
||||
if (pindexFailure)
|
||||
return error("VerifyDB() : *** coin database inconsistencies found (last %i blocks, %i good transactions before that)\n", chainActive.Height() - pindexFailure->nHeight + 1, nGoodTransactions);
|
||||
@@ -3146,6 +3230,149 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
|
||||
return nLoaded > 0;
|
||||
}
|
||||
|
||||
void static CheckBlockIndex()
|
||||
{
|
||||
if (!fCheckBlockIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
// During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
|
||||
// so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
|
||||
// iterating the block tree require that chainActive has been initialized.)
|
||||
if (chainActive.Height() < 0) {
|
||||
assert(mapBlockIndex.size() <= 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Build forward-pointing map of the entire block tree.
|
||||
std::multimap<CBlockIndex*,CBlockIndex*> forward;
|
||||
for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) {
|
||||
forward.insert(std::make_pair(it->second->pprev, it->second));
|
||||
}
|
||||
|
||||
assert(forward.size() == mapBlockIndex.size());
|
||||
|
||||
std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeGenesis = forward.equal_range(NULL);
|
||||
CBlockIndex *pindex = rangeGenesis.first->second;
|
||||
rangeGenesis.first++;
|
||||
assert(rangeGenesis.first == rangeGenesis.second); // There is only one index entry with parent NULL.
|
||||
|
||||
// Iterate over the entire block tree, using depth-first search.
|
||||
// Along the way, remember whether there are blocks on the path from genesis
|
||||
// block being explored which are the first to have certain properties.
|
||||
size_t nNodes = 0;
|
||||
int nHeight = 0;
|
||||
CBlockIndex* pindexFirstInvalid = NULL; // Oldest ancestor of pindex which is invalid.
|
||||
CBlockIndex* pindexFirstMissing = NULL; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA.
|
||||
CBlockIndex* pindexFirstNotTreeValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
|
||||
CBlockIndex* pindexFirstNotChainValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
|
||||
CBlockIndex* pindexFirstNotScriptsValid = NULL; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
|
||||
while (pindex != NULL) {
|
||||
nNodes++;
|
||||
if (pindexFirstInvalid == NULL && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
|
||||
if (pindexFirstMissing == NULL && !(pindex->nStatus & BLOCK_HAVE_DATA)) pindexFirstMissing = pindex;
|
||||
if (pindex->pprev != NULL && pindexFirstNotTreeValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_TREE) pindexFirstNotTreeValid = pindex;
|
||||
if (pindex->pprev != NULL && pindexFirstNotChainValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_CHAIN) pindexFirstNotChainValid = pindex;
|
||||
if (pindex->pprev != NULL && pindexFirstNotScriptsValid == NULL && (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS) pindexFirstNotScriptsValid = pindex;
|
||||
|
||||
// Begin: actual consistency checks.
|
||||
if (pindex->pprev == NULL) {
|
||||
// Genesis block checks.
|
||||
assert(pindex->GetBlockHash() == Params().HashGenesisBlock()); // Genesis block's hash must match.
|
||||
assert(pindex == chainActive.Genesis()); // The current active chain's genesis block must be this block.
|
||||
}
|
||||
// HAVE_DATA is equivalent to VALID_TRANSACTIONS and equivalent to nTx > 0 (we stored the number of transactions in the block)
|
||||
assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
|
||||
assert(((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS) == (pindex->nTx > 0));
|
||||
if (pindex->nChainTx == 0) assert(pindex->nSequenceId == 0); // nSequenceId can't be set for blocks that aren't linked
|
||||
// All parents having data is equivalent to all parents being VALID_TRANSACTIONS, which is equivalent to nChainTx being set.
|
||||
assert((pindexFirstMissing != NULL) == (pindex->nChainTx == 0)); // nChainTx == 0 is used to signal that all parent block's transaction data is available.
|
||||
assert(pindex->nHeight == nHeight); // nHeight must be consistent.
|
||||
assert(pindex->pprev == NULL || pindex->nChainWork >= pindex->pprev->nChainWork); // For every block except the genesis block, the chainwork must be larger than the parent's.
|
||||
assert(nHeight < 2 || (pindex->pskip && (pindex->pskip->nHeight < nHeight))); // The pskip pointer must point back for all but the first 2 blocks.
|
||||
assert(pindexFirstNotTreeValid == NULL); // All mapBlockIndex entries must at least be TREE valid
|
||||
if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TREE) assert(pindexFirstNotTreeValid == NULL); // TREE valid implies all parents are TREE valid
|
||||
if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_CHAIN) assert(pindexFirstNotChainValid == NULL); // CHAIN valid implies all parents are CHAIN valid
|
||||
if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_SCRIPTS) assert(pindexFirstNotScriptsValid == NULL); // SCRIPTS valid implies all parents are SCRIPTS valid
|
||||
if (pindexFirstInvalid == NULL) {
|
||||
// Checks for not-invalid blocks.
|
||||
assert((pindex->nStatus & BLOCK_FAILED_MASK) == 0); // The failed mask cannot be set for blocks without invalid parents.
|
||||
}
|
||||
if (!CBlockIndexWorkComparator()(pindex, chainActive.Tip()) && pindexFirstMissing == NULL) {
|
||||
if (pindexFirstInvalid == NULL) { // If this block sorts at least as good as the current tip and is valid, it must be in setBlockIndexCandidates.
|
||||
assert(setBlockIndexCandidates.count(pindex));
|
||||
}
|
||||
} else { // If this block sorts worse than the current tip, it cannot be in setBlockIndexCandidates.
|
||||
assert(setBlockIndexCandidates.count(pindex) == 0);
|
||||
}
|
||||
// Check whether this block is in mapBlocksUnlinked.
|
||||
std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = mapBlocksUnlinked.equal_range(pindex->pprev);
|
||||
bool foundInUnlinked = false;
|
||||
while (rangeUnlinked.first != rangeUnlinked.second) {
|
||||
assert(rangeUnlinked.first->first == pindex->pprev);
|
||||
if (rangeUnlinked.first->second == pindex) {
|
||||
foundInUnlinked = true;
|
||||
break;
|
||||
}
|
||||
rangeUnlinked.first++;
|
||||
}
|
||||
if (pindex->pprev && pindex->nStatus & BLOCK_HAVE_DATA && pindexFirstMissing != NULL) {
|
||||
if (pindexFirstInvalid == NULL) { // If this block has block data available, some parent doesn't, and has no invalid parents, it must be in mapBlocksUnlinked.
|
||||
assert(foundInUnlinked);
|
||||
}
|
||||
} else { // If this block does not have block data available, or all parents do, it cannot be in mapBlocksUnlinked.
|
||||
assert(!foundInUnlinked);
|
||||
}
|
||||
// assert(pindex->GetBlockHash() == pindex->GetBlockHeader().GetHash()); // Perhaps too slow
|
||||
// End: actual consistency checks.
|
||||
|
||||
// Try descending into the first subnode.
|
||||
std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
|
||||
if (range.first != range.second) {
|
||||
// A subnode was found.
|
||||
pindex = range.first->second;
|
||||
nHeight++;
|
||||
continue;
|
||||
}
|
||||
// This is a leaf node.
|
||||
// Move upwards until we reach a node of which we have not yet visited the last child.
|
||||
while (pindex) {
|
||||
// We are going to either move to a parent or a sibling of pindex.
|
||||
// If pindex was the first with a certain property, unset the corresponding variable.
|
||||
if (pindex == pindexFirstInvalid) pindexFirstInvalid = NULL;
|
||||
if (pindex == pindexFirstMissing) pindexFirstMissing = NULL;
|
||||
if (pindex == pindexFirstNotTreeValid) pindexFirstNotTreeValid = NULL;
|
||||
if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = NULL;
|
||||
if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = NULL;
|
||||
// Find our parent.
|
||||
CBlockIndex* pindexPar = pindex->pprev;
|
||||
// Find which child we just visited.
|
||||
std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
|
||||
while (rangePar.first->second != pindex) {
|
||||
assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
|
||||
rangePar.first++;
|
||||
}
|
||||
// Proceed to the next one.
|
||||
rangePar.first++;
|
||||
if (rangePar.first != rangePar.second) {
|
||||
// Move to the sibling.
|
||||
pindex = rangePar.first->second;
|
||||
break;
|
||||
} else {
|
||||
// Move up further.
|
||||
pindex = pindexPar;
|
||||
nHeight--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that we actually traversed the entire map.
|
||||
assert(nNodes == forward.size());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CAlert
|
||||
@@ -3259,19 +3486,17 @@ void static ProcessGetData(CNode* pfrom)
|
||||
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
|
||||
if (mi != mapBlockIndex.end())
|
||||
{
|
||||
// If the requested block is at a height below our last
|
||||
// checkpoint, only serve it if it's in the checkpointed chain
|
||||
int nHeight = mi->second->nHeight;
|
||||
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
|
||||
if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
|
||||
if (!chainActive.Contains(mi->second))
|
||||
{
|
||||
LogPrintf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n");
|
||||
} else {
|
||||
send = true;
|
||||
}
|
||||
} else {
|
||||
if (chainActive.Contains(mi->second)) {
|
||||
send = true;
|
||||
} else {
|
||||
// To prevent fingerprinting attacks, only send blocks outside of the active
|
||||
// chain if they are valid, and no more than a month older than the best header
|
||||
// chain we know about.
|
||||
send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
|
||||
(mi->second->GetBlockTime() > pindexBestHeader->GetBlockTime() - 30 * 24 * 60 * 60);
|
||||
if (!send) {
|
||||
LogPrintf("ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (send)
|
||||
@@ -3369,7 +3594,7 @@ void static ProcessGetData(CNode* pfrom)
|
||||
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
|
||||
{
|
||||
RandAddSeedPerfmon();
|
||||
LogPrint("net", "received: %s (%u bytes) peer=%d\n", strCommand, vRecv.size(), pfrom->id);
|
||||
LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
|
||||
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
|
||||
{
|
||||
LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
|
||||
@@ -3509,6 +3734,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
else if (strCommand == "verack")
|
||||
{
|
||||
pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
|
||||
|
||||
// Mark this node as currently connected, so we update its timestamp later.
|
||||
if (pfrom->fNetworkNode) {
|
||||
LOCK(cs_main);
|
||||
State(pfrom->GetId())->fCurrentlyConnected = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3618,7 +3849,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
// doing this will result in the received block being rejected as an orphan in case it is
|
||||
// not a direct successor.
|
||||
pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash);
|
||||
if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20) {
|
||||
CNodeState *nodestate = State(pfrom->GetId());
|
||||
if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20 &&
|
||||
nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
|
||||
vToFetch.push_back(inv);
|
||||
// Mark block as in flight already, even though the actual "getdata" message only goes out
|
||||
// later (within the same cs_main lock, though).
|
||||
@@ -3896,6 +4129,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
|
||||
pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256(0));
|
||||
}
|
||||
|
||||
CheckBlockIndex();
|
||||
}
|
||||
|
||||
else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing
|
||||
@@ -3923,7 +4158,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
}
|
||||
|
||||
|
||||
else if (strCommand == "getaddr")
|
||||
// This asymmetric behavior for inbound and outbound connections was introduced
|
||||
// to prevent a fingerprinting attack: an attacker can send specific fake addresses
|
||||
// to users' AddrMan and later request them by sending getaddr messages.
|
||||
// Making users (which are behind NAT and can only make outgoing connections) ignore
|
||||
// getaddr message mitigates the attack.
|
||||
else if ((strCommand == "getaddr") && (pfrom->fInbound))
|
||||
{
|
||||
pfrom->vAddrToSend.clear();
|
||||
vector<CAddress> vAddr = addrman.GetAddr();
|
||||
@@ -4036,34 +4276,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
}
|
||||
|
||||
|
||||
else if (strCommand == "alert")
|
||||
else if (fAlerts && strCommand == "alert")
|
||||
{
|
||||
CAlert alert;
|
||||
vRecv >> alert;
|
||||
|
||||
uint256 alertHash = alert.GetHash();
|
||||
if (pfrom->setKnown.count(alertHash) == 0)
|
||||
{
|
||||
if (alert.ProcessAlert())
|
||||
{
|
||||
// Relay
|
||||
pfrom->setKnown.insert(alertHash);
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
alert.RelayTo(pnode);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Small DoS penalty so peers that send us lots of
|
||||
// duplicate/expired/invalid-signature/whatever alerts
|
||||
// eventually get banned.
|
||||
// This isn't a Misbehaving(100) (immediate ban) because the
|
||||
// peer might be an older or different implementation with
|
||||
// a different signature key, etc.
|
||||
Misbehaving(pfrom->GetId(), 10);
|
||||
}
|
||||
}
|
||||
// Alert message handling disabled
|
||||
// See https://bitcoin.org/en/alert/2016-11-01-alert-retirement
|
||||
}
|
||||
|
||||
|
||||
@@ -4146,11 +4362,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
}
|
||||
|
||||
|
||||
// Update the last seen time for this node's address
|
||||
if (pfrom->fNetworkNode)
|
||||
if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping")
|
||||
AddressCurrentlyConnected(pfrom->addr);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -4200,7 +4411,7 @@ bool ProcessMessages(CNode* pfrom)
|
||||
|
||||
// Scan for message start
|
||||
if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
|
||||
LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", msg.hdr.GetCommand(), pfrom->id);
|
||||
LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
|
||||
fOk = false;
|
||||
break;
|
||||
}
|
||||
@@ -4209,7 +4420,7 @@ bool ProcessMessages(CNode* pfrom)
|
||||
CMessageHeader& hdr = msg.hdr;
|
||||
if (!hdr.IsValid())
|
||||
{
|
||||
LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", hdr.GetCommand(), pfrom->id);
|
||||
LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
|
||||
continue;
|
||||
}
|
||||
string strCommand = hdr.GetCommand();
|
||||
@@ -4224,8 +4435,8 @@ bool ProcessMessages(CNode* pfrom)
|
||||
memcpy(&nChecksum, &hash, sizeof(nChecksum));
|
||||
if (nChecksum != hdr.nChecksum)
|
||||
{
|
||||
LogPrintf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
|
||||
strCommand, nMessageSize, nChecksum, hdr.nChecksum);
|
||||
LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
|
||||
SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -4242,12 +4453,12 @@ bool ProcessMessages(CNode* pfrom)
|
||||
if (strstr(e.what(), "end of data"))
|
||||
{
|
||||
// Allow exceptions from under-length message on vRecv
|
||||
LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand, nMessageSize, e.what());
|
||||
LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", SanitizeString(strCommand), nMessageSize, e.what());
|
||||
}
|
||||
else if (strstr(e.what(), "size too large"))
|
||||
{
|
||||
// Allow exceptions from over-long size
|
||||
LogPrintf("ProcessMessages(%s, %u bytes) : Exception '%s' caught\n", strCommand, nMessageSize, e.what());
|
||||
LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", SanitizeString(strCommand), nMessageSize, e.what());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4264,7 +4475,7 @@ bool ProcessMessages(CNode* pfrom)
|
||||
}
|
||||
|
||||
if (!fRet)
|
||||
LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", strCommand, nMessageSize, pfrom->id);
|
||||
LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", SanitizeString(strCommand), nMessageSize, pfrom->id);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -4461,6 +4672,15 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||
LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
|
||||
pto->fDisconnect = true;
|
||||
}
|
||||
// In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
|
||||
// (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
|
||||
// timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
|
||||
// being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes
|
||||
// to unreasonably increase our timeout.
|
||||
if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacing() * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) {
|
||||
LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id);
|
||||
pto->fDisconnect = true;
|
||||
}
|
||||
|
||||
//
|
||||
// Message: getdata (blocks)
|
||||
|
||||
15
src/main.h
15
src/main.h
@@ -54,6 +54,8 @@ static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000;
|
||||
static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0;
|
||||
/** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/
|
||||
static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 50000;
|
||||
/** Default for accepting alerts from the P2P network. */
|
||||
static const bool DEFAULT_ALERTS = true;
|
||||
/** The maximum size for transactions we're willing to relay/mine */
|
||||
static const unsigned int MAX_STANDARD_TX_SIZE = 100000;
|
||||
/** The maximum allowed number of signature check operations in a block (network rule) */
|
||||
@@ -64,8 +66,6 @@ static const unsigned int MAX_P2SH_SIGOPS = 15;
|
||||
static const unsigned int MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5;
|
||||
/** Default for -maxorphantx, maximum number of orphan transactions kept in memory */
|
||||
static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100;
|
||||
/** Default for -maxorphanblocks, maximum number of orphan blocks kept in memory */
|
||||
static const unsigned int DEFAULT_MAX_ORPHAN_BLOCKS = 750;
|
||||
/** The maximum size of a blk?????.dat file (since 0.8) */
|
||||
static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
|
||||
/** The pre-allocation chunk size for blk?????.dat files (since 0.8) */
|
||||
@@ -74,8 +74,6 @@ static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
|
||||
static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
|
||||
/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
|
||||
static const int COINBASE_MATURITY = 100;
|
||||
/** Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. */
|
||||
static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
|
||||
/** Maximum number of script-checking threads allowed */
|
||||
static const int MAX_SCRIPTCHECK_THREADS = 16;
|
||||
/** -par default (number of script-checking threads, 0 = auto) */
|
||||
@@ -128,8 +126,10 @@ extern bool fReindex;
|
||||
extern int nScriptCheckThreads;
|
||||
extern bool fTxIndex;
|
||||
extern bool fIsBareMultisigStd;
|
||||
extern bool fCheckBlockIndex;
|
||||
extern unsigned int nCoinCacheSize;
|
||||
extern CFeeRate minRelayTxFee;
|
||||
extern bool fAlerts;
|
||||
|
||||
/** Best header we've seen so far (used for getheaders queries' starting points). */
|
||||
extern CBlockIndex *pindexBestHeader;
|
||||
@@ -181,7 +181,12 @@ bool LoadBlockIndex();
|
||||
void UnloadBlockIndex();
|
||||
/** Process protocol messages received from a given node */
|
||||
bool ProcessMessages(CNode* pfrom);
|
||||
/** Send queued protocol messages to be sent to a give node */
|
||||
/**
|
||||
* Send queued protocol messages to be sent to a give node.
|
||||
*
|
||||
* @param[in] pto The node which we are sending messages to.
|
||||
* @param[in] fSendTrickle When true send the trickled data, otherwise trickle the data until true.
|
||||
*/
|
||||
bool SendMessages(CNode* pto, bool fSendTrickle);
|
||||
/** Run an instance of the script checking thread */
|
||||
void ThreadScriptCheck();
|
||||
|
||||
@@ -139,7 +139,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
|
||||
// traverse the partial tree
|
||||
unsigned int nBitsUsed = 0, nHashUsed = 0;
|
||||
uint256 hashMerkleRoot = TraverseAndExtract(nHeight, 0, nBitsUsed, nHashUsed, vMatch);
|
||||
// verify that no problems occured during the tree traversal
|
||||
// verify that no problems occurred during the tree traversal
|
||||
if (fBad)
|
||||
return 0;
|
||||
// verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence)
|
||||
|
||||
@@ -456,8 +456,16 @@ void static BitcoinMiner(CWallet *pwallet)
|
||||
if (Params().MiningRequiresPeers()) {
|
||||
// Busy-wait for the network to come online so we don't waste time mining
|
||||
// on an obsolete chain. In regtest mode we expect to fly solo.
|
||||
while (vNodes.empty())
|
||||
do {
|
||||
bool fvNodesEmpty;
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
fvNodesEmpty = vNodes.empty();
|
||||
}
|
||||
if (!fvNodesEmpty && !IsInitialBlockDownload())
|
||||
break;
|
||||
MilliSleep(1000);
|
||||
} while (true);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -570,6 +578,11 @@ void static BitcoinMiner(CWallet *pwallet)
|
||||
LogPrintf("BitcoinMiner terminated\n");
|
||||
throw;
|
||||
}
|
||||
catch (const std::runtime_error &e)
|
||||
{
|
||||
LogPrintf("BitcoinMiner runtime error: %s\n", e.what());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
|
||||
|
||||
53
src/net.cpp
53
src/net.cpp
@@ -403,6 +403,12 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
|
||||
if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) :
|
||||
ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed))
|
||||
{
|
||||
if (!IsSelectableSocket(hSocket)) {
|
||||
LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
|
||||
CloseSocket(hSocket);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
addrman.Attempt(addrConnect);
|
||||
|
||||
// Add node
|
||||
@@ -574,6 +580,11 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
|
||||
if (handled < 0)
|
||||
return false;
|
||||
|
||||
if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
|
||||
LogPrint("net", "Oversized message from peer=%i, disconnecting\n", GetId());
|
||||
return false;
|
||||
}
|
||||
|
||||
pch += handled;
|
||||
nBytes -= handled;
|
||||
|
||||
@@ -866,8 +877,14 @@ void ThreadSocketHandler()
|
||||
if (nErr != WSAEWOULDBLOCK)
|
||||
LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
|
||||
}
|
||||
else if (!IsSelectableSocket(hSocket))
|
||||
{
|
||||
LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
|
||||
CloseSocket(hSocket);
|
||||
}
|
||||
else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS)
|
||||
{
|
||||
LogPrint("net", "connection from %s dropped (full)\n", addr.ToString());
|
||||
CloseSocket(hSocket);
|
||||
}
|
||||
else if (CNode::IsBanned(addr) && !whitelisted)
|
||||
@@ -877,6 +894,15 @@ void ThreadSocketHandler()
|
||||
}
|
||||
else
|
||||
{
|
||||
// According to the internet TCP_NODELAY is not carried into accepted sockets
|
||||
// on all platforms. Set it again here just to be sure.
|
||||
int set = 1;
|
||||
#ifdef WIN32
|
||||
setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&set, sizeof(int));
|
||||
#else
|
||||
setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&set, sizeof(int));
|
||||
#endif
|
||||
|
||||
CNode* pnode = new CNode(hSocket, addr, "", true);
|
||||
pnode->AddRef();
|
||||
pnode->fWhitelisted = whitelisted;
|
||||
@@ -1015,10 +1041,14 @@ void ThreadMapPort()
|
||||
#ifndef UPNPDISCOVER_SUCCESS
|
||||
/* miniupnpc 1.5 */
|
||||
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
|
||||
#else
|
||||
#elif MINIUPNPC_API_VERSION < 14
|
||||
/* miniupnpc 1.6 */
|
||||
int error = 0;
|
||||
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
|
||||
#else
|
||||
/* miniupnpc 1.9.20150730 */
|
||||
int error = 0;
|
||||
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
|
||||
#endif
|
||||
|
||||
struct UPNPUrls urls;
|
||||
@@ -1266,8 +1296,7 @@ void ThreadOpenConnections()
|
||||
int nTries = 0;
|
||||
while (true)
|
||||
{
|
||||
// use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
|
||||
CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
|
||||
CAddress addr = addrman.Select();
|
||||
|
||||
// if we selected an invalid address, restart
|
||||
if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
|
||||
@@ -1451,7 +1480,7 @@ void ThreadMessageHandler()
|
||||
{
|
||||
TRY_LOCK(pnode->cs_vSend, lockSend);
|
||||
if (lockSend)
|
||||
g_signals.SendMessages(pnode, pnode == pnodeTrickle);
|
||||
g_signals.SendMessages(pnode, pnode == pnodeTrickle || pnode->fWhitelisted);
|
||||
}
|
||||
boost::this_thread::interruption_point();
|
||||
}
|
||||
@@ -1494,6 +1523,13 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste
|
||||
LogPrintf("%s\n", strError);
|
||||
return false;
|
||||
}
|
||||
if (!IsSelectableSocket(hListenSocket))
|
||||
{
|
||||
strError = "Error: Couldn't create a listenable socket for incoming connections";
|
||||
LogPrintf("%s\n", strError);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
#ifdef SO_NOSIGPIPE
|
||||
@@ -1501,8 +1537,13 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste
|
||||
setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
|
||||
#endif
|
||||
// Allow binding if the port is still in TIME_WAIT state after
|
||||
// the program was closed and restarted. Not an issue on windows!
|
||||
// the program was closed and restarted.
|
||||
setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
|
||||
// Disable Nagle's algorithm
|
||||
setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&nOne, sizeof(int));
|
||||
#else
|
||||
setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&nOne, sizeof(int));
|
||||
setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&nOne, sizeof(int));
|
||||
#endif
|
||||
|
||||
// Set to non-blocking, incoming connections will also inherit this
|
||||
@@ -2021,7 +2062,7 @@ void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSen
|
||||
ENTER_CRITICAL_SECTION(cs_vSend);
|
||||
assert(ssSend.size() == 0);
|
||||
ssSend << CMessageHeader(pszCommand, 0);
|
||||
LogPrint("net", "sending: %s ", pszCommand);
|
||||
LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
|
||||
}
|
||||
|
||||
void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
|
||||
|
||||
@@ -46,6 +46,8 @@ static const int TIMEOUT_INTERVAL = 20 * 60;
|
||||
static const unsigned int MAX_INV_SZ = 50000;
|
||||
/** The maximum number of new addresses to accumulate before announcing. */
|
||||
static const unsigned int MAX_ADDR_TO_SEND = 1000;
|
||||
/** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */
|
||||
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024;
|
||||
/** -listen default */
|
||||
static const bool DEFAULT_LISTEN = true;
|
||||
/** -upnp default */
|
||||
|
||||
@@ -267,6 +267,9 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock
|
||||
} else { // Other error or blocking
|
||||
int nErr = WSAGetLastError();
|
||||
if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) {
|
||||
if (!IsSelectableSocket(hSocket)) {
|
||||
return false;
|
||||
}
|
||||
struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait));
|
||||
fd_set fdset;
|
||||
FD_ZERO(&fdset);
|
||||
@@ -404,12 +407,19 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
|
||||
if (hSocket == INVALID_SOCKET)
|
||||
return false;
|
||||
|
||||
#ifdef SO_NOSIGPIPE
|
||||
int set = 1;
|
||||
#ifdef SO_NOSIGPIPE
|
||||
// Different way of disabling SIGPIPE on BSD
|
||||
setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
|
||||
#endif
|
||||
|
||||
//Disable Nagle's algorithm
|
||||
#ifdef WIN32
|
||||
setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&set, sizeof(int));
|
||||
#else
|
||||
setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&set, sizeof(int));
|
||||
#endif
|
||||
|
||||
// Set to non-blocking
|
||||
if (!SetSocketNonBlocking(hSocket, true))
|
||||
return error("ConnectSocketDirectly: Setting socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
|
||||
@@ -944,7 +954,7 @@ std::vector<unsigned char> CNetAddr::GetGroup() const
|
||||
nBits -= 8;
|
||||
}
|
||||
if (nBits > 0)
|
||||
vchRet.push_back(GetByte(15 - nStartByte) | ((1 << nBits) - 1));
|
||||
vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1));
|
||||
|
||||
return vchRet;
|
||||
}
|
||||
@@ -1214,15 +1224,15 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup)
|
||||
std::string strNetmask = strSubnet.substr(slash + 1);
|
||||
int32_t n;
|
||||
// IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n
|
||||
int noffset = network.IsIPv4() ? (12 * 8) : 0;
|
||||
const int astartofs = network.IsIPv4() ? 12 : 0;
|
||||
if (ParseInt32(strNetmask, &n)) // If valid number, assume /24 symtex
|
||||
{
|
||||
if(n >= 0 && n <= (128 - noffset)) // Only valid if in range of bits of address
|
||||
if(n >= 0 && n <= (128 - astartofs*8)) // Only valid if in range of bits of address
|
||||
{
|
||||
n += noffset;
|
||||
n += astartofs*8;
|
||||
// Clear bits [n..127]
|
||||
for (; n < 128; ++n)
|
||||
netmask[n>>3] &= ~(1<<(n&7));
|
||||
netmask[n>>3] &= ~(1<<(7-(n&7)));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1233,12 +1243,10 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup)
|
||||
{
|
||||
if (LookupHost(strNetmask.c_str(), vIP, 1, false)) // Never allow lookup for netmask
|
||||
{
|
||||
// Remember: GetByte returns bytes in reversed order
|
||||
// Copy only the *last* four bytes in case of IPv4, the rest of the mask should stay 1's as
|
||||
// we don't want pchIPv4 to be part of the mask.
|
||||
int asize = network.IsIPv4() ? 4 : 16;
|
||||
for(int x=0; x<asize; ++x)
|
||||
netmask[15-x] = vIP[0].GetByte(x);
|
||||
for(int x=astartofs; x<16; ++x)
|
||||
netmask[x] = vIP[0].ip[x];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1251,6 +1259,10 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup)
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
|
||||
// Normalize network according to netmask
|
||||
for(int x=0; x<16; ++x)
|
||||
network.ip[x] &= netmask[x];
|
||||
}
|
||||
|
||||
bool CSubNet::Match(const CNetAddr &addr) const
|
||||
@@ -1258,7 +1270,7 @@ bool CSubNet::Match(const CNetAddr &addr) const
|
||||
if (!valid || !addr.IsValid())
|
||||
return false;
|
||||
for(int x=0; x<16; ++x)
|
||||
if ((addr.GetByte(x) & netmask[15-x]) != network.GetByte(x))
|
||||
if ((addr.ip[x] & netmask[x]) != network.ip[x])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -100,6 +100,8 @@ class CNetAddr
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
READWRITE(FLATDATA(ip));
|
||||
}
|
||||
|
||||
friend class CSubNet;
|
||||
};
|
||||
|
||||
class CSubNet
|
||||
|
||||
@@ -24,7 +24,7 @@ class CBlockHeader
|
||||
{
|
||||
public:
|
||||
// header
|
||||
static const int32_t CURRENT_VERSION=2;
|
||||
static const int32_t CURRENT_VERSION=4;
|
||||
int32_t nVersion;
|
||||
uint256 hashPrevBlock;
|
||||
uint256 hashMerkleRoot;
|
||||
|
||||
@@ -40,7 +40,7 @@ CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSize
|
||||
|
||||
std::string CMessageHeader::GetCommand() const
|
||||
{
|
||||
return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
|
||||
return std::string(pchCommand, pchCommand + strnlen_int(pchCommand, COMMAND_SIZE));
|
||||
}
|
||||
|
||||
bool CMessageHeader::IsValid() const
|
||||
|
||||
@@ -89,17 +89,9 @@ static std::string Translate(const char* psz)
|
||||
return QCoreApplication::translate("bitcoin-core", psz).toStdString();
|
||||
}
|
||||
|
||||
/** Set up translations */
|
||||
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
|
||||
static QString GetLangTerritory()
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
// Remove old translators
|
||||
QApplication::removeTranslator(&qtTranslatorBase);
|
||||
QApplication::removeTranslator(&qtTranslator);
|
||||
QApplication::removeTranslator(&translatorBase);
|
||||
QApplication::removeTranslator(&translator);
|
||||
|
||||
// Get desired locale (e.g. "de_DE")
|
||||
// 1) System default language
|
||||
QString lang_territory = QLocale::system().name();
|
||||
@@ -109,6 +101,22 @@ static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTrans
|
||||
lang_territory = lang_territory_qsettings;
|
||||
// 3) -lang command line argument
|
||||
lang_territory = QString::fromStdString(GetArg("-lang", lang_territory.toStdString()));
|
||||
return lang_territory;
|
||||
}
|
||||
|
||||
/** Set up translations */
|
||||
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
|
||||
{
|
||||
|
||||
// Remove old translators
|
||||
QApplication::removeTranslator(&qtTranslatorBase);
|
||||
QApplication::removeTranslator(&qtTranslator);
|
||||
QApplication::removeTranslator(&translatorBase);
|
||||
QApplication::removeTranslator(&translator);
|
||||
|
||||
// Get desired locale (e.g. "de_DE")
|
||||
// 1) System default language
|
||||
QString lang_territory = GetLangTerritory();
|
||||
|
||||
// Convert to "de" only by truncating "_DE"
|
||||
QString lang = lang_territory;
|
||||
@@ -498,8 +506,6 @@ int main(int argc, char *argv[])
|
||||
Q_INIT_RESOURCE(bitcoin);
|
||||
Q_INIT_RESOURCE(bitcoin_locale);
|
||||
|
||||
GUIUtil::SubstituteFonts();
|
||||
|
||||
BitcoinApplication app(argc, argv);
|
||||
#if QT_VERSION > 0x050100
|
||||
// Generate high-dpi pixmaps
|
||||
@@ -521,6 +527,7 @@ int main(int argc, char *argv[])
|
||||
QApplication::setOrganizationName(QAPP_ORG_NAME);
|
||||
QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
|
||||
QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
|
||||
GUIUtil::SubstituteFonts(GetLangTerritory());
|
||||
|
||||
/// 4. Initialization of translations, so that intro dialog is in user's language
|
||||
// Now that QSettings are accessible, initialize translations
|
||||
@@ -530,7 +537,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Show help message immediately after parsing command-line options (for "-lang") and setting locale,
|
||||
// but before showing splash screen.
|
||||
if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version"))
|
||||
if (mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version"))
|
||||
{
|
||||
HelpMessageDialog help(NULL, mapArgs.count("-version"));
|
||||
help.showOrPrint();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
class AmountSpinBox: public QAbstractSpinBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AmountSpinBox(QWidget *parent):
|
||||
QAbstractSpinBox(parent),
|
||||
@@ -72,23 +73,6 @@ public:
|
||||
setValue(val);
|
||||
}
|
||||
|
||||
StepEnabled stepEnabled() const
|
||||
{
|
||||
StepEnabled rv = 0;
|
||||
if(text().isEmpty()) // Allow step-up with empty field
|
||||
return StepUpEnabled;
|
||||
bool valid = false;
|
||||
CAmount val = value(&valid);
|
||||
if(valid)
|
||||
{
|
||||
if(val > 0)
|
||||
rv |= StepDownEnabled;
|
||||
if(val < BitcoinUnits::maxMoney())
|
||||
rv |= StepUpEnabled;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void setDisplayUnit(int unit)
|
||||
{
|
||||
bool valid = false;
|
||||
@@ -139,6 +123,7 @@ public:
|
||||
}
|
||||
return cachedMinimumSizeHint;
|
||||
}
|
||||
|
||||
private:
|
||||
int currentUnit;
|
||||
CAmount singleStep;
|
||||
@@ -179,6 +164,25 @@ protected:
|
||||
return QAbstractSpinBox::event(event);
|
||||
}
|
||||
|
||||
StepEnabled stepEnabled() const
|
||||
{
|
||||
StepEnabled rv = 0;
|
||||
if (isReadOnly()) // Disable steps when AmountSpinBox is read-only
|
||||
return StepNone;
|
||||
if(text().isEmpty()) // Allow step-up with empty field
|
||||
return StepUpEnabled;
|
||||
bool valid = false;
|
||||
CAmount val = value(&valid);
|
||||
if(valid)
|
||||
{
|
||||
if(val > 0)
|
||||
rv |= StepDownEnabled;
|
||||
if(val < BitcoinUnits::maxMoney())
|
||||
rv |= StepUpEnabled;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
signals:
|
||||
void valueChanged();
|
||||
};
|
||||
|
||||
@@ -207,11 +207,6 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
|
||||
statusBar()->addWidget(progressBar);
|
||||
statusBar()->addPermanentWidget(frameBlocks);
|
||||
|
||||
connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));
|
||||
|
||||
// prevents an open debug window from becoming stuck/unusable on client shutdown
|
||||
connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide()));
|
||||
|
||||
// Install event filter to be able to catch status tip events (QEvent::StatusTip)
|
||||
this->installEventFilter(this);
|
||||
|
||||
@@ -232,7 +227,7 @@ BitcoinGUI::~BitcoinGUI()
|
||||
trayIcon->hide();
|
||||
#ifdef Q_OS_MAC
|
||||
delete appMenuBar;
|
||||
MacDockIconHandler::instance()->setMainWindow(NULL);
|
||||
MacDockIconHandler::cleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -325,6 +320,7 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
|
||||
openAction->setStatusTip(tr("Open a bitcoin: URI or payment request"));
|
||||
|
||||
showHelpMessageAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation), tr("&Command-line options"), this);
|
||||
showHelpMessageAction->setMenuRole(QAction::NoRole);
|
||||
showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options"));
|
||||
|
||||
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
|
||||
@@ -333,6 +329,10 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
|
||||
connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
|
||||
connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden()));
|
||||
connect(showHelpMessageAction, SIGNAL(triggered()), this, SLOT(showHelpMessageClicked()));
|
||||
connect(openRPCConsoleAction, SIGNAL(triggered()), this, SLOT(showDebugWindow()));
|
||||
// prevents an open debug window from becoming stuck/unusable on client shutdown
|
||||
connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide()));
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
if(walletFrame)
|
||||
{
|
||||
@@ -568,6 +568,14 @@ void BitcoinGUI::aboutClicked()
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void BitcoinGUI::showDebugWindow()
|
||||
{
|
||||
rpcConsole->showNormal();
|
||||
rpcConsole->show();
|
||||
rpcConsole->raise();
|
||||
rpcConsole->activateWindow();
|
||||
}
|
||||
|
||||
void BitcoinGUI::showHelpMessageClicked()
|
||||
{
|
||||
HelpMessageDialog *help = new HelpMessageDialog(this, false);
|
||||
|
||||
@@ -189,6 +189,8 @@ private slots:
|
||||
void optionsClicked();
|
||||
/** Show about dialog */
|
||||
void aboutClicked();
|
||||
/** Show debug window */
|
||||
void showDebugWindow();
|
||||
/** Show help message dialog */
|
||||
void showHelpMessageClicked();
|
||||
#ifndef Q_OS_MAC
|
||||
|
||||
@@ -10,18 +10,6 @@
|
||||
#endif
|
||||
static const char UNUSED *bitcoin_strings[] = {
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"%s, you must set a rpcpassword in the configuration file:\n"
|
||||
"%s\n"
|
||||
"It is recommended you use the following random password:\n"
|
||||
"rpcuser=bitcoinrpc\n"
|
||||
"rpcpassword=%s\n"
|
||||
"(you do not need to remember this password)\n"
|
||||
"The username and password MUST NOT be the same.\n"
|
||||
"If the file does not exist, create it with owner-readable-only file "
|
||||
"permissions.\n"
|
||||
"It is also recommended to set alertnotify so you are notified of problems;\n"
|
||||
"for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"(1 = keep tx meta data e.g. account owner and payment request information, 2 "
|
||||
"= drop tx meta data)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
@@ -62,13 +50,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: Listening for incoming connections failed (listen returned error %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: The transaction was rejected! This might happen if some of the coins "
|
||||
"in your wallet were already spent, such as if you used a copy of wallet.dat "
|
||||
"and coins were spent in the copy but not marked as spent here."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: This transaction requires a transaction fee of at least %s because of "
|
||||
"its amount, complexity, or use of recently received funds!"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: Unsupported argument -socks found. Setting SOCKS version isn't "
|
||||
"possible anymore, only SOCKS5 proxies are supported."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
@@ -92,12 +73,15 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"How thorough the block verification of -checkblocks is (0-4, default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"If paytxfee is not set, include enough fee so transactions are confirmed on "
|
||||
"average within n blocks (default: %u)"),
|
||||
"If paytxfee is not set, include enough fee so transactions begin "
|
||||
"confirmation on average within n blocks (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"In this mode -genproclimit controls how many blocks are generated "
|
||||
"immediately."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay "
|
||||
"fee of %s to prevent stuck transactions)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Log transaction priority and fee per kB when mining blocks (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Maintain a full transaction index, used by the getrawtransaction rpc call "
|
||||
@@ -106,6 +90,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Maximum size of data in data carrier transactions we relay and mine "
|
||||
"(default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Maximum total fees to use in a single wallet transaction, setting too low "
|
||||
"may abort large transactions (default: %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Number of seconds to keep misbehaving peers from reconnecting (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Output debugging information (default: %u, supplying <category> is optional)"),
|
||||
@@ -113,6 +100,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Query for peer addresses via DNS lookup, if low on addresses (default: 1 "
|
||||
"unless -connect)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Require high priority for relaying free or low-fee transactions (default:%u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Set the number of script verification threads (%u to %d, 0 = auto, <0 = "
|
||||
@@ -128,12 +117,28 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software "
|
||||
"written by Eric Young and UPnP software written by Thomas Bernard."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"To use bitcoind, or the -server option to bitcoin-qt, you must set an "
|
||||
"rpcpassword in the configuration file:\n"
|
||||
"%s\n"
|
||||
"It is recommended you use the following random password:\n"
|
||||
"rpcuser=bitcoinrpc\n"
|
||||
"rpcpassword=%s\n"
|
||||
"(you do not need to remember this password)\n"
|
||||
"The username and password MUST NOT be the same.\n"
|
||||
"If the file does not exist, create it with owner-readable-only file "
|
||||
"permissions.\n"
|
||||
"It is also recommended to set alertnotify so you are notified of problems;\n"
|
||||
"for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Unable to bind to %s on this computer. Bitcoin Core is probably already "
|
||||
"running."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: "
|
||||
"%s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Warning: -maxtxfee is set very high! Fees this large could be paid on a "
|
||||
"single transaction."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Warning: -paytxfee is set very high! This is the transaction fee you will "
|
||||
"pay if you send a transaction."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
@@ -163,6 +168,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "(default: 1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "<category> can be:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1 if no -proxy or -connect)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Accept public REST requests (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Acceptable ciphers (default: %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"),
|
||||
@@ -194,11 +200,11 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin Core"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error reading from database, shutting down."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occured, see debug.log for details"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occurred, see debug.log for details"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unsupported argument -tor found, use -onion."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Wallet locked, unable to create transaction!"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in BTC/kB) to add to transactions you send (default: %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Force safe mode (default: %u)"),
|
||||
@@ -214,13 +220,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Initialization sanity check failed. Bitcoin C
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -onion address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -maxtxfee=<amount>: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -minrelaytxfee=<amount>: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -mintxfee=<amount>: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable blocks in memory (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable transactions in memory (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Limit size of signature cache to <n> entries (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"),
|
||||
@@ -239,13 +244,13 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (ipv4,
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Print block on startup, if found in block index"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Print block tree on startup (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "RPC server options:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "RPC support for HTTP persistent connections (default: %d)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Randomly drop 1 of every <n> network messages"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Randomly fuzz 1 of every <n> network messages"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Rebuild block chain index from current blk000??.dat files"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Receive and display P2P network alerts (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Relay and mine data carrier transactions (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Relay non-P2SH multisig (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions"),
|
||||
@@ -277,9 +282,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "This is intended for regression testing tools and app development."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: %u)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "To use the %s option"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amount too small"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large for fee policy"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"),
|
||||
|
||||
@@ -116,6 +116,10 @@ CoinControlDialog::CoinControlDialog(QWidget *parent) :
|
||||
// (un)select all
|
||||
connect(ui->pushButtonSelectAll, SIGNAL(clicked()), this, SLOT(buttonSelectAllClicked()));
|
||||
|
||||
// change coin control first column label due Qt4 bug.
|
||||
// see https://github.com/bitcoin/bitcoin/issues/5716
|
||||
ui->treeWidget->headerItem()->setText(COLUMN_CHECKBOX, QString());
|
||||
|
||||
ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, 84);
|
||||
ui->treeWidget->setColumnWidth(COLUMN_AMOUNT, 100);
|
||||
ui->treeWidget->setColumnWidth(COLUMN_LABEL, 170);
|
||||
|
||||
@@ -17,7 +17,8 @@ void CoinControlTreeWidget::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
event->ignore();
|
||||
int COLUMN_CHECKBOX = 0;
|
||||
this->currentItem()->setCheckState(COLUMN_CHECKBOX, ((this->currentItem()->checkState(COLUMN_CHECKBOX) == Qt::Checked) ? Qt::Unchecked : Qt::Checked));
|
||||
if(this->currentItem())
|
||||
this->currentItem()->setCheckState(COLUMN_CHECKBOX, ((this->currentItem()->checkState(COLUMN_CHECKBOX) == Qt::Checked) ? Qt::Unchecked : Qt::Checked));
|
||||
}
|
||||
else if (event->key() == Qt::Key_Escape) // press esc -> close dialog
|
||||
{
|
||||
@@ -29,4 +30,4 @@ void CoinControlTreeWidget::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
this->QTreeWidget::keyPressEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Double-click to edit address or label</string>
|
||||
<string>Right-click to edit address or label</string>
|
||||
</property>
|
||||
<property name="tabKeyNavigation">
|
||||
<bool>false</bool>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user