Merge remote-tracking branch 'upstream/master'

Conflicts:
	src/qt/overviewpage.cpp
	src/qt/transactiondesc.cpp
This commit is contained in:
Roy Badami 2014-07-07 22:06:21 +01:00
commit 96df327834
331 changed files with 19565 additions and 8435 deletions

13
.gitignore vendored
View file

@ -13,12 +13,19 @@ autom4te.cache/
config.log config.log
config.status config.status
configure configure
src/bitcoin-config.h src/config/bitcoin-config.h
src/bitcoin-config.h.in src/config/bitcoin-config.h.in
src/config/stamp-h1
src/build-aux/ src/build-aux/
src/stamp-h1
share/setup.nsi share/setup.nsi
share/qt/Info.plist share/qt/Info.plist
# Libtool
libtool
src/m4/libtool.m4
src/m4/ltoptions.m4
src/m4/ltsugar.m4
src/m4/ltversion.m4
src/m4/lt~obsolete.m4
src/qt/*.moc src/qt/*.moc
src/qt/moc_*.cpp src/qt/moc_*.cpp

View file

@ -1,4 +1,4 @@
Copyright (c) 2009-2013 Bitcoin Developers Copyright (c) 2009-2014 Bitcoin Developers
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,6 +1,6 @@
ACLOCAL_AMFLAGS = -I src/m4 ACLOCAL_AMFLAGS = -I src/m4
SUBDIRS = src SUBDIRS = src
.PHONY: deploy .PHONY: deploy FORCE
GZIP_ENV="-9n" GZIP_ENV="-9n"
@ -35,6 +35,7 @@ COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \
dist-hook: dist-hook:
-$(MAKE) -C $(top_distdir)/src/leveldb clean -$(MAKE) -C $(top_distdir)/src/leveldb clean
-$(MAKE) -C $(top_distdir)/src/secp256k1 distclean
-$(GIT) archive --format=tar HEAD -- src/version.cpp | $(AMTAR) -C $(top_distdir) -xf - -$(GIT) archive --format=tar HEAD -- src/version.cpp | $(AMTAR) -C $(top_distdir) -xf -
distcheck-hook: distcheck-hook:
@ -53,8 +54,8 @@ $(BITCOIN_WIN_INSTALLER): $(BITCOIND_BIN) $(BITCOIN_QT_BIN) $(BITCOIN_CLI_BIN)
@test -f $(MAKENSIS) && $(MAKENSIS) $(top_builddir)/share/setup.nsi || \ @test -f $(MAKENSIS) && $(MAKENSIS) $(top_builddir)/share/setup.nsi || \
echo error: could not build $@ echo error: could not build $@
$(BITCOIND_BIN) $(BITCOIN_QT_BIN) $(BITCOIN_CLI_BIN): $(if $(findstring src/,$(MAKECMDGOALS)),$(MAKECMDGOALS), none): FORCE
make -C $(dir $@) $(notdir $@) $(MAKE) -C src $(patsubst src/%,%,$@)
$(OSX_APP)/Contents/PkgInfo: $(OSX_APP)/Contents/PkgInfo:
$(MKDIR_P) $(@D) $(MKDIR_P) $(@D)

View file

@ -1,7 +1,7 @@
Bitcoin Core integration/staging tree Bitcoin Core integration/staging tree
===================================== =====================================
http://www.bitcoin.org https://www.bitcoin.org
Copyright (c) 2009-2014 Bitcoin Core Developers Copyright (c) 2009-2014 Bitcoin Core Developers
@ -15,7 +15,7 @@ out collectively by the network. Bitcoin Core is the name of open source
software which enables the use of this currency. software which enables the use of this currency.
For more information, as well as an immediately useable, binary version of For more information, as well as an immediately useable, binary version of
the Bitcoin Core software, see http://www.bitcoin.org/en/download. the Bitcoin Core software, see https://www.bitcoin.org/en/download.
License License
------- -------
@ -49,8 +49,8 @@ Testing
------- -------
Testing and code review is the bottleneck for development; we get more pull Testing and code review is the bottleneck for development; we get more pull
requests than we can review and test. Please be patient and help out, and requests than we can review and test on short notice. Please be patient and help out by testing
remember this is a security-critical project where any mistake might cost people other people's pull requests, and remember this is a security-critical project where any mistake might cost people
lots of money. lots of money.
### Automated Testing ### Automated Testing
@ -76,8 +76,45 @@ Translations
Changes to translations as well as new translations can be submitted to Changes to translations as well as new translations can be submitted to
[Bitcoin Core's Transifex page](https://www.transifex.com/projects/p/bitcoin/). [Bitcoin Core's Transifex page](https://www.transifex.com/projects/p/bitcoin/).
Periodically the translations are pulled from Transifex and merged into the git repository. See the Translations are periodically pulled from Transifex and merged into the git repository. See the
[translation process](doc/translation_process.md) for details on how this works. [translation process](doc/translation_process.md) for details on how this works.
**Important**: We do not accept translation changes as github pull request because the next **Important**: We do not accept translation changes as GitHub pull requests because the next
pull from Transifex would automatically overwrite them again. pull from Transifex would automatically overwrite them again.
Translators should also subscribe to the [mailing list](https://groups.google.com/forum/#!forum/bitcoin-translators).
Development tips and tricks
---------------------------
**compiling for debugging**
Run configure with the --enable-debug option, then make. Or run configure with
CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need.
**debug.log**
If the code is behaving strangely, take a look in the debug.log file in the data directory;
error and debugging message are written there.
The -debug=... command-line option controls debugging; running with just -debug will turn
on all categories (and give you a very large debug.log file).
The Qt code routes qDebug() output to debug.log under category "qt": run with -debug=qt
to see it.
**testnet and regtest modes**
Run with the -testnet option to run with "play bitcoins" on the test network, if you
are testing multi-machine code that needs to operate across the internet.
If you are testing something that can run on one machine, run with the -regtest option.
In regression test mode blocks can be created on-demand; see qa/rpc-tests/ for tests
that run in -regest mode.
**DEBUG_LOCKORDER**
Bitcoin Core is a multithreaded application, and deadlocks or other multithreading bugs
can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure
CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of what locks
are held, and adds warning to the debug.log file if inconsistencies are detected.

View file

@ -2,4 +2,7 @@
set -e set -e
srcdir="$(dirname $0)" srcdir="$(dirname $0)"
cd "$srcdir" cd "$srcdir"
if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="`which glibtoolize 2>/dev/null`"; then
export LIBTOOLIZE="${GLIBTOOLIZE}"
fi
autoreconf --install --force autoreconf --install --force

View file

@ -9,6 +9,7 @@ define(_COPYRIGHT_YEAR, 2014)
AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[info@bitcoin.org],[bitcoin]) AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[info@bitcoin.org],[bitcoin])
AC_CONFIG_AUX_DIR([src/build-aux]) AC_CONFIG_AUX_DIR([src/build-aux])
AC_CONFIG_MACRO_DIR([src/m4]) AC_CONFIG_MACRO_DIR([src/m4])
LT_INIT([disable-shared])
AC_CANONICAL_HOST AC_CANONICAL_HOST
AH_TOP([#ifndef BITCOIN_CONFIG_H]) AH_TOP([#ifndef BITCOIN_CONFIG_H])
AH_TOP([#define BITCOIN_CONFIG_H]) AH_TOP([#define BITCOIN_CONFIG_H])
@ -111,7 +112,7 @@ AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[spec
AC_CONFIG_SRCDIR([src]) AC_CONFIG_SRCDIR([src])
AC_CONFIG_HEADERS([src/bitcoin-config.h]) AC_CONFIG_HEADERS([src/config/bitcoin-config.h])
dnl Checks for programs. dnl Checks for programs.
AC_PROG_CXX AC_PROG_CXX
@ -303,6 +304,8 @@ INCLUDES="$INCLUDES $PTHREAD_CFLAGS"
# they also need to be passed down to any subprojects. Pull the results out of # they also need to be passed down to any subprojects. Pull the results out of
# the cache and add them to CPPFLAGS. # the cache and add them to CPPFLAGS.
AC_SYS_LARGEFILE AC_SYS_LARGEFILE
# detect POSIX or GNU variant of strerror_r
AC_FUNC_STRERROR_R
if test x$ac_cv_sys_file_offset_bits != x && if test x$ac_cv_sys_file_offset_bits != x &&
test x$ac_cv_sys_file_offset_bits != xno && test x$ac_cv_sys_file_offset_bits != xno &&
@ -366,7 +369,14 @@ if test x$TARGET_OS = xdarwin; then
AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"]) AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"])
fi fi
AC_CHECK_HEADERS([stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h]) AC_CHECK_HEADERS([endian.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h])
AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])])
AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])])
AC_CHECK_DECLS([le32toh, le64toh, htole32, htole64, be32toh, be64toh, htobe32, htobe64],,,
[#if HAVE_ENDIAN_H
#include <endian.h>
#endif])
dnl Check for MSG_NOSIGNAL dnl Check for MSG_NOSIGNAL
AC_MSG_CHECKING(for MSG_NOSIGNAL) AC_MSG_CHECKING(for MSG_NOSIGNAL)
@ -664,11 +674,15 @@ AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin])
AM_CONDITIONAL([BUILD_DARWIN], [test x$BUILD_OS = xdarwin]) AM_CONDITIONAL([BUILD_DARWIN], [test x$BUILD_OS = xdarwin])
AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows]) AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows])
AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet == xyes]) AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet == xyes])
AM_CONDITIONAL([ENABLE_TESTS],[test x$use_tests == xyes])
AM_CONDITIONAL([ENABLE_QT],[test x$bitcoin_enable_qt == xyes])
AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$use_tests$bitcoin_enable_qt_test = xyesyes])
AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes]) AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes])
AM_CONDITIONAL([USE_LCOV],[test x$use_lcov == xyes]) AM_CONDITIONAL([USE_LCOV],[test x$use_lcov == xyes])
AM_CONDITIONAL([USE_COMPARISON_TOOL],[test x$use_comparison_tool != xno]) AM_CONDITIONAL([USE_COMPARISON_TOOL],[test x$use_comparison_tool != xno])
AM_CONDITIONAL([USE_COMPARISON_TOOL_REORG_TESTS],[test x$use_comparison_tool_reorg_test != xno]) AM_CONDITIONAL([USE_COMPARISON_TOOL_REORG_TESTS],[test x$use_comparison_tool_reorg_test != xno])
AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes])
AM_CONDITIONAL([USE_LIBSECP256K1],[test x$use_libsecp256k1 = xyes])
AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version]) AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version])
AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version]) AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version])
@ -693,7 +707,7 @@ AC_SUBST(LEVELDB_TARGET_FLAGS)
AC_SUBST(BUILD_TEST) AC_SUBST(BUILD_TEST)
AC_SUBST(BUILD_QT) AC_SUBST(BUILD_QT)
AC_SUBST(BUILD_TEST_QT) AC_SUBST(BUILD_TEST_QT)
AC_CONFIG_FILES([Makefile src/Makefile src/test/Makefile src/qt/Makefile src/qt/test/Makefile share/setup.nsi share/qt/Info.plist]) AC_CONFIG_FILES([Makefile src/Makefile share/setup.nsi share/qt/Info.plist])
AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh]) AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh])
AC_CONFIG_FILES([qa/pull-tester/build-tests.sh],[chmod +x qa/pull-tester/build-tests.sh]) AC_CONFIG_FILES([qa/pull-tester/build-tests.sh],[chmod +x qa/pull-tester/build-tests.sh])
AC_OUTPUT AC_OUTPUT

View file

@ -23,6 +23,18 @@ if cmd == "backupwallet":
except: except:
print "\n---An error occurred---\n" print "\n---An error occurred---\n"
elif cmd == "encryptwallet":
try:
pwd = getpass.getpass(prompt="Enter passphrase: ")
pwd2 = getpass.getpass(prompt="Repeat passphrase: ")
if pwd == pwd2:
access.encryptwallet(pwd)
print "\n---Wallet encrypted. Server stopping, restart to run with encrypted wallet---\n"
else:
print "\n---Passphrases do not match---\n"
except:
print "\n---An error occurred---\n"
elif cmd == "getaccount": elif cmd == "getaccount":
try: try:
addr = raw_input("Enter a Bitcoin address: ") addr = raw_input("Enter a Bitcoin address: ")

View file

@ -6,6 +6,7 @@ Uploaders: Micah Anderson <micah@debian.org>
Build-Depends: debhelper, Build-Depends: debhelper,
devscripts, devscripts,
automake, automake,
libtool,
bash-completion, bash-completion,
libboost-system-dev (>> 1.35) | libboost-system1.35-dev, libboost-system-dev (>> 1.35) | libboost-system1.35-dev,
libdb4.8++-dev, libdb4.8++-dev,

View file

@ -1,79 +1,110 @@
# bitcoin.conf configuration file. Lines beginning with # are comments. ##
## bitcoin.conf configuration file. Lines beginning with # are comments.
##
# Network-related settings: # Network-related settings:
# Run on the test network instead of the real bitcoin network. # Run on the test network instead of the real bitcoin network.
#testnet=1 #testnet=0
# Run a regression test network
#regtest=0
# Connect via a socks4 proxy # Connect via a socks4 proxy
#proxy=127.0.0.1:9050 #proxy=127.0.0.1:9050
##############################################################
## Quick Primer on addnode vs connect ##
## Let's say for instance you use addnode=4.2.2.4 ##
## addnode will connect you to and tell you about the ##
## nodes connected to 4.2.2.4. In addition it will tell ##
## the other nodes connected to it that you exist so ##
## they can connect to you. ##
## connect will not do the above when you 'connect' to it. ##
## It will *only* connect you to 4.2.2.4 and no one else.##
## ##
## So if you're behind a firewall, or have other problems ##
## finding nodes, add some using 'addnode'. ##
## ##
## If you want to stay private, use 'connect' to only ##
## connect to "trusted" nodes. ##
## ##
## If you run multiple nodes on a LAN, there's no need for ##
## all of them to open lots of connections. Instead ##
## 'connect' them all to one node that is port forwarded ##
## and has lots of connections. ##
## Thanks goes to [Noodle] on Freenode. ##
##############################################################
# Use as many addnode= settings as you like to connect to specific peers # Use as many addnode= settings as you like to connect to specific peers
#addnode=69.164.218.197 #addnode=69.164.218.197
#addnode=10.0.0.2:8333 #addnode=10.0.0.2:8333
# ... or use as many connect= settings as you like to connect ONLY # Alternatively use as many connect= settings as you like to connect ONLY to specific peers
# to specific peers:
#connect=69.164.218.197 #connect=69.164.218.197
#connect=10.0.0.1:8333 #connect=10.0.0.1:8333
# Listening mode, enabled by default except when 'connect' is being used
#listen=1
# Maximum number of inbound+outbound connections. # Maximum number of inbound+outbound connections.
#maxconnections= #maxconnections=
#
# JSON-RPC options (for controlling a running Bitcoin/bitcoind process) # JSON-RPC options (for controlling a running Bitcoin/bitcoind process)
#
# server=1 tells Bitcoin to accept JSON-RPC commands. # server=1 tells Bitcoin-QT and bitcoind to accept JSON-RPC commands
#server=1 #server=0
# You must set rpcuser and rpcpassword to secure the JSON-RPC api # You must set rpcuser and rpcpassword to secure the JSON-RPC api
#rpcuser=Ulysseys #rpcuser=Ulysseys
#rpcpassword=YourSuperGreatPasswordNumber_385593 #rpcpassword=YourSuperGreatPasswordNumber_DO_NOT_USE_THIS_OR_YOU_WILL_GET_ROBBED_385593
# By default, only RPC connections from localhost are allowed. Specify # How many seconds bitcoin will wait for a complete RPC HTTP request.
# as many rpcallowip= settings as you like to allow connections from # after the HTTP connection is established.
# other hosts (and you may use * as a wildcard character): #rpctimeout=30
#rpcallowip=10.1.1.34
#rpcallowip=192.168.1.* # By default, only RPC connections from localhost are allowed.
# Specify as many rpcallowip= settings as you like to allow connections from other hosts,
# either as a single IPv4/IPv6 or with a subnet specification.
# 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.
# 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
#rpcallowip=2001:db8:85a3:0:0:8a2e:370:7334/96
# Listen for RPC connections on this TCP port: # Listen for RPC connections on this TCP port:
rpcport=8332 #rpcport=8332
# You can use Bitcoin or bitcoind to send commands to Bitcoin/bitcoind # You can use Bitcoin or bitcoind to send commands to Bitcoin/bitcoind
# running on another host using this option: # running on another host using this option:
rpcconnect=127.0.0.1 #rpcconnect=127.0.0.1
# Use Secure Sockets Layer (also known as TLS or HTTPS) to communicate # Use Secure Sockets Layer (also known as TLS or HTTPS) to communicate
# with Bitcoin -server or bitcoind # with Bitcoin -server or bitcoind
#rpcssl=1 #rpcssl=1
# OpenSSL settings used when rpcssl=1 # OpenSSL settings used when rpcssl=1
rpcsslciphers=TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH #rpcsslciphers=TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH
rpcsslcertificatechainfile=server.cert #rpcsslcertificatechainfile=server.cert
rpcsslprivatekeyfile=server.pem #rpcsslprivatekeyfile=server.pem
# Miscellaneous options # Miscellaneous options
# Set gen=1 to attempt to generate bitcoins
gen=0
# Use SSE instructions to try to generate bitcoins faster.
#4way=1
# Pre-generate this many public/private key pairs, so wallet backups will be valid for # Pre-generate this many public/private key pairs, so wallet backups will be valid for
# both prior transactions and several dozen future transactions. # both prior transactions and several dozen future transactions.
keypool=100 #keypool=100
# Pay an optional transaction fee every time you send bitcoins. Transactions with fees # Pay an optional transaction fee every time you send bitcoins. Transactions with fees
# are more likely than free transactions to be included in generated blocks, so may # are more likely than free transactions to be included in generated blocks, so may
# be validated sooner. # be validated sooner.
paytxfee=0.00 #paytxfee=0.00
# Allow direct connections for the 'pay via IP address' feature.
#allowreceivebyip=1
# User interface options # User interface options

View file

@ -139,6 +139,9 @@ Execute command when the best block changes (%s in cmd is replaced by block hash
\fB\-walletnotify=\fR<cmd> \fB\-walletnotify=\fR<cmd>
Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)
.TP .TP
\fB\-respendnotify=\fR<cmd>
Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)
.TP
\fB\-alertnotify=\fR<cmd> \fB\-alertnotify=\fR<cmd>
Execute command when a relevant alert is received (%s in cmd is replaced by message) Execute command when a relevant alert is received (%s in cmd is replaced by message)
.TP .TP

View file

@ -37,9 +37,6 @@ You must set *rpcuser* to secure the JSON-RPC api.
\fBrpcpassword=\fR\fI'password'\fR \fBrpcpassword=\fR\fI'password'\fR
You must set *rpcpassword* to secure the JSON-RPC api. You must set *rpcpassword* to secure the JSON-RPC api.
.TP .TP
\fBrpctimeout=\fR\fI'30'\fR
How many seconds *bitcoin* will wait for a complete RPC HTTP request, after the HTTP connection is established.
.TP
\fBrpcallowip=\fR\fI'192.168.1.*'\fR \fBrpcallowip=\fR\fI'192.168.1.*'\fR
By default, only RPC connections from localhost are allowed. Specify as many *rpcallowip=* settings as you like to allow connections from other hosts (and you may use * as a wildcard character). By default, only RPC connections from localhost are allowed. Specify as many *rpcallowip=* settings as you like to allow connections from other hosts (and you may use * as a wildcard character).
.TP .TP

View file

@ -16,7 +16,7 @@ packages:
reference_datetime: "2013-06-01 00:00:00" reference_datetime: "2013-06-01 00:00:00"
remotes: [] remotes: []
files: files:
- "openssl-1.0.1g.tar.gz" - "openssl-1.0.1h.tar.gz"
- "miniupnpc-1.9.tar.gz" - "miniupnpc-1.9.tar.gz"
- "qrencode-3.4.3.tar.bz2" - "qrencode-3.4.3.tar.bz2"
- "protobuf-2.5.0.tar.bz2" - "protobuf-2.5.0.tar.bz2"
@ -30,15 +30,15 @@ script: |
export TZ=UTC export TZ=UTC
export LIBRARY_PATH="$STAGING/lib" export LIBRARY_PATH="$STAGING/lib"
# Integrity Check # Integrity Check
echo "53cb818c3b90e507a8348f4f5eaedb05d8bfe5358aabb508b7263cc670c3e028 openssl-1.0.1g.tar.gz" | sha256sum -c echo "9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093 openssl-1.0.1h.tar.gz" | sha256sum -c
echo "2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464 miniupnpc-1.9.tar.gz" | sha256sum -c echo "2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464 miniupnpc-1.9.tar.gz" | sha256sum -c
echo "dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98 qrencode-3.4.3.tar.bz2" | sha256sum -c echo "dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98 qrencode-3.4.3.tar.bz2" | sha256sum -c
echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c
echo "12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz" | sha256sum -c echo "12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz" | sha256sum -c
# #
tar xzf openssl-1.0.1g.tar.gz tar xzf openssl-1.0.1h.tar.gz
cd openssl-1.0.1g cd openssl-1.0.1h
# need -fPIC to avoid relocation error in 64 bit builds # need -fPIC to avoid relocation error in 64 bit builds
./config no-shared no-zlib no-dso no-krb5 --openssldir=$STAGING -fPIC ./config no-shared no-zlib no-dso no-krb5 --openssldir=$STAGING -fPIC
# need to build OpenSSL with faketime because a timestamp is embedded into cversion.o # need to build OpenSSL with faketime because a timestamp is embedded into cversion.o
@ -95,4 +95,4 @@ script: |
done done
# #
cd $STAGING cd $STAGING
find include lib bin host | sort | zip -X@ $OUTDIR/bitcoin-deps-linux${GBUILD_BITS}-gitian-r5.zip find include lib bin host | sort | zip -X@ $OUTDIR/bitcoin-deps-linux${GBUILD_BITS}-gitian-r6.zip

View file

@ -14,7 +14,7 @@ packages:
reference_datetime: "2011-01-30 00:00:00" reference_datetime: "2011-01-30 00:00:00"
remotes: [] remotes: []
files: files:
- "openssl-1.0.1g.tar.gz" - "openssl-1.0.1h.tar.gz"
- "db-4.8.30.NC.tar.gz" - "db-4.8.30.NC.tar.gz"
- "miniupnpc-1.9.tar.gz" - "miniupnpc-1.9.tar.gz"
- "zlib-1.2.8.tar.gz" - "zlib-1.2.8.tar.gz"
@ -28,7 +28,7 @@ script: |
INDIR=$HOME/build INDIR=$HOME/build
TEMPDIR=$HOME/tmp TEMPDIR=$HOME/tmp
# Input Integrity Check # Input Integrity Check
echo "53cb818c3b90e507a8348f4f5eaedb05d8bfe5358aabb508b7263cc670c3e028 openssl-1.0.1g.tar.gz" | sha256sum -c echo "9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093 openssl-1.0.1h.tar.gz" | sha256sum -c
echo "12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz" | sha256sum -c echo "12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz" | sha256sum -c
echo "2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464 miniupnpc-1.9.tar.gz" | sha256sum -c echo "2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464 miniupnpc-1.9.tar.gz" | sha256sum -c
echo "36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d zlib-1.2.8.tar.gz" | sha256sum -c echo "36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d zlib-1.2.8.tar.gz" | sha256sum -c
@ -48,8 +48,8 @@ script: |
mkdir -p $INSTALLPREFIX $BUILDDIR mkdir -p $INSTALLPREFIX $BUILDDIR
cd $BUILDDIR cd $BUILDDIR
# #
tar xzf $INDIR/openssl-1.0.1g.tar.gz tar xzf $INDIR/openssl-1.0.1h.tar.gz
cd openssl-1.0.1g cd openssl-1.0.1h
if [ "$BITS" == "32" ]; then if [ "$BITS" == "32" ]; then
OPENSSL_TGT=mingw OPENSSL_TGT=mingw
else else
@ -124,5 +124,5 @@ script: |
done done
# #
cd $INSTALLPREFIX cd $INSTALLPREFIX
find include lib | sort | zip -X@ $OUTDIR/bitcoin-deps-win$BITS-gitian-r12.zip find include lib | sort | zip -X@ $OUTDIR/bitcoin-deps-win$BITS-gitian-r13.zip
done # for BITS in done # for BITS in

View file

@ -25,8 +25,8 @@ remotes:
- "url": "https://github.com/bitcoin/bitcoin.git" - "url": "https://github.com/bitcoin/bitcoin.git"
"dir": "bitcoin" "dir": "bitcoin"
files: files:
- "bitcoin-deps-linux32-gitian-r5.zip" - "bitcoin-deps-linux32-gitian-r6.zip"
- "bitcoin-deps-linux64-gitian-r5.zip" - "bitcoin-deps-linux64-gitian-r6.zip"
- "boost-linux32-1.55.0-gitian-r1.zip" - "boost-linux32-1.55.0-gitian-r1.zip"
- "boost-linux64-1.55.0-gitian-r1.zip" - "boost-linux64-1.55.0-gitian-r1.zip"
- "qt-linux32-4.6.4-gitian-r1.tar.gz" - "qt-linux32-4.6.4-gitian-r1.tar.gz"
@ -43,7 +43,7 @@ script: |
# #
mkdir -p $STAGING mkdir -p $STAGING
cd $STAGING cd $STAGING
unzip ../build/bitcoin-deps-linux${GBUILD_BITS}-gitian-r5.zip unzip ../build/bitcoin-deps-linux${GBUILD_BITS}-gitian-r6.zip
unzip ../build/boost-linux${GBUILD_BITS}-1.55.0-gitian-r1.zip unzip ../build/boost-linux${GBUILD_BITS}-1.55.0-gitian-r1.zip
tar -zxf ../build/qt-linux${GBUILD_BITS}-4.6.4-gitian-r1.tar.gz tar -zxf ../build/qt-linux${GBUILD_BITS}-4.6.4-gitian-r1.tar.gz
cd ../build cd ../build

View file

@ -0,0 +1,61 @@
---
name: "bitcoin"
suites:
- "precise"
architectures:
- "i386"
packages:
- "git-core"
- "automake"
- "faketime"
- "bsdmainutils"
- "pkg-config"
- "p7zip-full"
- "libtool"
reference_datetime: "2013-06-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
"dir": "bitcoin"
files:
- "osx-native-depends-r3.tar.gz"
- "osx-depends-r4.tar.gz"
- "osx-depends-qt-5.2.1-r4.tar.gz"
- "MacOSX10.7.sdk.tar.gz"
script: |
HOST=x86_64-apple-darwin11
PREFIX=`pwd`/osx-cross-depends/prefix
SDK=`pwd`/osx-cross-depends/SDKs/MacOSX10.7.sdk
NATIVEPREFIX=`pwd`/osx-cross-depends/native-prefix
export TAR_OPTIONS="-m --mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
export SOURCES_PATH=`pwd`
mkdir -p osx-cross-depends/SDKs
tar -C osx-cross-depends/SDKs -xf ${SOURCES_PATH}/MacOSX10.7.sdk.tar.gz
tar -C osx-cross-depends -xf osx-native-depends-r3.tar.gz
tar -C osx-cross-depends -xf osx-depends-r4.tar.gz
tar -C osx-cross-depends -xf osx-depends-qt-5.2.1-r4.tar.gz
export PATH=`pwd`/osx-cross-depends/native-prefix/bin:$PATH
cd bitcoin
export ZERO_AR_DATE=1
export QT_RCC_TEST=1
./autogen.sh
./configure --host=${HOST} --with-boost=${PREFIX} CC=clang CXX=clang++ OBJC=clang OBJCXX=clang++ CFLAGS="-target ${HOST} -mmacosx-version-min=10.6 --sysroot ${SDK} -msse2 -Qunused-arguments" CXXFLAGS="-target ${HOST} -mmacosx-version-min=10.6 --sysroot ${SDK} -msse2 -Qunused-arguments" LDFLAGS="-B${NATIVEPREFIX}/bin -L${PREFIX}/lib -L${SDK}/usr/lib/i686-apple-darwin10/4.2.1" CPPFLAGS="-I${NATIVEPREFIX}/lib/clang/3.2/include -I${PREFIX}/include" SSL_LIBS="-lz -lssl -lcrypto" --disable-tests -with-gui=qt5 PKG_CONFIG_LIBDIR="${PREFIX}/lib/pkgconfig" --disable-dependency-tracking --disable-maintainer-mode
make dist
mkdir -p distsrc
cd distsrc
tar --strip-components=1 -xf ../bitcoin-*.tar*
./configure --host=${HOST} --with-boost=${PREFIX} CC=clang CXX=clang++ OBJC=clang OBJCXX=clang++ CFLAGS="-target ${HOST} -mmacosx-version-min=10.6 --sysroot ${SDK} -msse2 -Qunused-arguments" CXXFLAGS="-target ${HOST} -mmacosx-version-min=10.6 --sysroot ${SDK} -msse2 -Qunused-arguments" LDFLAGS="-B${NATIVEPREFIX}/bin -L${PREFIX}/lib -L${SDK}/usr/lib/i686-apple-darwin10/4.2.1" CPPFLAGS="-I${NATIVEPREFIX}/lib/clang/3.2/include -I${PREFIX}/include" SSL_LIBS="-lz -lssl -lcrypto" --disable-tests -with-gui=qt5 PKG_CONFIG_LIBDIR="${PREFIX}/lib/pkgconfig" --disable-dependency-tracking --disable-maintainer-mode
make $MAKEOPTS
export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1
export FAKETIME=$REFERENCE_DATETIME
export TZ=UTC
make deploy
dmg dmg Bitcoin-Qt.dmg $OUTDIR/Bitcoin-Qt.dmg

View file

@ -0,0 +1,159 @@
---
name: "osx-depends"
suites:
- "precise"
architectures:
- "i386"
packages:
- "git-core"
- "automake"
- "p7zip-full"
reference_datetime: "2013-06-01 00:00:00"
remotes: []
files:
- "boost_1_55_0.tar.bz2"
- "db-4.8.30.NC.tar.gz"
- "miniupnpc-1.9.tar.gz"
- "openssl-1.0.1h.tar.gz"
- "protobuf-2.5.0.tar.bz2"
- "qrencode-3.4.3.tar.bz2"
- "MacOSX10.7.sdk.tar.gz"
- "osx-native-depends-r3.tar.gz"
script: |
echo "fff00023dd79486d444c8e29922f4072e1d451fc5a4d2b6075852ead7f2b7b52 boost_1_55_0.tar.bz2" | sha256sum -c
echo "12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz" | sha256sum -c
echo "2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464 miniupnpc-1.9.tar.gz" | sha256sum -c
echo "9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093 openssl-1.0.1h.tar.gz" | sha256sum -c
echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c
echo "dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98 qrencode-3.4.3.tar.bz2" | sha256sum -c
REVISION=r4
export SOURCES_PATH=`pwd`
export TAR_OPTIONS="-m --mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
export PATH=$HOME:$PATH
export SOURCES_PATH=`pwd`
export ZERO_AR_DATE=1
mkdir -p osx-cross-depends/build
cd osx-cross-depends
PREFIX=`pwd`/prefix
NATIVEPREFIX=`pwd`/native-prefix
BUILD_BASE=`pwd`/build
SDK=`pwd`/SDKs/MacOSX10.7.sdk
HOST=x86_64-apple-darwin11
MIN_VERSION=10.6
INT_CFLAGS="-target ${HOST} -mmacosx-version-min=${MIN_VERSION} --sysroot ${SDK} -msse2 -Qunused-arguments"
INT_CXXFLAGS="${INT_CFLAGS}"
INT_LDFLAGS="-L${PREFIX}/lib -L${SDK}/usr/lib/i686-apple-darwin10/4.2.1"
INT_LDFLAGS_CLANG="-B${NATIVEPREFIX}/bin"
INT_CPPFLAGS="-I${PREFIX}/include"
INT_CC=clang
INT_CXX=clang++
INT_OBJC=clang
INT_OBJCXX=clang++
INT_AR=${HOST}-ar
INT_RANLIB=${HOST}-ranlib
INT_LIBTOOL=${HOST}-libtool
INT_INSTALL_NAME_TOOL=${HOST}-install_name_tool
export PATH=${NATIVEPREFIX}/bin:${PATH}
mkdir -p ${NATIVEPREFIX}/bin
mkdir -p ${NATIVEPREFIX}/lib
mkdir -p ${PREFIX}/bin
mkdir -p ${PREFIX}/lib
mkdir -p ${BUILD_BASE}
mkdir -p SDKs
tar -C SDKs -xf ${SOURCES_PATH}/MacOSX10.7.sdk.tar.gz
tar xf /home/ubuntu/build/osx-native-depends-r3.tar.gz
# bdb
SOURCE_FILE=${SOURCES_PATH}/db-4.8.30.NC.tar.gz
BUILD_DIR=${BUILD_BASE}/db-4.8.30.NC
tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
sed -i 's/__atomic_compare_exchange/__atomic_compare_exchange_db/g' ${BUILD_DIR}/dbinc/atomic.h
pushd ${BUILD_DIR}
cd build_unix;
../dist/configure --host=${HOST} --prefix="${PREFIX}" --disable-shared --enable-cxx CC="${INT_CC}" CXX="${INT_CXX}" AR="${INT_AR}" RANLIB="${INT_RANLIB}" OBJC="${INT_OBJC}" OBJCXX="${INT_OBJCXX}" CFLAGS="${INT_CFLAGS}" CXXFLAGS="${INT_CXXFLAGS}" LDFLAGS="${INT_CLANG_LDFLAGS} ${INT_LDFLAGS}" CPPFLAGS="${INT_CPPFLAGS}"
make $MAKEOPTS libdb.a libdb_cxx.a
make install_lib install_include
popd
# openssl
SOURCE_FILE=${SOURCES_PATH}/openssl-1.0.1h.tar.gz
BUILD_DIR=${BUILD_BASE}/openssl-1.0.1h
tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
pushd ${BUILD_DIR}
sed -ie "s|cc:|${INT_CC}:|" ${BUILD_DIR}/Configure
sed -ie "s|\(-arch [_a-zA-Z0-9]*\)|\1 --sysroot ${SDK} -target ${HOST} -msse2|" ${BUILD_DIR}/Configure
AR="${INT_AR}" RANLIB="${INT_RANLIB}" ./Configure --prefix=${PREFIX} --openssldir=${PREFIX}/etc/openssl zlib shared no-krb5 darwin64-x86_64-cc ${INT_LDFLAGS} ${INT_CLANG_LDFLAGS} ${INT_CPPFLAGS}
sed -i "s|engines apps test|engines|" ${BUILD_DIR}/Makefile
sed -i "/define DATE/d" ${BUILD_DIR}/crypto/Makefile
make -j1 build_libs libcrypto.pc libssl.pc openssl.pc
make -j1 install_sw
popd
#libminiupnpc
SOURCE_FILE=${SOURCES_PATH}/miniupnpc-1.9.tar.gz
BUILD_DIR=${BUILD_BASE}/miniupnpc-1.9
tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
pushd ${BUILD_DIR}
CFLAGS="${INT_CFLAGS} ${INT_CPPFLAGS}" make $MAKEOPTS OS=Darwin CC="${INT_CC}" AR="${INT_AR}" libminiupnpc.a
install -d ${PREFIX}/include/miniupnpc
install *.h ${PREFIX}/include/miniupnpc
install libminiupnpc.a ${PREFIX}/lib
popd
# qrencode
SOURCE_FILE=${SOURCES_PATH}/qrencode-3.4.3.tar.bz2
BUILD_DIR=${BUILD_BASE}/qrencode-3.4.3
tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
pushd ${BUILD_DIR}
# m4 folder is not included in the stable release, which can confuse aclocal
# if its timestamp ends up being earlier than configure.ac when extracted
touch aclocal.m4
./configure --host=${HOST} --prefix="${PREFIX}" --disable-shared CC="${INT_CC}" CXX="${INT_CXX}" AR="${INT_AR}" RANLIB="${INT_RANLIB}" OBJC="${INT_OBJC}" OBJCXX="${INT_OBJCXX}" CFLAGS="${INT_CFLAGS}" CXXFLAGS="${INT_CXXFLAGS}" LDFLAGS="${INT_CLANG_LDFLAGS} ${INT_LDFLAGS}" CPPFLAGS="${INT_CPPFLAGS}" --disable-shared -without-tools --disable-sdltest --disable-dependency-tracking
make $MAKEOPTS
make install
popd
# libprotobuf
SOURCE_FILE=${SOURCES_PATH}/protobuf-2.5.0.tar.bz2
BUILD_DIR=${BUILD_BASE}/protobuf-2.5.0
tar -C ${BUILD_BASE} -xjf ${SOURCE_FILE}
pushd ${BUILD_DIR}
./configure --host=${HOST} --prefix="${PREFIX}" --disable-shared --enable-cxx CC="${INT_CC}" CXX="${INT_CXX}" AR="${INT_AR}" RANLIB="${INT_RANLIB}" OBJC="${INT_OBJC}" OBJCXX="${INT_OBJCXX}" CFLAGS="${INT_CFLAGS}" CXXFLAGS="${INT_CXXFLAGS}" LDFLAGS="${INT_CLANG_LDFLAGS} ${INT_LDFLAGS}" CPPFLAGS="${INT_CPPFLAGS}" --enable-shared=no --disable-dependency-tracking --with-protoc=${NATIVEPREFIX}/bin/protoc
cd src
make $MAKEOPTS libprotobuf.la
make install-libLTLIBRARIES install-nobase_includeHEADERS
cd ..
make install-pkgconfigDATA
popd
# boost
SOURCE_FILE=${SOURCES_PATH}/boost_1_55_0.tar.bz2
BUILD_DIR=${BUILD_BASE}/boost_1_55_0
tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
pushd ${BUILD_DIR}
./bootstrap.sh --with-libraries=chrono,filesystem,program_options,system,thread,test
echo "using darwin : : ${INT_CXX} : <cxxflags>\"${INT_CFLAGS} ${INT_CPPFLAGS}\" <linkflags>\"${INT_LDFLAGS} ${INT_CLANG_LDFLAGS}\" <archiver>\"${INT_LIBTOOL}\" <striper>\"${INT_STRIP}\" : ;" > "user-config.jam"
./b2 -d2 --layout=tagged --build-type=complete --prefix="${PREFIX}" --toolset=darwin-4.2.1 --user-config=user-config.jam variant=release threading=multi link=static install
popd
export GZIP="-9n"
find prefix | sort | tar --no-recursion -czf osx-depends-${REVISION}.tar.gz -T -
mv osx-depends-${REVISION}.tar.gz $OUTDIR

View file

@ -0,0 +1,178 @@
---
name: "osx-native"
suites:
- "precise"
architectures:
- "i386"
packages:
- "git-core"
- "automake"
- "faketime"
- "libssl-dev"
- "libbz2-dev"
- "libz-dev"
- "cmake"
- "libcap-dev"
- "p7zip-full"
- "uuid-dev"
reference_datetime: "2013-06-01 00:00:00"
remotes: []
files:
- "10cc648683617cca8bcbeae507888099b41b530c.tar.gz"
- "cctools-809.tar.gz"
- "dyld-195.5.tar.gz"
- "ld64-127.2.tar.gz"
- "protobuf-2.5.0.tar.bz2"
- "MacOSX10.7.sdk.tar.gz"
- "cdrkit-1.1.11.tar.gz"
- "libdmg-hfsplus-v0.1.tar.gz"
- "clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz"
- "cdrkit-deterministic.patch"
script: |
echo "18406961fd4a1ec5c7ea35c91d6a80a2f8bb797a2bd243a610bd75e13eff9aca 10cc648683617cca8bcbeae507888099b41b530c.tar.gz" | sha256sum -c
echo "03ba62749b843b131c7304a044a98c6ffacd65b1399b921d69add0375f79d8ad cctools-809.tar.gz" | sha256sum -c
echo "2cf0484c87cf79b606b351a7055a247dae84093ae92c747a74e0cde2c8c8f83c dyld-195.5.tar.gz" | sha256sum -c
echo "97b75547b2bd761306ab3e15ae297f01e7ab9760b922bc657f4ef72e4e052142 ld64-127.2.tar.gz" | sha256sum -c
echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c
echo "d1c030756ecc182defee9fe885638c1785d35a2c2a297b4604c0e0dcc78e47da cdrkit-1.1.11.tar.gz" | sha256sum -c
echo "6569a02eb31c2827080d7d59001869ea14484c281efab0ae7f2b86af5c3120b3 libdmg-hfsplus-v0.1.tar.gz" | sha256sum -c
echo "b9d57a88f9514fa1f327a1a703756d0c1c960f4c58494a5bd80313245d13ffff clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz" | sha256sum -c
echo "cc12bdbd7a09f71cb2a6a3e6ec3e0abe885ca7111c2b47857f5095e5980caf4f cdrkit-deterministic.patch" | sha256sum -c
REVISION=r3
export REFERENCE_DATETIME
export TAR_OPTIONS="-m --mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
export FAKETIME=$REFERENCE_DATETIME
export TZ=UTC
REAL_AR=`which ar`
REAL_RANLIB=`which ranlib`
REAL_DATE=`which date`
echo '#!/bin/bash' > $HOME/ar
echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> $HOME/ar
echo "$REAL_AR \"\$@\"" >> $HOME/ar
echo '#!/bin/bash' > $HOME/ranlib
echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> $HOME/ranlib
echo "$REAL_RANLIB \"\$@\"" >> $HOME/ranlib
echo '#!/bin/bash' > $HOME/date
echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> $HOME/date
echo "$REAL_DATE \"\$@\"" >> $HOME/date
chmod +x $HOME/ar $HOME/ranlib $HOME/date
export PATH=$HOME:$PATH
export SOURCES_PATH=`pwd`
mkdir -p osx-cross-depends/build
cd osx-cross-depends
NATIVEPREFIX=`pwd`/native-prefix
BUILD_BASE=`pwd`/build
SDK=`pwd`/SDKs/MacOSX10.7.sdk
HOST=x86_64-apple-darwin11
MIN_VERSION=10.6
CFLAGS=""
CXXFLAGS="${CFLAGS}"
LDFLAGS="-L${NATIVEPREFIX}/lib"
export PATH=${NATIVEPREFIX}/bin:${PATH}
mkdir -p ${NATIVEPREFIX}/bin
mkdir -p ${NATIVEPREFIX}/lib
mkdir -p SDKs
tar -C SDKs -xf ${SOURCES_PATH}/MacOSX10.7.sdk.tar.gz
# Clang
SOURCE_FILE=${SOURCES_PATH}/clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz
BUILD_DIR=${BUILD_BASE}/clang+llvm-3.2-x86-linux-ubuntu-12.04
mkdir -p ${NATIVEPREFIX}/lib/clang/3.2/include
tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
cp ${BUILD_DIR}/bin/clang ${NATIVEPREFIX}/bin/
cp ${BUILD_DIR}/bin/clang++ ${NATIVEPREFIX}/bin/
cp ${BUILD_DIR}/lib/libLTO.so ${NATIVEPREFIX}/lib/
cp ${BUILD_DIR}/lib/clang/3.2/include/* ${NATIVEPREFIX}/lib/clang/3.2/include
# cctools
SOURCE_FILE=${SOURCES_PATH}/10cc648683617cca8bcbeae507888099b41b530c.tar.gz
BUILD_DIR=${BUILD_BASE}/toolchain4-10cc648683617cca8bcbeae507888099b41b530c
tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
mkdir -p ${BUILD_DIR}/sdks
pushd ${BUILD_DIR}/sdks;
ln -sf ${SDK} MacOSX10.7.sdk
ln -sf ${SOURCES_PATH}/cctools-809.tar.gz ${BUILD_DIR}/cctools2odcctools/cctools-809.tar.gz
ln -sf ${SOURCES_PATH}/ld64-127.2.tar.gz ${BUILD_DIR}/cctools2odcctools/ld64-127.2.tar.gz
ln -sf ${SOURCES_PATH}/dyld-195.5.tar.gz ${BUILD_DIR}/cctools2odcctools/dyld-195.5.tar.gz
tar -C ${BUILD_DIR} -xf ${SOURCES_PATH}/clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz
# Hack in the use of our llvm headers rather than grabbing the old llvm-gcc.
sed -i "s|GCC_DIR|LLVM_CLANG_DIR|g" ${BUILD_DIR}/cctools2odcctools/extract.sh
sed -i "s|llvmgcc42-2336.1|clang+llvm-3.2-x86-linux-ubuntu-12.04|g" ${BUILD_DIR}/cctools2odcctools/extract.sh
sed -i "s|\${LLVM_CLANG_DIR}/llvmCore/include/llvm-c|\${LLVM_CLANG_DIR}/include/llvm-c \${LLVM_CLANG_DIR}/include/llvm |" ${BUILD_DIR}/cctools2odcctools/extract.sh
sed -i "s|fAC_INIT|AC_INIT|" ${BUILD_DIR}/cctools2odcctools/files/configure.ac
sed -i 's/\# Dynamically linked LTO/\t ;\&\n\t linux*)\n# Dynamically linked LTO/' ${BUILD_DIR}/cctools2odcctools/files/configure.ac
cd ${BUILD_DIR}/cctools2odcctools
./extract.sh --osxver 10.7
cd odcctools-809
./configure --prefix=${NATIVEPREFIX} --target=${HOST} CFLAGS="${CFLAGS} -I${NATIVEPREFIX}/include -D__DARWIN_UNIX03 -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS" LDFLAGS="${LDFLAGS} -Wl,-rpath=\\\$\$ORIGIN/../lib" --with-sysroot=${SDK}
# The 'PC' define in sparc/reg.h conflicts but doesn't get used anyway. Just rename it.
sed -i "s|define\tPC|define\tPC_|" ${BUILD_DIR}/cctools2odcctools/odcctools-809/include/architecture/sparc/reg.h
make $MAKEOPTS
make install
popd
# protoc
SOURCE_FILE=${SOURCES_PATH}/protobuf-2.5.0.tar.bz2
BUILD_DIR=${BUILD_BASE}/protobuf-2.5.0
tar -C ${BUILD_BASE} -xjf ${SOURCE_FILE}
pushd ${BUILD_DIR};
./configure --enable-shared=no --disable-dependency-tracking --prefix=${NATIVEPREFIX}
make $MAKEOPTS
cp ${BUILD_DIR}/src/protoc ${NATIVEPREFIX}/bin/
popd
# cdrkit
SOURCE_FILE=${SOURCES_PATH}/cdrkit-1.1.11.tar.gz
BUILD_DIR=${BUILD_BASE}/cdrkit-1.1.11
tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
pushd ${BUILD_DIR}
patch -p1 < ${SOURCES_PATH}/cdrkit-deterministic.patch
cmake -DCMAKE_INSTALL_PREFIX=${NATIVEPREFIX}
make $MAKEOPTS genisoimage
make -C genisoimage install
popd
# libdmg-hfsplus
SOURCE_FILE=${SOURCES_PATH}/libdmg-hfsplus-v0.1.tar.gz
BUILD_DIR=${BUILD_BASE}/libdmg-hfsplus-libdmg-hfsplus-v0.1
tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
mkdir -p ${BUILD_DIR}/build
pushd ${BUILD_DIR}/build
cmake -DCMAKE_INSTALL_PREFIX:PATH=${NATIVEPREFIX}/bin ..
make $MAKEOPTS
make install
popd
rm -rf native-prefix/docs
export GZIP="-9n"
find native-prefix | sort | tar --no-recursion -czf osx-native-depends-$REVISION.tar.gz -T -
mv osx-native-depends-$REVISION.tar.gz $OUTDIR

View file

@ -0,0 +1,186 @@
---
name: "osx-qt"
suites:
- "precise"
architectures:
- "i386"
packages:
- "git-core"
- "automake"
- "p7zip-full"
reference_datetime: "2013-06-01 00:00:00"
remotes: []
files:
- "qt-everywhere-opensource-src-5.2.1.tar.gz"
- "osx-native-depends-r3.tar.gz"
- "osx-depends-r4.tar.gz"
- "MacOSX10.7.sdk.tar.gz"
script: |
echo "84e924181d4ad6db00239d87250cc89868484a14841f77fb85ab1f1dbdcd7da1 qt-everywhere-opensource-src-5.2.1.tar.gz" | sha256sum -c
REVISION=r4
export SOURCES_PATH=`pwd`
export TAR_OPTIONS="-m --mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
export ZERO_AR_DATE=1
export TZ=UTC
REAL_DATE=`which date`
echo '#!/bin/bash' > $HOME/date
echo "$REAL_DATE -d \"${REFERENCE_DATETIME}\" \"\$@\"" >> $HOME/date
chmod +x $HOME/date
export PATH=$HOME:$PATH
mkdir -p osx-cross-depends/build
cd osx-cross-depends
PREFIX=`pwd`/prefix
NATIVEPREFIX=`pwd`/native-prefix
BUILD_BASE=`pwd`/build
SDK=`pwd`/SDKs/MacOSX10.7.sdk
HOST=x86_64-apple-darwin11
MIN_VERSION=10.6
INT_CFLAGS="-target ${HOST} -mmacosx-version-min=${MIN_VERSION} --sysroot ${SDK} -msse2 -Qunused-arguments"
INT_CXXFLAGS="${INT_CFLAGS}"
INT_LDFLAGS="-L${PREFIX}/lib -L${SDK}/usr/lib/i686-apple-darwin10/4.2.1"
INT_LDFLAGS_CLANG="-B${NATIVEPREFIX}/bin"
INT_CPPFLAGS="-I${PREFIX}/include"
INT_CC=clang
INT_CXX=clang++
INT_OBJC=clang
INT_OBJCXX=clang++
INT_AR=${HOST}-ar
INT_RANLIB=${HOST}-ranlib
INT_LIBTOOL=${HOST}-libtool
INT_INSTALL_NAME_TOOL=${HOST}-install_name_tool
export PATH=${NATIVEPREFIX}/bin:${PATH}
mkdir -p ${NATIVEPREFIX}/bin
mkdir -p ${NATIVEPREFIX}/lib
mkdir -p ${PREFIX}/bin
mkdir -p ${PREFIX}/lib
mkdir -p ${BUILD_BASE}
mkdir -p SDKs
tar -C SDKs -xf ${SOURCES_PATH}/MacOSX10.7.sdk.tar.gz
tar xf /home/ubuntu/build/osx-native-depends-r3.tar.gz
export PATH=`pwd`/native-prefix/bin:$PATH
tar xf /home/ubuntu/build/osx-depends-r4.tar.gz
SOURCE_FILE=${SOURCES_PATH}/qt-everywhere-opensource-src-5.2.1.tar.gz
BUILD_DIR=${BUILD_BASE}/qt-everywhere-opensource-src-5.2.1
tar -C ${BUILD_BASE} -xf ${SOURCE_FILE}
# Install our mkspec. All files are pulled from the macx-clang spec, except for
# our custom qmake.conf
SPECFILE=${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux/qmake.conf
mkdir -p ${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux
cp -f ${BUILD_DIR}/qtbase/mkspecs/macx-clang/Info.plist.lib ${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux/
cp -f ${BUILD_DIR}/qtbase/mkspecs/macx-clang/Info.plist.app ${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux/
cp -f ${BUILD_DIR}/qtbase/mkspecs/macx-clang/qplatformdefs.h ${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux/
cat > ${SPECFILE} <<ENDCONF
MAKEFILE_GENERATOR = UNIX
CONFIG += app_bundle incremental global_init_link_order lib_version_first plugin_no_soname absolute_library_soname
QMAKE_INCREMENTAL_STYLE = sublib
include(../common/macx.conf)
include(../common/gcc-base-mac.conf)
include(../common/clang.conf)
include(../common/clang-mac.conf)
QMAKE_XCODE_VERSION=4.3
QMAKE_XCODE_DEVELOPER_PATH=/Developer
QMAKE_MACOSX_DEPLOYMENT_TARGET = ${MIN_VERSION}
QMAKE_MAC_SDK=macosx
QMAKE_MAC_SDK.macosx.path = ${SDK}
QMAKE_MAC_SDK.macosx.platform_name = macosx
QMAKE_MAC_SDK_PATH=${SDK}
QMAKE_CFLAGS += -target ${HOST}
QMAKE_OBJECTIVE_CFLAGS += -target ${HOST}
QMAKE_CXXFLAGS += -target ${HOST}
QMAKE_LFLAGS += -target ${HOST}
QMAKE_AR = ${HOST}-ar cq
QMAKE_RANLIB=${HOST}-ranlib
QMAKE_LIBTOOL=${HOST}-libtool
QMAKE_INSTALL_NAME_TOOL=${HOST}-install_name_tool
load(qt_config)
ENDCONF
pushd ${BUILD_DIR}
./configure -release -opensource -openssl-linked \
-no-audio-backend -no-javascript-jit -no-sql-sqlite -no-sql-tds \
-no-cups -no-iconv -no-dbus -no-gif -no-audio-backend -no-freetype \
-no-javascript-jit -no-sql-sqlite -no-nis -no-cups -no-iconv -no-pch \
-no-dbus -no-gif -no-sm -nomake examples -no-feature-style-plastique \
-no-xcb -no-qml-debug -no-pch -no-nis \
-no-feature-style-cde -no-feature-style-s60 -no-feature-style-motif \
-no-feature-style-windowsmobile -no-feature-style-windowsce \
-no-feature-style-cleanlooks \
-no-sql-db2 -no-sql-ibase -no-sql-oci -no-sql-tds -no-sql-mysql \
-no-sql-odbc -no-sql-psql -no-sql-sqlite -no-sql-sqlite2 \
-skip qtsvg -skip qtwebkit -skip qtwebkit-examples -skip qtserialport \
-skip qtdeclarative -skip qtmultimedia -skip qtimageformats \
-skip qtlocation -skip qtsensors -skip qtquick1 -skip qtxmlpatterns \
-skip qtquickcontrols -skip qtactiveqt -skip qtconnectivity \
-skip qtwinextras -skip qtscript \
-prefix ${PREFIX} -bindir ${NATIVEPREFIX}/bin \
-confirm-license -xplatform macx-clang-linux -v ${INT_LDFLAGS}
# RCC's output is sorted using each file entry's hash as the key. Unfortunately,
# the hash function uses a random seed for each run so the results aren't
# deterministic. This leads to static resources being defined in a random order,
# which in-turn means that object files are not predictable.
# Fortunately, this upsets Qt's unit tests as well, so they've added the
# QT_RCC_TEST environment variable to set a pre-defined seed. Here, do the same
# thing for the same reason.
QT_RCC_TEST=1 make $MAKEOPTS module-qtbase-make_first
make $MAKEOPTS module-qttranslations-make_first
make $MAKEOPTS module-qttools-make_first
make $MAKEOPTS -C qtbase
make -C qtbase install
make -C qttranslations install
make -C qttools/src/linguist install
popd
# This file should not be installed to the destination. It's native and
# non-deterministic. Remove it.
# See: https://bugreports.qt-project.org/browse/QTBUG-31393
rm -f ${PREFIX}/lib/libQt5Bootstrap.a
rm -f ${PREFIX}/lib/Qt*.framework/Qt*.prl
pushd ${PREFIX}/include
ln -sf ../lib/QtNetwork.framework/Headers/ QtNetwork
ln -sf ../lib/QtWidgets.framework/Headers/ QtWidgets
ln -sf ../lib/QtGui.framework/Headers/ QtGui
ln -sf ../lib/QtCore.framework/Headers/ QtCore
ln -sf ../lib/QtTest.framework/Headers/ QtTest
popd
rm -f ${PREFIX}/lib/*.la
find ${PREFIX}/lib -name "*.prl" -delete
export GZIP="-9n"
find native-prefix prefix | sort | tar --no-recursion -czf osx-depends-qt-5.2.1-${REVISION}.tar.gz -T -
mv osx-depends-qt-5.2.1-${REVISION}.tar.gz $OUTDIR

View file

@ -26,8 +26,8 @@ files:
- "qt-win64-5.2.0-gitian-r3.zip" - "qt-win64-5.2.0-gitian-r3.zip"
- "boost-win32-1.55.0-gitian-r6.zip" - "boost-win32-1.55.0-gitian-r6.zip"
- "boost-win64-1.55.0-gitian-r6.zip" - "boost-win64-1.55.0-gitian-r6.zip"
- "bitcoin-deps-win32-gitian-r12.zip" - "bitcoin-deps-win32-gitian-r13.zip"
- "bitcoin-deps-win64-gitian-r12.zip" - "bitcoin-deps-win64-gitian-r13.zip"
- "protobuf-win32-2.5.0-gitian-r4.zip" - "protobuf-win32-2.5.0-gitian-r4.zip"
- "protobuf-win64-2.5.0-gitian-r4.zip" - "protobuf-win64-2.5.0-gitian-r4.zip"
script: | script: |
@ -61,7 +61,7 @@ script: |
cd $STAGING cd $STAGING
unzip $INDIR/qt-win${BITS}-5.2.0-gitian-r3.zip unzip $INDIR/qt-win${BITS}-5.2.0-gitian-r3.zip
unzip $INDIR/boost-win${BITS}-1.55.0-gitian-r6.zip unzip $INDIR/boost-win${BITS}-1.55.0-gitian-r6.zip
unzip $INDIR/bitcoin-deps-win${BITS}-gitian-r12.zip unzip $INDIR/bitcoin-deps-win${BITS}-gitian-r13.zip
unzip $INDIR/protobuf-win${BITS}-2.5.0-gitian-r4.zip unzip $INDIR/protobuf-win${BITS}-2.5.0-gitian-r4.zip
if [ "$NEEDDIST" == "1" ]; then if [ "$NEEDDIST" == "1" ]; then
# Make source code archive which is architecture independent so it only needs to be done once # Make source code archive which is architecture independent so it only needs to be done once

View file

@ -40,6 +40,7 @@ script: |
tar xzf qt-everywhere-opensource-src-4.6.4.tar.gz tar xzf qt-everywhere-opensource-src-4.6.4.tar.gz
cd qt-everywhere-opensource-src-4.6.4 cd qt-everywhere-opensource-src-4.6.4
QTBUILDDIR=$(pwd) QTBUILDDIR=$(pwd)
sed 's/TODAY=`date +%Y-%m-%d`/TODAY=2011-01-30/' -i configure
# Need to build 4.6-versioned host utilities as well (lrelease/qrc/lupdate/...) # Need to build 4.6-versioned host utilities as well (lrelease/qrc/lupdate/...)
./configure -prefix $INSTALLPREFIX -confirm-license -release -opensource -no-qt3support -no-multimedia -no-audio-backend -no-phonon -no-phonon-backend -no-declarative -no-script -no-scripttools -no-javascript-jit -no-webkit -no-svg -no-xmlpatterns -no-sql-sqlite -no-nis -no-cups -no-iconv -no-dbus -no-gif -no-libtiff -no-opengl -nomake examples -nomake demos -nomake docs ./configure -prefix $INSTALLPREFIX -confirm-license -release -opensource -no-qt3support -no-multimedia -no-audio-backend -no-phonon -no-phonon-backend -no-declarative -no-script -no-scripttools -no-javascript-jit -no-webkit -no-svg -no-xmlpatterns -no-sql-sqlite -no-nis -no-cups -no-iconv -no-dbus -no-gif -no-libtiff -no-opengl -nomake examples -nomake demos -nomake docs

View file

@ -15,8 +15,8 @@ reference_datetime: "2011-01-30 00:00:00"
remotes: [] remotes: []
files: files:
- "qt-everywhere-opensource-src-5.2.0.tar.gz" - "qt-everywhere-opensource-src-5.2.0.tar.gz"
- "bitcoin-deps-win32-gitian-r12.zip" - "bitcoin-deps-win32-gitian-r13.zip"
- "bitcoin-deps-win64-gitian-r12.zip" - "bitcoin-deps-win64-gitian-r13.zip"
script: | script: |
# Defines # Defines
export TZ=UTC export TZ=UTC
@ -48,7 +48,7 @@ script: |
# #
# Need mingw-compiled openssl from bitcoin-deps: # Need mingw-compiled openssl from bitcoin-deps:
cd $DEPSDIR cd $DEPSDIR
unzip $INDIR/bitcoin-deps-win${BITS}-gitian-r12.zip unzip $INDIR/bitcoin-deps-win${BITS}-gitian-r13.zip
# #
cd $BUILDDIR cd $BUILDDIR
# #

View file

@ -0,0 +1,52 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.12 (GNU/Linux)
mQINBFOHTh4BEADdKsRvmNhX+B+bcPsgMkp8ztwJA5g/rmrOlHQpKOOf4P2tAr6w
FmXCChWF9Iq3pDFQ0t0iq5rgisFPyrGVT/VToMmH+/PSLTyIdAlgkRYDMAPsMAFV
MaADH4yiAgJ3cdXtysjaNQV5O25ypqq6/obUjZJD5Enn6b/UgHe2+7LTmTNsskOx
5s/WPPht79EY1kM4JQfmDx68CsmqeSAlT6yeO3RQcLn/l46cfXiwzMO4h1hsZS1r
pgciRp0EHK9uAjF2rjqt8v4SDxwyTnwfpBBulzvH9mBf+HRXWzoTMR4sC/oOZext
hKAH/ex47BxN3HU3ftNhCK2c1xcU1UOGSjbf0RdbwuSCxxa7mktEDumvOxAk9EBB
+PDPv7jO1FBK3rsJdscYQIL0AiRyO49VfNLARa34OqUi8pOAxKBQ9plO02W1gp7a
DVBPI05TZ46Y8dTR2Bc1raAgOyxnXM7jfiQG2gSULiKAJAI4HwOiodaiiHAxDaIo
a3mtsmfN25TZUQuA0I0BvHbJvLRlVnyZm3XVOcwReKJpZJV4qRhd3XNrERZdz6ZK
cAZnyC/X+Uzo4HfnVSsJk1GpIa4seYyrVCFfHMiAA6SkgAUFbV26KCOv4rNR2GlV
l2fVhu1RKOEUJ8nRcEqf93SehRVYdI67LepIPgmIwi0KG4HhoTbIHDAKWQARAQAB
tCtDb3J5IEZpZWxkcyA8Y2ZpZWxkc0BiaXRjb2luZm91bmRhdGlvbi5vcmc+iQI4
BBMBAgAiBQJTh04eAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRAcJJH/
6w73cBTiEADIGZSueBFmaOTJCgasKGguHns/n8P94EQBZr07rrgN99Rzp85WvDUN
Qa72wj3GNcAffN7aZlIWv4g+fjyr9AzHekjI/7iwwSYIfjfTR/xRUW7czRfKAOrK
iwpEzgv440i7PBvkS/AhNdUNkm+cJvaQUej/F2/O52qDLEpHuzvjAUUWlSeF9/oO
AjM9dfC24L5k5cVwQvH9noxk3EyuE7BuiGE5a+kKiORrtxiHeUG6GYQxuqrPucLU
fI67ETyXa0YSpYm5/O65BKMTMpmkMvv1JC2kqqsYTrO5p158CrKzq2xvpuG4ABsb
9KwICUGW31Ndr6TXwQJFa1b7VK4G1g6M1DFkVTOLJnEyOwgYxsXrV5QFpzpAOAji
6KcxNGeow1avAFYbqjjLgu9UNuq6b8du13hjkQxVs2NAP1Kd/u2ADwxQHMhZGVEC
9LIcLVSP9ShY6fR8m6fwSlJfpiV81uLNVD8KIyvp+pYTQ/FnxoPhPIwalYquBZKi
0u38igW75IzZ0fYvJgTumE/8ofSVkutVtrQb21eJclVrJGMNweTlJcJhAWdKkjDC
e6mSj8GItKV1ef+eusXSzs/wPyTaqgkELvvAOZdwUq3kobQErE5HOuPEOvcwuY96
DcxLexirCGW5wCUq7Db0c0dUjQwzzb5OTW2jdnPVR0qxi29TnOJ2aLkCDQRTh04e
ARAAuJKpI6NTCQrjEqe9AYywN8676+fPS5bqXkyb/iub6MXeQdwpH0K42lXAaYMq
ow/0aLlvGWCHuJJGozoOWpTzQ+VPbhpdARoLCop5fYTpy8Q17ubLeeODDtr6jtDN
lmg+9PBIErIVUnUS2wNZuJRVsfwlLaU3T2v8kQnQ6AEbl/QwyWW9nB8rAWBu6Hvs
VdtcBmtHSr9xAGBGfW6rSVhTitikR4lWJPdNJxI3pLaswpLIUIQ1rssKO4glljcp
C6nhMvRkDLvDFvDP9QnmwY/A4ch5S6ANPrhOjQuu9njjQ+/ImrJTjAXqHwg5KdTc
NKxufgvi9elOQ422o0No3yKdRoRA4kdcUmqA9gNZDyX0ZTd17aNqc42Zt3aYLJ11
bLZZp0qnfhkmhbsBZZtaLNkuF+RGPWysxY7KPMm+nHn6f3Wpr18E+T02wi02r4nS
HOQI+gppDqy3Vq3ZZNoUZynctiLZVHkqi+WYXqfD2tEn8UJKpht7jrZlNgkHFgT7
T0/U4+JmaQ/HltE+IexAIH0GP0Jt6hmRoZimdoy8Q8NY5t/fn9CQNJm5InrHvooN
aFmZMvzGTGiTqBqnA/7k9FCUEG98LK11MsIssY8YE/F6HD69R3ISyRvhUbpFvhD8
c6zOkEKngTWvyRevrDrDz2yoZ1+T1X350+92rbEc/8WyutcAEQEAAYkCHwQYAQIA
CQUCU4dOHgIbDAAKCRAcJJH/6w73cAakEACv4EUEjtFjqnGB0Lru5FKs1obWcf37
c4a5yYvOw58dkEZ9hsq34qWGLT128n6R24KEG+3O4CbplAD5Kt2eAPracbPHMAn8
TGmC+KjiGlBR5xCY9dD0fn5EbRWOa+Fdcj1DpneaqMl9vLnBbqGp7pa/MwSOc+FB
0Ms2rcGJJMNHgITfP22eCf6pvf/xq7kKbUJ3Kjqdc2hWlRMjC/OOeITdrgycfDk/
AOzLNqk5q7bYOxna6rWDLGSkCATyQKaBTVK7wRd1VrIhI4vfFqy+BWYXyXJ0pxjS
eaCDwbWHX/KW+0qLsmHxFMAyHJPjs8LEwK/DRbmWhe1HzPcBKmpyjqlkuxPjAdSl
hP4+IBvVNLf2Kh3uFHehk9A6oCYZGe3lLfQnOxIantXF7IROTmiZZsb+08w6cIXE
+r6kWG6vP2aCVtzYNfY+2p5xfg3yMxcxENJki1WSCOq6WVf9IWFzSJu+0+eazD3L
3QpZoSX5VvT6x05C0Ay1ert0Q5MyF84Eh8mDqL4PhpWtQhZMp8SG4jqFVgrhM4sl
vWGYXGns4tbnNPiiksjBD8TTvG3+mt48sNJIpHThjdWJSZjllYG7jV8oi7HrX8M2
LOwWWLYxHkqi9wpmrWHSmniex6ABozcqrb+EgSMnHuSd7glmOJxHToJIudJbKG5D
MrD0ofsytfy1LQ==
=DE4h
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -37,3 +37,6 @@ signers:
E944AE667CF960B1004BC32FCA662BE18B877A60: E944AE667CF960B1004BC32FCA662BE18B877A60:
name: "Andreas Schildbach" name: "Andreas Schildbach"
key: aschildbach key: aschildbach
C060A6635913D98A3587D7DB1C2491FFEB0EF770:
name: "Cory Fields"
key: "cfields"

View file

@ -37,3 +37,6 @@ signers:
E944AE667CF960B1004BC32FCA662BE18B877A60: E944AE667CF960B1004BC32FCA662BE18B877A60:
name: "Andreas Schildbach" name: "Andreas Schildbach"
key: aschildbach key: aschildbach
C060A6635913D98A3587D7DB1C2491FFEB0EF770:
name: "Cory Fields"
key: "cfields"

View file

@ -1,9 +1,5 @@
### MacDeploy ### ### MacDeploy ###
You will need the appscript package for the fancy disk image creation to work:
sudo easy_install appscript
For Snow Leopard (which uses [Python 2.6](http://www.python.org/download/releases/2.6/)), you will need the param_parser package: For Snow Leopard (which uses [Python 2.6](http://www.python.org/download/releases/2.6/)), you will need the param_parser package:
sudo easy_install argparse sudo easy_install argparse

View file

@ -19,7 +19,6 @@
import subprocess, sys, re, os, shutil, stat, os.path import subprocess, sys, re, os, shutil, stat, os.path
from string import Template from string import Template
from time import sleep
from argparse import ArgumentParser from argparse import ArgumentParser
# This is ported from the original macdeployqt with modifications # This is ported from the original macdeployqt with modifications
@ -488,16 +487,6 @@ if len(config.fancy) == 1:
sys.stderr.write("Error: Could not import plistlib which is required for fancy disk images.\n") sys.stderr.write("Error: Could not import plistlib which is required for fancy disk images.\n")
sys.exit(1) sys.exit(1)
if verbose >= 3:
print "Fancy: Importing appscript..."
try:
import appscript
except ImportError:
if verbose >= 1:
sys.stderr.write("Error: Could not import appscript which is required for fancy disk images.\n")
sys.stderr.write("Please install it e.g. with \"sudo easy_install appscript\".\n")
sys.exit(1)
p = config.fancy[0] p = config.fancy[0]
if verbose >= 3: if verbose >= 3:
print "Fancy: Loading \"%s\"..." % p print "Fancy: Loading \"%s\"..." % p
@ -580,7 +569,7 @@ try:
except RuntimeError as e: except RuntimeError as e:
if verbose >= 1: if verbose >= 1:
sys.stderr.write("Error: %s\n" % str(e)) sys.stderr.write("Error: %s\n" % str(e))
sys.exit(ret) sys.exit(1)
# ------------------------------------------------ # ------------------------------------------------
@ -593,7 +582,7 @@ if config.plugins:
except RuntimeError as e: except RuntimeError as e:
if verbose >= 1: if verbose >= 1:
sys.stderr.write("Error: %s\n" % str(e)) sys.stderr.write("Error: %s\n" % str(e))
sys.exit(ret) sys.exit(1)
# ------------------------------------------------ # ------------------------------------------------

View file

@ -1,5 +1,5 @@
### Verify SF Binaries ### ### Verify SF Binaries ###
This script attempts to download the signature file `SHA256SUMS.asc` from SourceForge. This script attempts to download the signature file `SHA256SUMS.asc` from https://bitcoin.org.
It first checks if the signature passes, and then downloads the files specified in the file, and checks if the hashes of these files match those that are specified in the signature file. It first checks if the signature passes, and then downloads the files specified in the file, and checks if the hashes of these files match those that are specified in the signature file.

View file

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
### This script attempts to download the signature file SHA256SUMS.asc from SourceForge ### This script attempts to download the signature file SHA256SUMS.asc from bitcoin.org
### It first checks if the signature passes, and then downloads the files specified in ### It first checks if the signature passes, and then downloads the files specified in
### the file, and checks if the hashes of these files match those that are specified ### the file, and checks if the hashes of these files match those that are specified
### in the signature file. ### in the signature file.
@ -18,11 +18,11 @@ WORKINGDIR="/tmp/bitcoin"
TMPFILE="hashes.tmp" TMPFILE="hashes.tmp"
#this URL is used if a version number is not specified as an argument to the script #this URL is used if a version number is not specified as an argument to the script
SIGNATUREFILE="http://downloads.sourceforge.net/project/bitcoin/Bitcoin/bitcoin-0.9.0rc1/SHA256SUMS.asc" SIGNATUREFILE="https://bitcoin.org/bin/0.9.2.1/SHA256SUMS.asc"
SIGNATUREFILENAME="SHA256SUMS.asc" SIGNATUREFILENAME="SHA256SUMS.asc"
RCSUBDIR="test/" RCSUBDIR="test/"
BASEDIR="http://downloads.sourceforge.net/project/bitcoin/Bitcoin/" BASEDIR="https://bitcoin.org/bin/"
VERSIONPREFIX="bitcoin-" VERSIONPREFIX="bitcoin-"
RCVERSIONSTRING="rc" RCVERSIONSTRING="rc"
@ -62,7 +62,7 @@ WGETOUT=$(wget -N "$BASEDIR$SIGNATUREFILENAME" 2>&1)
#and then see if wget completed successfully #and then see if wget completed successfully
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "Error: couldn't fetch signature file. Have you specified the version number in the following format?" echo "Error: couldn't fetch signature file. Have you specified the version number in the following format?"
echo "[bitcoin-]<version>-[rc[0-9]] (example: bitcoin-0.7.1-rc1)" echo "[bitcoin-]<version>-[rc[0-9]] (example: bitcoin-0.9.2-rc1)"
echo "wget output:" echo "wget output:"
echo "$WGETOUT"|sed 's/^/\t/g' echo "$WGETOUT"|sed 's/^/\t/g'
exit 2 exit 2

75
doc/README_osx.txt Normal file
View file

@ -0,0 +1,75 @@
Deterministic OSX Dmg Notes.
Working OSX DMG's 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
available in the Precise repositories at the time this work was started. In the
future, it can be switched to use system packages instead.
Apple's version of binutils (called cctools) contains lots of functionality
missing in the FSF's binutils. In addition to extra linker options for
frameworks and sysroots, several other tools are needed as well such as
install_name_tool, lipo, and nmedit. These do not build under linux, so they
have been patched to do so. The work here was used as a starting point:
https://github.com/mingwandroid/toolchain4
In order to build a working toolchain, the following source packages are needed
from Apple: cctools, dyld, and ld64.
Beware. This part is ugly. Very very very ugly. In the future, this should be
broken out into a new repository and cleaned up. Additionally, the binaries
only work when built as x86 and not x86_64. This is an especially nasty
limitation because it must be linked with the toolchain's libLTO.so, meaning
that the entire toolchain must be x86. Gitian x86_64 should not be used until
this has been fixed, because it would mean that several native dependencies
(openssl, libuuid, etc) would need to be built as x86 first.
These tools inject timestamps by default, which produce non-deterministic
binaries. The ZERO_AR_DATE environment variable is used to disable that.
This version of cctools has been patched to use the current version of clang's
headers and and its libLTO.so rather than those from llvmgcc, as it was
originally done in toolchain4.
To complicate things further, all builds must target an Apple SDK. These SDKs
are free to download, but not redistributable.
To obtain it, register for a developer account, then download xcode4630916281a.dmg:
https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6.3/xcode4630916281a.dmg
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:
$ 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
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.
genisoimage is used to create the initial DMG. It is not deterministic as-is,
so it has been patched. A system genisoimage will work fine, but it will not
be deterministic because the file-order will change between invocations.
The patch can be seen here:
https://raw.githubusercontent.com/theuni/osx-cross-depends/master/patches/cdrtools/genisoimage.diff
No effort was made to fix this cleanly, so it likely leaks memory badly. But
it's only used for a single invocation, so that's no real concern.
genisoimage cannot compress DMGs, so afterwards, the 'dmg' tool from the
libdmg-hfsplus project is used to compress it. There are several bugs in this
tool and its maintainer has seemingly abandoned the project. It has been forked
and is available (with fixes) here: https://github.com/theuni/libdmg-hfsplus .
The 'dmg' tool has the ability to create DMG's from scratch as well, but this
functionality is broken. Only the compression feature is currently used.
Ideally, the creation could be fixed and genisoimage would no longer be necessary.
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
grab the .DS_Store file for later use. That is the approach taken here.

View file

@ -22,7 +22,7 @@ Xcode 4.3 or later, you'll need to install its command line tools. This can
be done in `Xcode > Preferences > Downloads > Components` and generally must be done in `Xcode > Preferences > Downloads > Components` and generally must
be re-done or updated every time Xcode is updated. be re-done or updated every time Xcode is updated.
There's an assumption that you already have `git` installed, as well. If There's also an assumption that you already have `git` installed. If
not, it's the path of least resistance to install [Github for Mac](https://mac.github.com/) not, it's the path of least resistance to install [Github for Mac](https://mac.github.com/)
(OS X 10.7+) or (OS X 10.7+) or
[Git for OS X](https://code.google.com/p/git-osx-installer/). It is also [Git for OS X](https://code.google.com/p/git-osx-installer/). It is also
@ -30,11 +30,8 @@ available via Homebrew or MacPorts.
You will also need to install [Homebrew](http://brew.sh) You will also need to install [Homebrew](http://brew.sh)
or [MacPorts](https://www.macports.org/) in order to install library or [MacPorts](https://www.macports.org/) in order to install library
dependencies. It's largely a religious decision which to choose, but, as of dependencies. It's largely a religious decision which to choose, however, Homebrew
December 2012, MacPorts is a little easier because you can just install the is now used for building release versions.
dependencies immediately - no other work required. If you're unsure, read
the instructions through first in order to assess what you want to do.
Homebrew is a little more popular among those newer to OS X.
The installation of the actual dependencies is covered in the Instructions The installation of the actual dependencies is covered in the Instructions
sections below. sections below.
@ -44,9 +41,7 @@ Instructions: MacPorts
### Install dependencies ### Install dependencies
Installing the dependencies using MacPorts is very straightforward. sudo port install boost db48@+no_java openssl miniupnpc autoconf pkgconfig automake libtool
sudo port install boost db48@+no_java openssl miniupnpc autoconf pkgconfig automake
Optional: install Qt4 Optional: install Qt4
@ -74,13 +69,13 @@ Instructions: Homebrew
#### Install dependencies using Homebrew #### Install dependencies using Homebrew
brew install autoconf automake berkeley-db4 boost miniupnpc openssl pkg-config protobuf qt brew install autoconf automake libtool berkeley-db4 boost miniupnpc openssl pkg-config protobuf qt
Note: After you have installed the dependencies, you should check that the Homebrew installed version of OpenSSL is the one available for compilation. You can check this by typing Note: After you have installed the dependencies, you should check that the Homebrew installed version of OpenSSL is the one available for compilation. You can check this by typing
openssl version openssl version
into Terminal. You should see OpenSSL 1.0.1f 6 Jan 2014. into Terminal. You should see OpenSSL 1.0.1h 5 Jun 2014.
If not, you can ensure that the Homebrew OpenSSL is correctly linked by running If not, you can ensure that the Homebrew OpenSSL is correctly linked by running
@ -103,7 +98,7 @@ PATH.
./configure ./configure
make make
3. It is a good idea to build and run the unit tests, too: 3. It is also a good idea to build and run the unit tests:
make check make check
@ -131,7 +126,7 @@ For MacPorts, that means editing your macports.conf and setting
... and then uninstalling and re-installing, or simply rebuilding, all ports. ... and then uninstalling and re-installing, or simply rebuilding, all ports.
As of December 2012, the `boost` port does not obey `macosx_deployment_target`. As of December 2012, the `boost` port does not obey `macosx_deployment_target`.
Download `http://gavinandresen-bitcoin.s3.amazonaws.com/boost_macports_fix.zip` Download `https://gavinandresen-bitcoin.s3.amazonaws.com/boost_macports_fix.zip`
for a fix. for a fix.
Once dependencies are compiled, see release-process.md for how the Bitcoin-Qt.app Once dependencies are compiled, see release-process.md for how the Bitcoin-Qt.app
@ -149,13 +144,14 @@ commands:
echo -e "rpcuser=bitcoinrpc\nrpcpassword=$(xxd -l 16 -p /dev/urandom)" > "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf" echo -e "rpcuser=bitcoinrpc\nrpcpassword=$(xxd -l 16 -p /dev/urandom)" > "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf"
chmod 600 "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf" chmod 600 "/Users/${USER}/Library/Application Support/Bitcoin/bitcoin.conf"
When next you run it, it will start downloading the blockchain, but it won't The next time you run it, it will start downloading the blockchain, but it won't
output anything while it's doing this. This process may take several hours; output anything while it's doing this. This process may take several hours;
you can monitor its process by looking at the debug.log file, like this: you can monitor its process by looking at the debug.log file, like this:
tail -f $HOME/Library/Application\ Support/Bitcoin/debug.log tail -f $HOME/Library/Application\ Support/Bitcoin/debug.log
Other commands: Other commands:
-------
./bitcoind -daemon # to start the bitcoin daemon. ./bitcoind -daemon # to start the bitcoin daemon.
./bitcoin-cli --help # for a list of command-line options. ./bitcoin-cli --help # for a list of command-line options.

View file

@ -2,6 +2,16 @@ UNIX BUILD NOTES
==================== ====================
Some notes on how to build Bitcoin in Unix. Some notes on how to build Bitcoin in Unix.
Note
---------------------
Always use absolute paths to configure and compile bitcoin and the dependencies,
for example, when specifying the the path of the dependency:
../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX
Here BDB_PREFIX must absolute path - it is defined using $(pwd) which ensures
the usage of the absolute path.
To Build To Build
--------------------- ---------------------
@ -51,9 +61,7 @@ Dependency Build Instructions: Ubuntu & Debian
---------------------------------------------- ----------------------------------------------
Build requirements: Build requirements:
sudo apt-get install build-essential sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev
sudo apt-get install libtool autotools-dev autoconf
sudo apt-get install libssl-dev
for Ubuntu 12.04 and later: for Ubuntu 12.04 and later:
@ -83,10 +91,9 @@ To enable the change run
sudo apt-get update sudo apt-get update
for other Ubuntu & Debian: for other Debian & Ubuntu (with ppa):
sudo apt-get install libdb4.8-dev sudo apt-get install libdb4.8-dev libdb4.8++-dev
sudo apt-get install libdb4.8++-dev
Optional: Optional:

View file

@ -4,7 +4,7 @@ Coding
Please be consistent with the existing coding style. Please be consistent with the existing coding style.
Block style: Block style:
```c++
bool Function(char* psz, int n) bool Function(char* psz, int n)
{ {
// Comment summarising what this section of code does // Comment summarising what this section of code does
@ -19,12 +19,33 @@ Block style:
// Success return is usually at the end // Success return is usually at the end
return true; return true;
} }
```
- ANSI/Allman block style - ANSI/Allman block style
- 4 space indenting, no tabs - 4 space indenting, no tabs
- No extra spaces inside parenthesis; please don't do ( this ) - No extra spaces inside parenthesis; please don't do ( this )
- No space after function names, one space after if, for and while - No space after function names, one space after if, for and while
- Includes need to be ordered alphabetically, separate own and foreign headers with a new-line (example key.cpp):
```c++
#include "key.h"
#include "crypto/sha2.h"
#include "util.h"
#include <openssl/foo.h>
```
- Class or struct keywords in header files need to be ordered alphabetically:
```c++
class CAlpha;
class CBeta;
```
- When using namespace keyword use the following form:
```c++
namespace Foo {
...
} // Foo
```
Variable names begin with the type in lowercase, like nSomeVariable. Variable names begin with the type in lowercase, like nSomeVariable.
Please don't put the first word of the variable name in lowercase like Please don't put the first word of the variable name in lowercase like
someVariable. someVariable.

View file

@ -4,8 +4,8 @@ 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 Gitian is the deterministic build process that is used to build the Bitcoin
Core executables [1]. It provides a way to be reasonably sure that the Core executables. It provides a way to be reasonably sure that the
executables are really built from source on github. It also makes sure that executables are really built from source on GitHub. It also makes sure that
the same, tested dependencies are used and statically built into the executable. the same, tested dependencies are used and statically built into the executable.
Multiple developers build the source code by following a specific descriptor Multiple developers build the source code by following a specific descriptor
@ -17,9 +17,6 @@ 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 guide. It is preferred to follow these steps yourself instead of using someone else's
VM image to avoid 'contaminating' the build. VM image to avoid 'contaminating' the build.
[1] For all platforms except for MacOSX, at this point. Work for deterministic
builds for Mac is under way here: https://github.com/theuni/osx-cross-depends .
Table of Contents Table of Contents
------------------ ------------------
@ -34,19 +31,22 @@ Table of Contents
- [Signing externally](#signing-externally) - [Signing externally](#signing-externally)
- [Uploading signatures](#uploading-signatures) - [Uploading signatures](#uploading-signatures)
Preparing the Gitian builder host
---------------------------------
The first step is to prepare the host environment that will be used to perform the Gitian builds.
This guide explains how to set up the environment, and how to start the builds.
Debian Linux was chosen as the host distribution because it has a lightweight install (in contrast to Ubuntu) and is readily available.
Any kind of virtualization can be used, for example:
- [VirtualBox](https://www.virtualbox.org/), covered by this guide
- [KVM](http://www.linux-kvm.org/page/Main_Page)
- [LXC](https://linuxcontainers.org/), see also [Gitian host docker container](https://github.com/gdm85/tenku/tree/master/docker/gitian-bitcoin-host/README.md).
You can also install on actual hardware instead of using virtualization.
Create a new VirtualBox VM Create a new VirtualBox VM
--------------------------- ---------------------------
The first step is to create a new Virtual Machine, which will be explained in
this section. This VM will be used to do the Gitian builds. In this guide it
will be explained how to set up the environment, and how to get the builds
started.
Debian Linux was chosen as the host distribution because it has a lightweight install (in
contrast to Ubuntu) and is readily available. We here show the steps for
VirtualBox [1], but any kind of virtualization can be used. You can also install
on actual hardware instead of using a VM, in this case you can skip this section.
In the VirtualBox GUI click "Create" and choose the following parameters in the wizard: In the VirtualBox GUI click "Create" and choose the following parameters in the wizard:
![](gitian-building/create_vm_page1.png) ![](gitian-building/create_vm_page1.png)
@ -74,11 +74,11 @@ In the VirtualBox GUI click "Create" and choose the following parameters in the
- 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 - Push the `Create` button
Get the [Debian 7.4 net installer](http://cdimage.debian.org/debian-cd/7.4.0/amd64/iso-cd/debian-7.4.0-amd64-netinst.iso). 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/)).
This DVD image can be validated using a SHA256 hashing tool, for example on This DVD image can be validated using a SHA256 hashing tool, for example on
Unixy OSes by entering the following in a terminal: Unixy OSes by entering the following in a terminal:
echo "b712a141bc60269db217d3b3e456179bd6b181645f90e4aac9c42ed63de492e9 /home/orion/Downloads/debian-7.4.0-amd64-netinst.iso" | sha256sum -c echo "b712a141bc60269db217d3b3e456179bd6b181645f90e4aac9c42ed63de492e9 debian-7.4.0-amd64-netinst.iso" | sha256sum -c
# (must return OK) # (must return OK)
After creating the VM, we need to configure it. After creating the VM, we need to configure it.
@ -106,8 +106,6 @@ Then start the VM. On the first launch you will be asked for a CD or DVD image.
![](gitian-building/select_startup_disk.png) ![](gitian-building/select_startup_disk.png)
[1] https://www.virtualbox.org/
Installing Debian Installing Debian
------------------ ------------------
@ -133,7 +131,7 @@ and proceed, just press `Enter`. To select a different button, press `Tab`.
![](gitian-building/debian_install_5_configure_the_network.png) ![](gitian-building/debian_install_5_configure_the_network.png)
- Choose a root password and enter it twice (and remember it for later) - Choose a root password and enter it twice (remember it for later)
![](gitian-building/debian_install_6a_set_up_root_password.png) ![](gitian-building/debian_install_6a_set_up_root_password.png)
@ -142,7 +140,7 @@ and proceed, just press `Enter`. To select a different button, press `Tab`.
![](gitian-building/debian_install_7_set_up_user_fullname.png) ![](gitian-building/debian_install_7_set_up_user_fullname.png)
![](gitian-building/debian_install_8_set_up_username.png) ![](gitian-building/debian_install_8_set_up_username.png)
- Choose a user password and enter it twice (and remember it for later) - Choose a user password and enter it twice (remember it for later)
![](gitian-building/debian_install_9_user_password.png) ![](gitian-building/debian_install_9_user_password.png)
@ -235,7 +233,7 @@ adduser debian sudo
When you get a colorful screen with a question about the 'LXC directory', just When you get a colorful screen with a question about the 'LXC directory', just
go with the default (`/var/lib/lxc`). go with the default (`/var/lib/lxc`).
Then set up LXC and the rest with the following is a complex jumble of settings and workarounds: Then set up LXC and the rest with the following, which is a complex jumble of settings and workarounds:
```bash ```bash
# the version of lxc-start in Debian 7.4 needs to run as root, so make sure # the version of lxc-start in Debian 7.4 needs to run as root, so make sure
@ -279,11 +277,14 @@ cd ..
**Note**: When sudo asks for a password, enter the password for the user *debian* not for *root*. **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, Clone the git repositories for bitcoin and gitian and then checkout the bitcoin version that you want to build.
```bash ```bash
git clone https://github.com/devrandom/gitian-builder.git git clone https://github.com/devrandom/gitian-builder.git
git clone https://github.com/bitcoin/bitcoin git clone https://github.com/bitcoin/bitcoin
cd bitcoin
git checkout v${VERSION}
cd ..
``` ```
Setting up gitian images Setting up gitian images
@ -315,10 +316,10 @@ you will find a list of `wget` commands that can be executed to get the dependen
I needed to add `--no-check-certificate` to the OpenSSL wget line to make it work. 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 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 integrity of the input archives and refuse to work security issue as the gitian descriptors check the integrity of the input archives and refuse to work
if any one is corrupted. if any one is corrupted.
After downloading the archives, execute the `gbuild` commends to build the dependencies. 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 This can take a long time, but only has to be done when the dependencies change, for example
to upgrade the used version. to upgrade the used version.
@ -335,7 +336,7 @@ tail -f var/build.log
Building Bitcoin Building Bitcoin
---------------- ----------------
To build Bitcoin (for Linux and/or Windows) just follow the steps under 'perform 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. gitian builds' in [doc/release-process.md](release-process.md) in the bitcoin repository.
Output from `gbuild` will look something like Output from `gbuild` will look something like
@ -368,7 +369,7 @@ can be inspected in `var/install.log` and `var/build.log`.
Building an alternative repository Building an alternative repository
----------------------------------- -----------------------------------
If you want to do a test build of a pull on github it can be useful to point 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. and inputs.
@ -378,13 +379,14 @@ URL=https://github.com/laanwj/bitcoin.git
COMMIT=2014_03_windows_unicode_path COMMIT=2014_03_windows_unicode_path
./bin/gbuild --commit bitcoin=${COMMIT} --url bitcoin=${URL} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml ./bin/gbuild --commit bitcoin=${COMMIT} --url bitcoin=${URL} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
./bin/gbuild --commit bitcoin=${COMMIT} --url bitcoin=${URL} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml ./bin/gbuild --commit bitcoin=${COMMIT} --url bitcoin=${URL} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml
./bin/gbuild --commit bitcoin=${COMMIT} --url bitcoin=${URL} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
``` ```
Signing externally Signing externally
------------------- -------------------
If you want to do the PGP signing on another device that's possible too; just define `SIGNER` as mentioned If you want to do the PGP signing on another device that's also possible; just define `SIGNER` as mentioned
and follow the steps in the build process as normally. and follow the steps in the build process as normal.
gpg: skipped "laanwj": secret key not available gpg: skipped "laanwj": secret key not available
@ -392,8 +394,9 @@ When you execute `gsign` you will get an error from GPG, which can be ignored. C
in `gitian.sigs` to your signing machine and do in `gitian.sigs` to your signing machine and do
```bash ```bash
gpg --detach-sign ${VERSION}/${SIGNER}/bitcoin-build.assert gpg --detach-sign ${VERSION}-linux/${SIGNER}/bitcoin-build.assert
gpg --detach-sign ${VERSION}-win/${SIGNER}/bitcoin-build.assert gpg --detach-sign ${VERSION}-win/${SIGNER}/bitcoin-build.assert
gpg --detach-sign ${VERSION}-osx/${SIGNER}/bitcoin-build.assert
``` ```
This will create the `.sig` files that can be committed together with the `.assert` files to assert your This will create the `.sig` files that can be committed together with the `.assert` files to assert your
@ -402,9 +405,6 @@ gitian build.
Uploading signatures Uploading signatures
--------------------- ---------------------
After building and signing you can push your signatures (both the `.assert` and After building and signing you can push your signatures (both the `.assert` and `.assert.sig` files) to the
`.assert.sig` files) to the [bitcoin/gitian.sigs](https://github.com/bitcoin/gitian.sigs/) repository, or if that's not possible create a pull
[bitcoin/gitian.sigs](https://github.com/bitcoin/gitian.sigs/) repository, or request. You can also mail the files to me (laanwj@gmail.com) and I'll commit them.
if not possible create a pull request. You can also mail the files to me
(laanwj@gmail.com) and I'll commit them.

View file

@ -1,2 +1,87 @@
(note: this is a temporary file, to be added-to by anybody, and moved to (note: this is a temporary file, to be added-to by anybody, and moved to
release-notes at release time) release-notes at release time)
Transaction fee changes
=======================
This release automatically estimates how high a transaction fee (or how
high a priority) transactions require to be confirmed quickly. The default
settings will create transactions that confirm quickly; see the new
'txconfirmtarget' setting to control the tradeoff between fees and
confirmation times.
Prior releases used hard-coded fees (and priorities), and would
sometimes create transactions that took a very long time to confirm.
New Command Line Options
========================
-txconfirmtarget=n : create transactions that have enough fees (or priority)
so they are likely to confirm within n blocks (default: 1). This setting
is over-ridden by the -paytxfee option.
New RPC methods
===============
Fee/Priority estimation
-----------------------
estimatefee nblocks : Returns approximate fee-per-1,000-bytes needed for
a transaction to be confirmed within nblocks. Returns -1 if not enough
transactions have been observed to compute a good estimate.
estimatepriority nblocks : Returns approximate priority needed for
a zero-fee transaction to confirm within nblocks. Returns -1 if not
enough free transactions have been observed to compute a good
estimate.
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.
Double-Spend Relay and Alerts
=============================
VERY IMPORTANT: *It has never been safe, and remains unsafe, to rely*
*on unconfirmed transactions.*
Relay
-----
When an attempt is seen on the network to spend the same unspent funds
more than once, it is no longer ignored. Instead, it is broadcast, to
serve as an alert. This broadcast is subject to protections against
denial-of-service attacks.
Wallets and other bitcoin services should alert their users to
double-spends that affect them. Merchants and other users may have
enough time to withhold goods or services when payment becomes
uncertain, until confirmation.
Bitcoin Core Wallet Alerts
--------------------------
The Bitcoin Core wallet now makes respend attempts visible in several
ways.
If you are online, and a respend affecting one of your wallet
transactions is seen, a notification is immediately issued to the
command registered with `-respendnotify=<cmd>`. Additionally, if
using the GUI:
- An alert box is immediately displayed.
- The affected wallet transaction is highlighted in red until it is
confirmed (and it may never be confirmed).
A `respendsobserved` array is added to `gettransaction`, `listtransactions`,
and `listsinceblock` RPC results.
Warning
-------
*If you rely on an unconfirmed transaction, these change do VERY*
*LITTLE to protect you from a malicious double-spend, because:*
- You may learn about the respend too late to avoid doing whatever
you were being paid for
- Using other relay rules, a double-spender can craft his crime to
resist broadcast
- Miners can choose which conflicting spend to confirm, and some
miners may not confirm the first acceptable spend they see

View file

@ -0,0 +1,53 @@
Bitcoin Core version 0.9.1 is now available from:
https://bitcoin.org/bin/0.9.1/
This is a security update. It is recommended to upgrade to this release
as soon as possible.
It is especially important to upgrade if you currently have version
0.9.0 installed and are using the graphical interface OR you are using
bitcoind from any pre-0.9.1 version, and have enabled SSL for RPC and
have configured allowip to allow rpc connections from potentially
hostile hosts.
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).
If you are upgrading from version 0.7.2 or earlier, the first time you run
0.9.1 your blockchain files will be re-indexed, which will take anywhere from
30 minutes to several hours, depending on the speed of your machine.
0.9.1 Release notes
=======================
No code changes were made between 0.9.0 and 0.9.1. Only the dependencies were changed.
- Upgrade OpenSSL to 1.0.1g. This release fixes the following vulnerabilities which can
affect the Bitcoin Core software:
- CVE-2014-0160 ("heartbleed")
A missing bounds check in the handling of the TLS heartbeat extension can
be used to reveal up to 64k of memory to a connected client or server.
- CVE-2014-0076
The Montgomery ladder implementation in OpenSSL does not ensure that
certain swap operations have a constant-time behavior, which makes it
easier for local users to obtain ECDSA nonces via a FLUSH+RELOAD cache
side-channel attack.
- Add statically built executables to Linux build
Credits
--------
Credits go to the OpenSSL team for fixing the vulnerabilities quickly.

View file

@ -0,0 +1,207 @@
Bitcoin Core version 0.9.2.1 is now available from:
https://bitcoin.org/bin/0.9.2.1/
This is a new minor version release, bringing mostly bug fixes and some minor
improvements. OpenSSL has been updated because of a security issue (CVE-2014-0224).
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).
If you are upgrading from version 0.7.2 or earlier, the first time you run
0.9.2.1 your blockchain files will be re-indexed, which will take anywhere from
30 minutes to several hours, depending on the speed of your machine.
Downgrading warnings
--------------------
The 'chainstate' for this release is not always compatible with previous
releases, so if you run 0.9.x and then decide to switch back to a
0.8.x release you might get a blockchain validation error when starting the
old release (due to 'pruned outputs' being omitted from the index of
unspent transaction outputs).
Running the old release with the -reindex option will rebuild the chainstate
data structures and correct the problem.
Also, the first time you run a 0.8.x release on a 0.9 wallet it will rescan
the blockchain for missing spent coins, which will take a long time (tens
of minutes on a typical machine).
Important changes
==================
Gitian OSX build
-----------------
The deterministic build system that was already used for Windows and Linux
builds is now used for OSX as well. Although the resulting executables have
been tested quite a bit, there could be possible regressions. Be sure to report
these on the Github bug tracker mentioned above.
Compatibility of Linux build
-----------------------------
For Linux we now build against Qt 4.6, and filter the symbols for libstdc++ and glibc.
This brings back compatibility with
- Debian 6+ / Tails
- Ubuntu 10.04
- CentOS 6.5
0.9.2 - 0.9.2.1 Release notes
=======================
The OpenSSL dependency in the gitian builds has been upgraded to 1.0.1h because of CVE-2014-0224.
RPC:
- Add `getwalletinfo`, `getblockchaininfo` and `getnetworkinfo` calls (will replace hodge-podge `getinfo` at some point)
- Add a `relayfee` field to `getnetworkinfo`
- Fix RPC related shutdown hangs and leaks
- Always show syncnode in `getpeerinfo`
- `sendrawtransaction`: report the reject code and reason, and make it possible to re-send transactions that are already in the mempool
- `getmininginfo` show right genproclimit
Command-line options:
- Fix `-printblocktree` output
- Show error message if ReadConfigFile fails
Block-chain handling and storage:
- Fix for GetBlockValue() after block 13,440,000 (BIP42)
- Upgrade leveldb to 1.17
Protocol and network code:
- Per-peer block download tracking and stalled download detection
- Add new DNS seed from bitnodes.io
- Prevent socket leak in ThreadSocketHandler and correct some proxy related socket leaks
- Use pnode->nLastRecv as sync score (was the wrong way around)
Wallet:
- Make GetAvailableCredit run GetHash() only once per transaction (performance improvement)
- Lower paytxfee warning threshold from 0.25 BTC to 0.01 BTC
- Fix importwallet nTimeFirstKey (trigger necessary rescans)
- Log BerkeleyDB version at startup
- CWallet init fix
Build system:
- Add OSX build descriptors to gitian
- Fix explicit --disable-qt-dbus
- Don't require db_cxx.h when compiling with wallet disabled and GUI enabled
- Improve missing boost error reporting
- Upgrade miniupnpc version to 1.9
- gitian-linux: --enable-glibc-back-compat for binary compatibility with old distributions
- gitian: don't export any symbols from executable
- gitian: build against Qt 4.6
- devtools: add script to check symbols from Linux gitian executables
- Remove build-time no-IPv6 setting
GUI:
- Fix various coin control visual issues
- Show number of in/out connections in debug console
- Show weeks as well as years behind for long timespans behind
- Enable and disable the Show and Remove buttons for requested payments history based on whether any entry is selected.
- Show also value for options overridden on command line in options dialog
- Fill in label from address book also for URIs
- Fixes feel when resizing the last column on tables (issue #2862)
- Fix ESC in disablewallet mode
- Add expert section to wallet tab in optionsdialog
- Do proper boost::path conversion (fixes unicode in datadir)
- Only override -datadir if different from the default (fixes -datadir in config file)
- Show rescan progress at start-up
- Show importwallet progress
- Get required locks upfront in polling functions (avoids hanging on locks)
- Catch Windows shutdown events while client is running
- Optionally add third party links to transaction context menu
- Check for !pixmap() before trying to export QR code (avoids crashes when no QR code could be generated)
- Fix "Start bitcoin on system login"
Miscellaneous:
- Replace non-threadsafe C functions (gmtime, strerror and setlocale)
- Add missing cs_main and wallet locks
- Avoid exception at startup when system locale not recognized
- Changed bitrpc.py's raw_input to getpass for passwords to conceal characters during command line input
- devtools: add a script to fetch and postprocess translations
Credits
--------
Thanks to everyone who contributed to this release:
- Addy Yeow
- Altoidnerd
- Andrea D'Amore
- Andreas Schildbach
- Bardi Harborow
- Brandon Dahler
- Bryan Bishop
- Chris Beams
- Christian von Roques
- Cory Fields
- Cozz Lovan
- daniel
- Daniel Newton
- David A. Harding
- ditto-b
- duanemoody
- Eric S. Bullington
- Fabian Raetz
- Gavin Andresen
- Gregory Maxwell
- gubatron
- Haakon Nilsen
- harry
- Hector Jusforgues
- Isidoro Ghezzi
- Jeff Garzik
- Johnathan Corgan
- jtimon
- Kamil Domanski
- langerhans
- Luke Dashjr
- Manuel Araoz
- Mark Friedenbach
- Matt Corallo
- Matthew Bogosian
- Meeh
- Michael Ford
- Michagogo
- Mikael Wikman
- Mike Hearn
- olalonde
- paveljanik
- peryaudo
- Philip Kaufmann
- philsong
- Pieter Wuille
- R E Broadley
- richierichrawr
- Rune K. Svendsen
- rxl
- shshshsh
- Simon de la Rouviere
- Stuart Cardall
- super3
- Telepatheic
- Thomas Zander
- Torstein Husebø
- Warren Togami
- Wladimir J. van der Laan
- Yoichi Hirai

View file

@ -0,0 +1,207 @@
Bitcoin Core version 0.9.2 is now available from:
https://bitcoin.org/bin/0.9.2/
This is a new minor version release, bringing mostly bug fixes and some minor
improvements. OpenSSL has been updated because of a security issue (CVE-2014-0224).
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).
If you are upgrading from version 0.7.2 or earlier, the first time you run
0.9.2 your blockchain files will be re-indexed, which will take anywhere from
30 minutes to several hours, depending on the speed of your machine.
Downgrading warnings
--------------------
The 'chainstate' for this release is not always compatible with previous
releases, so if you run 0.9.x and then decide to switch back to a
0.8.x release you might get a blockchain validation error when starting the
old release (due to 'pruned outputs' being omitted from the index of
unspent transaction outputs).
Running the old release with the -reindex option will rebuild the chainstate
data structures and correct the problem.
Also, the first time you run a 0.8.x release on a 0.9 wallet it will rescan
the blockchain for missing spent coins, which will take a long time (tens
of minutes on a typical machine).
Important changes
==================
Gitian OSX build
-----------------
The deterministic build system that was already used for Windows and Linux
builds is now used for OSX as well. Although the resulting executables have
been tested quite a bit, there could be possible regressions. Be sure to report
these on the Github bug tracker mentioned above.
Compatibility of Linux build
-----------------------------
For Linux we now build against Qt 4.6, and filter the symbols for libstdc++ and glibc.
This brings back compatibility with
- Debian 6+ / Tails
- Ubuntu 10.04
- CentOS 6.5
0.9.2 Release notes
=======================
The OpenSSL dependency in the gitian builds has been upgraded to 1.0.1h because of CVE-2014-0224.
RPC:
- Add `getwalletinfo`, `getblockchaininfo` and `getnetworkinfo` calls (will replace hodge-podge `getinfo` at some point)
- Add a `relayfee` field to `getnetworkinfo`
- Fix RPC related shutdown hangs and leaks
- Always show syncnode in `getpeerinfo`
- `sendrawtransaction`: report the reject code and reason, and make it possible to re-send transactions that are already in the mempool
- `getmininginfo` show right genproclimit
Command-line options:
- Fix `-printblocktree` output
- Show error message if ReadConfigFile fails
Block-chain handling and storage:
- Fix for GetBlockValue() after block 13,440,000 (BIP42)
- Upgrade leveldb to 1.17
Protocol and network code:
- Per-peer block download tracking and stalled download detection
- Add new DNS seed from bitnodes.io
- Prevent socket leak in ThreadSocketHandler and correct some proxy related socket leaks
- Use pnode->nLastRecv as sync score (was the wrong way around)
Wallet:
- Make GetAvailableCredit run GetHash() only once per transaction (performance improvement)
- Lower paytxfee warning threshold from 0.25 BTC to 0.01 BTC
- Fix importwallet nTimeFirstKey (trigger necessary rescans)
- Log BerkeleyDB version at startup
- CWallet init fix
Build system:
- Add OSX build descriptors to gitian
- Fix explicit --disable-qt-dbus
- Don't require db_cxx.h when compiling with wallet disabled and GUI enabled
- Improve missing boost error reporting
- Upgrade miniupnpc version to 1.9
- gitian-linux: --enable-glibc-back-compat for binary compatibility with old distributions
- gitian: don't export any symbols from executable
- gitian: build against Qt 4.6
- devtools: add script to check symbols from Linux gitian executables
- Remove build-time no-IPv6 setting
GUI:
- Fix various coin control visual issues
- Show number of in/out connections in debug console
- Show weeks as well as years behind for long timespans behind
- Enable and disable the Show and Remove buttons for requested payments history based on whether any entry is selected.
- Show also value for options overridden on command line in options dialog
- Fill in label from address book also for URIs
- Fixes feel when resizing the last column on tables (issue #2862)
- Fix ESC in disablewallet mode
- Add expert section to wallet tab in optionsdialog
- Do proper boost::path conversion (fixes unicode in datadir)
- Only override -datadir if different from the default (fixes -datadir in config file)
- Show rescan progress at start-up
- Show importwallet progress
- Get required locks upfront in polling functions (avoids hanging on locks)
- Catch Windows shutdown events while client is running
- Optionally add third party links to transaction context menu
- Check for !pixmap() before trying to export QR code (avoids crashes when no QR code could be generated)
- Fix "Start bitcoin on system login"
Miscellaneous:
- Replace non-threadsafe C functions (gmtime, strerror and setlocale)
- Add missing cs_main and wallet locks
- Avoid exception at startup when system locale not recognized
- Changed bitrpc.py's raw_input to getpass for passwords to conceal characters during command line input
- devtools: add a script to fetch and postprocess translations
Credits
--------
Thanks to everyone who contributed to this release:
- Addy Yeow
- Altoidnerd
- Andrea D'Amore
- Andreas Schildbach
- Bardi Harborow
- Brandon Dahler
- Bryan Bishop
- Chris Beams
- Christian von Roques
- Cory Fields
- Cozz Lovan
- daniel
- Daniel Newton
- David A. Harding
- ditto-b
- duanemoody
- Eric S. Bullington
- Fabian Raetz
- Gavin Andresen
- Gregory Maxwell
- gubatron
- Haakon Nilsen
- harry
- Hector Jusforgues
- Isidoro Ghezzi
- Jeff Garzik
- Johnathan Corgan
- jtimon
- Kamil Domanski
- langerhans
- Luke Dashjr
- Manuel Araoz
- Mark Friedenbach
- Matt Corallo
- Matthew Bogosian
- Meeh
- Michael Ford
- Michagogo
- Mikael Wikman
- Mike Hearn
- olalonde
- paveljanik
- peryaudo
- Philip Kaufmann
- philsong
- Pieter Wuille
- R E Broadley
- richierichrawr
- Rune K. Svendsen
- rxl
- shshshsh
- Simon de la Rouviere
- Stuart Cardall
- super3
- Telepatheic
- Thomas Zander
- Torstein Husebø
- Warren Togami
- Wladimir J. van der Laan
- Yoichi Hirai

View file

@ -23,7 +23,7 @@ Release Process
* * * * * *
##perform gitian builds ###perform gitian builds
From a directory containing the bitcoin source, gitian-builder and gitian.sigs From a directory containing the bitcoin source, gitian-builder and gitian.sigs
@ -34,21 +34,40 @@ Release Process
popd popd
pushd ./gitian-builder pushd ./gitian-builder
Fetch and build inputs: (first time, or when dependency versions change) ###fetch and build inputs: (first time, or when dependency versions change)
mkdir -p inputs; cd inputs/ mkdir -p inputs; cd inputs/
Register and download the Apple SDK: (see OSX Readme for details)
https://developer.apple.com/downloads/download.action?path=Developer_Tools/xcode_4.6.3/xcode4630916281a.dmg
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
Download remaining inputs, and build everything:
wget 'http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.9.tar.gz' -O miniupnpc-1.9.tar.gz wget 'http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.9.tar.gz' -O miniupnpc-1.9.tar.gz
wget 'https://www.openssl.org/source/openssl-1.0.1g.tar.gz' wget 'https://www.openssl.org/source/openssl-1.0.1h.tar.gz'
wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz' wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz'
wget 'http://zlib.net/zlib-1.2.8.tar.gz' wget 'http://zlib.net/zlib-1.2.8.tar.gz'
wget 'ftp://ftp.simplesystems.org/pub/png/src/history/libpng16/libpng-1.6.8.tar.gz' wget 'ftp://ftp.simplesystems.org/pub/png/src/history/libpng16/libpng-1.6.8.tar.gz'
wget 'https://fukuchi.org/works/qrencode/qrencode-3.4.3.tar.bz2' wget 'https://fukuchi.org/works/qrencode/qrencode-3.4.3.tar.bz2'
wget 'https://downloads.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.tar.bz2' wget 'https://downloads.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.tar.bz2'
wget 'https://svn.boost.org/trac/boost/raw-attachment/ticket/7262/boost-mingw.patch' -O \ wget 'https://svn.boost.org/trac/boost/raw-attachment/ticket/7262/boost-mingw.patch' -O boost-mingw-gas-cross-compile-2013-03-03.patch
boost-mingw-gas-cross-compile-2013-03-03.patch
wget 'https://download.qt-project.org/official_releases/qt/5.2/5.2.0/single/qt-everywhere-opensource-src-5.2.0.tar.gz' wget 'https://download.qt-project.org/official_releases/qt/5.2/5.2.0/single/qt-everywhere-opensource-src-5.2.0.tar.gz'
wget 'https://download.qt-project.org/official_releases/qt/5.2/5.2.1/single/qt-everywhere-opensource-src-5.2.1.tar.gz'
wget 'https://download.qt-project.org/archive/qt/4.6/qt-everywhere-opensource-src-4.6.4.tar.gz' wget 'https://download.qt-project.org/archive/qt/4.6/qt-everywhere-opensource-src-4.6.4.tar.gz'
wget 'https://protobuf.googlecode.com/files/protobuf-2.5.0.tar.bz2' wget 'https://protobuf.googlecode.com/files/protobuf-2.5.0.tar.bz2'
wget 'https://github.com/mingwandroid/toolchain4/archive/10cc648683617cca8bcbeae507888099b41b530c.tar.gz'
wget 'http://www.opensource.apple.com/tarballs/cctools/cctools-809.tar.gz'
wget 'http://www.opensource.apple.com/tarballs/dyld/dyld-195.5.tar.gz'
wget 'http://www.opensource.apple.com/tarballs/ld64/ld64-127.2.tar.gz'
wget 'http://cdrkit.org/releases/cdrkit-1.1.11.tar.gz'
wget 'https://github.com/theuni/libdmg-hfsplus/archive/libdmg-hfsplus-v0.1.tar.gz'
wget 'http://llvm.org/releases/3.2/clang+llvm-3.2-x86-linux-ubuntu-12.04.tar.gz' -O clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz
wget 'https://raw.githubusercontent.com/theuni/osx-cross-depends/master/patches/cdrtools/genisoimage.diff' -O cdrkit-deterministic.patch
cd .. cd ..
./bin/gbuild ../bitcoin/contrib/gitian-descriptors/boost-linux.yml ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/boost-linux.yml
mv build/out/boost-*.zip inputs/ mv build/out/boost-*.zip inputs/
@ -64,28 +83,38 @@ Release Process
mv build/out/qt-*.zip inputs/ mv build/out/qt-*.zip inputs/
./bin/gbuild ../bitcoin/contrib/gitian-descriptors/protobuf-win.yml ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/protobuf-win.yml
mv build/out/protobuf-*.zip inputs/ mv build/out/protobuf-*.zip inputs/
./bin/gbuild ../bitcoin/contrib/gitian-descriptors/gitian-osx-native.yml
mv build/out/osx-*.tar.gz inputs/
./bin/gbuild ../bitcoin/contrib/gitian-descriptors/gitian-osx-depends.yml
mv build/out/osx-*.tar.gz inputs/
./bin/gbuild ../bitcoin/contrib/gitian-descriptors/gitian-osx-qt.yml
mv build/out/osx-*.tar.gz inputs/
The expected SHA256 hashes of the intermediate inputs are: The expected SHA256 hashes of the intermediate inputs are:
35c3dfd8b9362f59e81b51881b295232e3bc9e286f1add193b59d486d9ac4a5c bitcoin-deps-linux32-gitian-r5.zip
571789867d172500fa96d63d0ba8c5b1e1a3d6f44f720eddf2f93665affc88b3 bitcoin-deps-linux64-gitian-r5.zip
f29b7d9577417333fb56e023c2977f5726a7c297f320b175a4108cf7cd4c2d29 boost-linux32-1.55.0-gitian-r1.zip f29b7d9577417333fb56e023c2977f5726a7c297f320b175a4108cf7cd4c2d29 boost-linux32-1.55.0-gitian-r1.zip
88232451c4104f7eb16e469ac6474fd1231bd485687253f7b2bdf46c0781d535 boost-linux64-1.55.0-gitian-r1.zip 88232451c4104f7eb16e469ac6474fd1231bd485687253f7b2bdf46c0781d535 boost-linux64-1.55.0-gitian-r1.zip
74ec2d301cf1a9d03b194153f545102ba45dad02b390485212fe6717de486361 qt-linux32-4.6.4-gitian-r1.tar.gz 46710f673467e367738d8806e45b4cb5931aaeea61f4b6b55a68eea56d5006c5 bitcoin-deps-linux32-gitian-r6.zip
01d0477e299467f09280f15424781154e2b1ea4072c5edb16e044c234954fd9a qt-linux64-4.6.4-gitian-r1.tar.gz f03be39fb26670243d3a659e64d18e19d03dec5c11e9912011107768390b5268 bitcoin-deps-linux64-gitian-r6.zip
57e57dbdadc818cd270e7e00500a5e1085b3bcbdef69a885f0fb7573a8d987e1 qt-linux32-4.6.4-gitian-r1.tar.gz
60eb4b9c5779580b7d66529efa5b2836ba1a70edde2a0f3f696d647906a826be qt-linux64-4.6.4-gitian-r1.tar.gz
60dc2d3b61e9c7d5dbe2f90d5955772ad748a47918ff2d8b74e8db9b1b91c909 boost-win32-1.55.0-gitian-r6.zip 60dc2d3b61e9c7d5dbe2f90d5955772ad748a47918ff2d8b74e8db9b1b91c909 boost-win32-1.55.0-gitian-r6.zip
f65fcaf346bc7b73bc8db3a8614f4f6bee2f61fcbe495e9881133a7c2612a167 boost-win64-1.55.0-gitian-r6.zip f65fcaf346bc7b73bc8db3a8614f4f6bee2f61fcbe495e9881133a7c2612a167 boost-win64-1.55.0-gitian-r6.zip
97e62002d338885336bb24e7cbb9471491294bd8857af7a83d18c0961f864ec0 bitcoin-deps-win32-gitian-r11.zip 70de248cd0dd7e7476194129e818402e974ca9c5751cbf591644dc9f332d3b59 bitcoin-deps-win32-gitian-r13.zip
ee3ea2d5aac1a67ea6bfbea2c04068a7c0940616ce48ee4f37c264bb9d4438ef bitcoin-deps-win64-gitian-r11.zip 9eace4c76f639f4f3580a478eee4f50246e1bbb5ccdcf37a158261a5a3fa3e65 bitcoin-deps-win64-gitian-r13.zip
963e3e5e85879010a91143c90a711a5d1d5aba992e38672cdf7b54e42c56b2f1 qt-win32-5.2.0-gitian-r3.zip 963e3e5e85879010a91143c90a711a5d1d5aba992e38672cdf7b54e42c56b2f1 qt-win32-5.2.0-gitian-r3.zip
751c579830d173ef3e6f194e83d18b92ebef6df03289db13ab77a52b6bc86ef0 qt-win64-5.2.0-gitian-r3.zip 751c579830d173ef3e6f194e83d18b92ebef6df03289db13ab77a52b6bc86ef0 qt-win64-5.2.0-gitian-r3.zip
e2e403e1a08869c7eed4d4293bce13d51ec6a63592918b90ae215a0eceb44cb4 protobuf-win32-2.5.0-gitian-r4.zip e2e403e1a08869c7eed4d4293bce13d51ec6a63592918b90ae215a0eceb44cb4 protobuf-win32-2.5.0-gitian-r4.zip
a0999037e8b0ef9ade13efd88fee261ba401f5ca910068b7e0cd3262ba667db0 protobuf-win64-2.5.0-gitian-r4.zip a0999037e8b0ef9ade13efd88fee261ba401f5ca910068b7e0cd3262ba667db0 protobuf-win64-2.5.0-gitian-r4.zip
512bc0622c883e2e0f4cbc3fedfd8c2402d06c004ce6fb32303cc2a6f405b6df osx-native-depends-r3.tar.gz
927e4b222be6d590b4bc2fc185872a5d0ca5c322adb983764d3ed84be6bdbc81 osx-depends-r4.tar.gz
ec95abef1df2b096a970359787c01d8c45e2a4475b7ae34e12c022634fbdba8a osx-depends-qt-5.2.1-r4.tar.gz
Build bitcoind and bitcoin-qt on Linux32, Linux64, and Win32:
Build Bitcoin Core for Linux, Windows, and OS X:
./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
./bin/gsign --signer $SIGNER --release ${VERSION} --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
pushd build/out pushd build/out
zip -r bitcoin-${VERSION}-linux-gitian.zip * zip -r bitcoin-${VERSION}-linux-gitian.zip *
mv bitcoin-${VERSION}-linux-gitian.zip ../../../ mv bitcoin-${VERSION}-linux-gitian.zip ../../../
@ -96,13 +125,19 @@ Release Process
zip -r bitcoin-${VERSION}-win-gitian.zip * zip -r bitcoin-${VERSION}-win-gitian.zip *
mv bitcoin-${VERSION}-win-gitian.zip ../../../ mv bitcoin-${VERSION}-win-gitian.zip ../../../
popd popd
./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx-bitcoin.yml
./bin/gsign --signer $SIGNER --release ${VERSION}-osx --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx-bitcoin.yml
pushd build/out
mv Bitcoin-Qt.dmg ../../../
popd
popd popd
Build output expected: Build output expected:
1. linux 32-bit and 64-bit binaries + source (bitcoin-${VERSION}-linux-gitian.zip) 1. linux 32-bit and 64-bit binaries + source (bitcoin-${VERSION}-linux-gitian.zip)
2. windows 32-bit and 64-bit binaries + installer + source (bitcoin-${VERSION}-win-gitian.zip) 2. windows 32-bit and 64-bit binaries + installer + source (bitcoin-${VERSION}-win-gitian.zip)
3. Gitian signatures (in gitian.sigs/${VERSION}[-win]/(your gitian key)/ 3. OSX installer (Bitcoin-Qt.dmg)
4. Gitian signatures (in gitian.sigs/${VERSION}-<linux|win|osx>/(your gitian key)/
repackage gitian builds for release as stand-alone zip/tar/installer exe repackage gitian builds for release as stand-alone zip/tar/installer exe
@ -119,21 +154,6 @@ repackage gitian builds for release as stand-alone zip/tar/installer exe
zip -r bitcoin-${VERSION}-win.zip bitcoin-${VERSION}-win zip -r bitcoin-${VERSION}-win.zip bitcoin-${VERSION}-win
rm -rf bitcoin-${VERSION}-win rm -rf bitcoin-${VERSION}-win
**Perform Mac build:**
OSX binaries are created by Gavin Andresen on a 64-bit, OSX 10.6 machine.
./autogen.sh
SDK=$(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk
CXXFLAGS="-mmacosx-version-min=10.6 -isysroot $SDK" ./configure --enable-upnp-default
make
export QTDIR=/opt/local/share/qt4 # needed to find translations/qt_*.qm files
T=$(contrib/qt_translations.py $QTDIR/translations src/qt/locale)
export CODESIGNARGS='--keychain ...path_to_keychain --sign "Developer ID Application: BITCOIN FOUNDATION, INC., THE"'
python2.7 contrib/macdeploy/macdeployqtplus Bitcoin-Qt.app -sign -add-qt-tr $T -dmg -fancy contrib/macdeploy/fancy.plist
Build output expected: Bitcoin-Qt.dmg
###Next steps: ###Next steps:
* Code-sign Windows -setup.exe (in a Windows virtual machine using signtool) * Code-sign Windows -setup.exe (in a Windows virtual machine using signtool)
@ -157,8 +177,9 @@ repackage gitian builds for release as stand-alone zip/tar/installer exe
Commit your signature to gitian.sigs: Commit your signature to gitian.sigs:
pushd gitian.sigs pushd gitian.sigs
git add ${VERSION}/${SIGNER} git add ${VERSION}-linux/${SIGNER}
git add ${VERSION}-win/${SIGNER} git add ${VERSION}-win/${SIGNER}
git add ${VERSION}-osx/${SIGNER}
git commit -a git commit -a
git push # Assuming you can push to the gitian.sigs tree git push # Assuming you can push to the gitian.sigs tree
popd popd
@ -167,34 +188,6 @@ Commit your signature to gitian.sigs:
### After 3 or more people have gitian-built, repackage gitian-signed zips: ### After 3 or more people have gitian-built, repackage gitian-signed zips:
From a directory containing bitcoin source, gitian.sigs and gitian zips
export VERSION=(new version, e.g. 0.8.0)
mkdir bitcoin-${VERSION}-linux-gitian
pushd bitcoin-${VERSION}-linux-gitian
unzip ../bitcoin-${VERSION}-linux-gitian.zip
mkdir gitian
cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/
for signer in $(ls ../gitian.sigs/${VERSION}/); do
cp ../gitian.sigs/${VERSION}/${signer}/bitcoin-build.assert ./gitian/${signer}-build.assert
cp ../gitian.sigs/${VERSION}/${signer}/bitcoin-build.assert.sig ./gitian/${signer}-build.assert.sig
done
zip -r bitcoin-${VERSION}-linux-gitian.zip *
cp bitcoin-${VERSION}-linux-gitian.zip ../
popd
mkdir bitcoin-${VERSION}-win-gitian
pushd bitcoin-${VERSION}-win-gitian
unzip ../bitcoin-${VERSION}-win-gitian.zip
mkdir gitian
cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/
for signer in $(ls ../gitian.sigs/${VERSION}-win/); do
cp ../gitian.sigs/${VERSION}-win/${signer}/bitcoin-build.assert ./gitian/${signer}-build.assert
cp ../gitian.sigs/${VERSION}-win/${signer}/bitcoin-build.assert.sig ./gitian/${signer}-build.assert.sig
done
zip -r bitcoin-${VERSION}-win-gitian.zip *
cp bitcoin-${VERSION}-win-gitian.zip ../
popd
- Upload gitian zips to SourceForge - Upload gitian zips to SourceForge
- Announce the release: - Announce the release:

View file

@ -1,7 +1,7 @@
Translations Translations
============ ============
The Qt GUI can be easily translated into other languages. Here's how we The Bitcoin Core GUI can be easily translated into other languages. Here's how we
handle those translations. handle those translations.
Files and Folders Files and Folders

134
qa/rpc-tests/netutil.py Normal file
View file

@ -0,0 +1,134 @@
# Linux network utilities
import sys
import socket
import fcntl
import struct
import array
import os
import binascii
# Roughly based on http://voorloopnul.com/blog/a-python-netstat-in-less-than-100-lines-of-code/ by Ricardo Pascal
STATE_ESTABLISHED = '01'
STATE_SYN_SENT = '02'
STATE_SYN_RECV = '03'
STATE_FIN_WAIT1 = '04'
STATE_FIN_WAIT2 = '05'
STATE_TIME_WAIT = '06'
STATE_CLOSE = '07'
STATE_CLOSE_WAIT = '08'
STATE_LAST_ACK = '09'
STATE_LISTEN = '0A'
STATE_CLOSING = '0B'
def get_socket_inodes(pid):
'''
Get list of socket inodes for process pid.
'''
base = '/proc/%i/fd' % pid
inodes = []
for item in os.listdir(base):
target = os.readlink(os.path.join(base, item))
if target.startswith('socket:'):
inodes.append(int(target[8:-1]))
return inodes
def _remove_empty(array):
return [x for x in array if x !='']
def _convert_ip_port(array):
host,port = array.split(':')
# convert host from mangled-per-four-bytes form as used by kernel
host = binascii.unhexlify(host)
host_out = ''
for x in range(0, len(host)/4):
(val,) = struct.unpack('=I', host[x*4:(x+1)*4])
host_out += '%08x' % val
return host_out,int(port,16)
def netstat(typ='tcp'):
'''
Function to return a list with status of tcp connections at linux systems
To get pid of all network process running on system, you must run this script
as superuser
'''
with open('/proc/net/'+typ,'r') as f:
content = f.readlines()
content.pop(0)
result = []
for line in content:
line_array = _remove_empty(line.split(' ')) # Split lines and remove empty spaces.
tcp_id = line_array[0]
l_addr = _convert_ip_port(line_array[1])
r_addr = _convert_ip_port(line_array[2])
state = line_array[3]
inode = int(line_array[9]) # Need the inode to match with process pid.
nline = [tcp_id, l_addr, r_addr, state, inode]
result.append(nline)
return result
def get_bind_addrs(pid):
'''
Get bind addresses as (host,port) tuples for process pid.
'''
inodes = get_socket_inodes(pid)
bind_addrs = []
for conn in netstat('tcp') + netstat('tcp6'):
if conn[3] == STATE_LISTEN and conn[4] in inodes:
bind_addrs.append(conn[1])
return bind_addrs
# from: http://code.activestate.com/recipes/439093/
def all_interfaces():
'''
Return all interfaces that are up
'''
is_64bits = sys.maxsize > 2**32
struct_size = 40 if is_64bits else 32
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
max_possible = 8 # initial value
while True:
bytes = max_possible * struct_size
names = array.array('B', '\0' * bytes)
outbytes = struct.unpack('iL', fcntl.ioctl(
s.fileno(),
0x8912, # SIOCGIFCONF
struct.pack('iL', bytes, names.buffer_info()[0])
))[0]
if outbytes == bytes:
max_possible *= 2
else:
break
namestr = names.tostring()
return [(namestr[i:i+16].split('\0', 1)[0],
socket.inet_ntoa(namestr[i+20:i+24]))
for i in range(0, outbytes, struct_size)]
def addr_to_hex(addr):
'''
Convert string IPv4 or IPv6 address to binary address as returned by
get_bind_addrs.
Very naive implementation that certainly doesn't work for all IPv6 variants.
'''
if '.' in addr: # IPv4
addr = [int(x) for x in addr.split('.')]
elif ':' in addr: # IPv6
sub = [[], []] # prefix, suffix
x = 0
addr = addr.split(':')
for i,comp in enumerate(addr):
if comp == '':
if i == 0 or i == (len(addr)-1): # skip empty component at beginning or end
continue
x += 1 # :: skips to suffix
assert(x < 2)
else: # two bytes per component
val = int(comp, 16)
sub[x].append(val >> 8)
sub[x].append(val & 0xff)
nullbytes = 16 - len(sub[0]) - len(sub[1])
assert((x == 0 and nullbytes == 0) or (x == 1 and nullbytes > 0))
addr = sub[0] + ([0] * nullbytes) + sub[1]
else:
raise ValueError('Could not parse address %s' % addr)
return binascii.hexlify(bytearray(addr))

225
qa/rpc-tests/receivedby.py Executable file
View file

@ -0,0 +1,225 @@
#!/usr/bin/env python
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the MIT/X11 software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# Exercise the listtransactions API
# Add python-bitcoinrpc to module search path:
import os
import sys
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "python-bitcoinrpc"))
import json
import shutil
import subprocess
import tempfile
import traceback
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
from util import *
def get_sub_array_from_array(object_array, to_match):
'''
Finds and returns a sub array from an array of arrays.
to_match should be a unique idetifier of a sub array
'''
num_matched = 0
for item in object_array:
all_match = True
for key,value in to_match.items():
if item[key] != value:
all_match = False
if not all_match:
continue
return item
return []
def check_array_result(object_array, to_match, expected, should_not_find = False):
"""
Pass in array of JSON objects, a dictionary with key/value pairs
to match against, and another dictionary with expected key/value
pairs.
If the should_not_find flag is true, to_match should not be found in object_array
"""
if should_not_find == True:
expected = { }
num_matched = 0
for item in object_array:
all_match = True
for key,value in to_match.items():
if item[key] != value:
all_match = False
if not all_match:
continue
for key,value in expected.items():
if item[key] != value:
raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
num_matched = num_matched+1
if num_matched == 0 and should_not_find != True:
raise AssertionError("No objects matched %s"%(str(to_match)))
if num_matched > 0 and should_not_find == True:
raise AssertionError("Objects was matched %s"%(str(to_match)))
def run_test(nodes):
'''
listreceivedbyaddress Test
'''
# Send from node 0 to 1
addr = nodes[1].getnewaddress()
txid = nodes[0].sendtoaddress(addr, 0.1)
sync_mempools(nodes)
#Check not listed in listreceivedbyaddress because has 0 confirmations
check_array_result(nodes[1].listreceivedbyaddress(),
{"address":addr},
{ },
True)
#Bury Tx under 10 block so it will be returned by listreceivedbyaddress
nodes[1].setgenerate(True, 10)
sync_blocks(nodes)
check_array_result(nodes[1].listreceivedbyaddress(),
{"address":addr},
{"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]})
#With min confidence < 10
check_array_result(nodes[1].listreceivedbyaddress(5),
{"address":addr},
{"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]})
#With min confidence > 10, should not find Tx
check_array_result(nodes[1].listreceivedbyaddress(11),{"address":addr},{ },True)
#Empty Tx
addr = nodes[1].getnewaddress()
check_array_result(nodes[1].listreceivedbyaddress(0,True),
{"address":addr},
{"address":addr, "account":"", "amount":0, "confirmations":0, "txids":[]})
'''
getreceivedbyaddress Test
'''
# Send from node 0 to 1
addr = nodes[1].getnewaddress()
txid = nodes[0].sendtoaddress(addr, 0.1)
sync_mempools(nodes)
#Check balance is 0 because of 0 confirmations
balance = nodes[1].getreceivedbyaddress(addr)
if balance != Decimal("0.0"):
raise AssertionError("Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance))
#Check balance is 0.1
balance = nodes[1].getreceivedbyaddress(addr,0)
if balance != Decimal("0.1"):
raise AssertionError("Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance))
#Bury Tx under 10 block so it will be returned by the default getreceivedbyaddress
nodes[1].setgenerate(True, 10)
sync_blocks(nodes)
balance = nodes[1].getreceivedbyaddress(addr)
if balance != Decimal("0.1"):
raise AssertionError("Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance))
'''
listreceivedbyaccount + getreceivedbyaccount Test
'''
#set pre-state
addrArr = nodes[1].getnewaddress()
account = nodes[1].getaccount(addrArr)
received_by_account_json = get_sub_array_from_array(nodes[1].listreceivedbyaccount(),{"account":account})
if len(received_by_account_json) == 0:
raise AssertionError("No accounts found in node")
balance_by_account = rec_by_accountArr = nodes[1].getreceivedbyaccount(account)
txid = nodes[0].sendtoaddress(addr, 0.1)
# listreceivedbyaccount should return received_by_account_json because of 0 confirmations
check_array_result(nodes[1].listreceivedbyaccount(),
{"account":account},
received_by_account_json)
# getreceivedbyaddress should return same balance because of 0 confirmations
balance = nodes[1].getreceivedbyaccount(account)
if balance != balance_by_account:
raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance))
nodes[1].setgenerate(True, 10)
sync_blocks(nodes)
# listreceivedbyaccount should return updated account balance
check_array_result(nodes[1].listreceivedbyaccount(),
{"account":account},
{"account":received_by_account_json["account"], "amount":(received_by_account_json["amount"] + Decimal("0.1"))})
# getreceivedbyaddress should return updates balance
balance = nodes[1].getreceivedbyaccount(account)
if balance != balance_by_account + Decimal("0.1"):
raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance))
#Create a new account named "mynewaccount" that has a 0 balance
nodes[1].getaccountaddress("mynewaccount")
received_by_account_json = get_sub_array_from_array(nodes[1].listreceivedbyaccount(0,True),{"account":"mynewaccount"})
if len(received_by_account_json) == 0:
raise AssertionError("No accounts found in node")
# Test includeempty of listreceivedbyaccount
if received_by_account_json["amount"] != Decimal("0.0"):
raise AssertionError("Wrong balance returned by listreceivedbyaccount, %0.2f"%(received_by_account_json["amount"]))
# Test getreceivedbyaccount for 0 amount accounts
balance = nodes[1].getreceivedbyaccount("mynewaccount")
if balance != Decimal("0.0"):
raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance))
def main():
import optparse
parser = optparse.OptionParser(usage="%prog [options]")
parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true",
help="Leave bitcoinds and test.* datadir on exit or error")
parser.add_option("--srcdir", dest="srcdir", default="../../src",
help="Source directory containing bitcoind/bitcoin-cli (default: %default%)")
parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"),
help="Root directory for datadirs")
(options, args) = parser.parse_args()
os.environ['PATH'] = options.srcdir+":"+os.environ['PATH']
check_json_precision()
success = False
nodes = []
try:
print("Initializing test directory "+options.tmpdir)
if not os.path.isdir(options.tmpdir):
os.makedirs(options.tmpdir)
initialize_chain(options.tmpdir)
nodes = start_nodes(2, options.tmpdir)
connect_nodes(nodes[1], 0)
sync_blocks(nodes)
run_test(nodes)
success = True
except AssertionError as e:
print("Assertion failed: "+e.message)
except Exception as e:
print("Unexpected exception caught during testing: "+str(e))
traceback.print_tb(sys.exc_info()[2])
if not options.nocleanup:
print("Cleaning up")
stop_nodes(nodes)
wait_bitcoinds()
shutil.rmtree(options.tmpdir)
if success:
print("Tests successful")
sys.exit(0)
else:
print("Failed")
sys.exit(1)
if __name__ == '__main__':
main()

154
qa/rpc-tests/rpcbind_test.py Executable file
View file

@ -0,0 +1,154 @@
#!/usr/bin/env python
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the MIT/X11 software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# Test for -rpcbind, as well as -rpcallowip and -rpcconnect
# Add python-bitcoinrpc to module search path:
import os
import sys
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "python-bitcoinrpc"))
import json
import shutil
import subprocess
import tempfile
import traceback
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
from util import *
from netutil import *
def run_bind_test(tmpdir, allow_ips, connect_to, addresses, expected):
'''
Start a node with requested rpcallowip and rpcbind parameters,
then try to connect, and check if the set of bound addresses
matches the expected set.
'''
expected = [(addr_to_hex(addr), port) for (addr, port) in expected]
base_args = ['-disablewallet', '-nolisten']
if allow_ips:
base_args += ['-rpcallowip=' + x for x in allow_ips]
binds = ['-rpcbind='+addr for addr in addresses]
nodes = start_nodes(1, tmpdir, [base_args + binds], connect_to)
try:
pid = bitcoind_processes[0].pid
assert_equal(set(get_bind_addrs(pid)), set(expected))
finally:
stop_nodes(nodes)
wait_bitcoinds()
def run_allowip_test(tmpdir, allow_ips, rpchost, rpcport):
'''
Start a node with rpcwallow IP, and request getinfo
at a non-localhost IP.
'''
base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips]
nodes = start_nodes(1, tmpdir, [base_args])
try:
# connect to node through non-loopback interface
url = "http://rt:rt@%s:%d" % (rpchost, rpcport,)
node = AuthServiceProxy(url)
node.getinfo()
finally:
node = None # make sure connection will be garbage collected and closed
stop_nodes(nodes)
wait_bitcoinds()
def run_test(tmpdir):
assert(sys.platform == 'linux2') # due to OS-specific network stats queries, this test works only on Linux
# find the first non-loopback interface for testing
non_loopback_ip = None
for name,ip in all_interfaces():
if ip != '127.0.0.1':
non_loopback_ip = ip
break
if non_loopback_ip is None:
assert(not 'This test requires at least one non-loopback IPv4 interface')
print("Using interface %s for testing" % non_loopback_ip)
defaultport = rpc_port(0)
# check default without rpcallowip (IPv4 and IPv6 localhost)
run_bind_test(tmpdir, None, '127.0.0.1', [],
[('127.0.0.1', defaultport), ('::1', defaultport)])
# check default with rpcallowip (IPv6 any)
run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', [],
[('::0', defaultport)])
# check only IPv4 localhost (explicit)
run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', ['127.0.0.1'],
[('127.0.0.1', defaultport)])
# check only IPv4 localhost (explicit) with alternative port
run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171'],
[('127.0.0.1', 32171)])
# check only IPv4 localhost (explicit) with multiple alternative ports on same host
run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171', '127.0.0.1:32172'],
[('127.0.0.1', 32171), ('127.0.0.1', 32172)])
# check only IPv6 localhost (explicit)
run_bind_test(tmpdir, ['[::1]'], '[::1]', ['[::1]'],
[('::1', defaultport)])
# check both IPv4 and IPv6 localhost (explicit)
run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', ['127.0.0.1', '[::1]'],
[('127.0.0.1', defaultport), ('::1', defaultport)])
# check only non-loopback interface
run_bind_test(tmpdir, [non_loopback_ip], non_loopback_ip, [non_loopback_ip],
[(non_loopback_ip, defaultport)])
# Check that with invalid rpcallowip, we are denied
run_allowip_test(tmpdir, [non_loopback_ip], non_loopback_ip, defaultport)
try:
run_allowip_test(tmpdir, ['1.1.1.1'], non_loopback_ip, defaultport)
assert(not 'Connection not denied by rpcallowip as expected')
except ValueError:
pass
def main():
import optparse
parser = optparse.OptionParser(usage="%prog [options]")
parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true",
help="Leave bitcoinds and test.* datadir on exit or error")
parser.add_option("--srcdir", dest="srcdir", default="../../src",
help="Source directory containing bitcoind/bitcoin-cli (default: %default%)")
parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"),
help="Root directory for datadirs")
(options, args) = parser.parse_args()
os.environ['PATH'] = options.srcdir+":"+os.environ['PATH']
check_json_precision()
success = False
nodes = []
try:
print("Initializing test directory "+options.tmpdir)
if not os.path.isdir(options.tmpdir):
os.makedirs(options.tmpdir)
initialize_chain(options.tmpdir)
run_test(options.tmpdir)
success = True
except AssertionError as e:
print("Assertion failed: "+e.message)
except Exception as e:
print("Unexpected exception caught during testing: "+str(e))
traceback.print_tb(sys.exc_info()[2])
if not options.nocleanup:
print("Cleaning up")
wait_bitcoinds()
shutil.rmtree(options.tmpdir)
if success:
print("Tests successful")
sys.exit(0)
else:
print("Failed")
sys.exit(1)
if __name__ == '__main__':
main()

142
qa/rpc-tests/smartfees.py Executable file
View file

@ -0,0 +1,142 @@
#!/usr/bin/env python
#
# Test fee estimation code
#
# Add python-bitcoinrpc to module search path:
import os
import sys
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "python-bitcoinrpc"))
import json
import random
import shutil
import subprocess
import tempfile
import traceback
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
from util import *
def run_test(nodes, test_dir):
nodes.append(start_node(0, test_dir,
["-debug=mempool", "-debug=estimatefee"]))
# 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)
nodes.append(start_node(1, test_dir,
["-blockprioritysize=1500", "-blockmaxsize=2000",
"-debug=mempool", "-debug=estimatefee"]))
connect_nodes(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"]
nodes.append(start_node(2, test_dir, node2args))
connect_nodes(nodes[2], 0)
sync_blocks(nodes)
# Prime the memory pool with pairs of transactions
# (high-priority, random fee and zero-priority, random fee)
min_fee = Decimal("0.001")
fees_per_kb = [];
for i in range(12):
(txid, txhex, fee) = random_zeropri_transaction(nodes, Decimal("1.1"),
min_fee, min_fee, 20)
tx_kbytes = (len(txhex)/2)/1000.0
fees_per_kb.append(float(fee)/tx_kbytes)
# Mine blocks with node2 until the memory pool clears:
count_start = nodes[2].getblockcount()
while len(nodes[2].getrawmempool()) > 0:
nodes[2].setgenerate(True, 1)
sync_blocks(nodes)
all_estimates = [ nodes[0].estimatefee(i) for i in range(1,20) ]
print("Fee estimates, super-stingy miner: "+str([str(e) for e in all_estimates]))
# Estimates should be within the bounds of what transactions fees actually were:
delta = 1.0e-6 # account for rounding error
for e in filter(lambda x: x >= 0, all_estimates):
if float(e)+delta < min(fees_per_kb) or float(e)-delta > max(fees_per_kb):
raise AssertionError("Estimated fee (%f) out of range (%f,%f)"%(float(e), min_fee_kb, max_fee_kb))
# Generate transactions while mining 30 more blocks, this time with node1:
for i in range(30):
for j in range(random.randrange(6-4,6+4)):
(txid, txhex, fee) = random_transaction(nodes, Decimal("1.1"),
Decimal("0.0"), min_fee, 20)
tx_kbytes = (len(txhex)/2)/1000.0
fees_per_kb.append(float(fee)/tx_kbytes)
nodes[1].setgenerate(True, 1)
sync_blocks(nodes)
all_estimates = [ nodes[0].estimatefee(i) for i in range(1,20) ]
print("Fee estimates, more generous miner: "+str([ str(e) for e in all_estimates]))
for e in filter(lambda x: x >= 0, all_estimates):
if float(e)+delta < min(fees_per_kb) or float(e)-delta > max(fees_per_kb):
raise AssertionError("Estimated fee (%f) out of range (%f,%f)"%(float(e), min_fee_kb, max_fee_kb))
# Finish by mining a normal-sized block:
while len(nodes[0].getrawmempool()) > 0:
nodes[0].setgenerate(True, 1)
sync_blocks(nodes)
final_estimates = [ nodes[0].estimatefee(i) for i in range(1,20) ]
print("Final fee estimates: "+str([ str(e) for e in final_estimates]))
def main():
import optparse
parser = optparse.OptionParser(usage="%prog [options]")
parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true",
help="Leave bitcoinds and test.* datadir on exit or error")
parser.add_option("--srcdir", dest="srcdir", default="../../src",
help="Source directory containing bitcoind/bitcoin-cli (default: %default%)")
parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"),
help="Root directory for datadirs")
(options, args) = parser.parse_args()
os.environ['PATH'] = options.srcdir+":"+os.environ['PATH']
check_json_precision()
success = False
nodes = []
try:
print("Initializing test directory "+options.tmpdir)
print(" node0 running at: 127.0.0.1:%d"%(p2p_port(0)))
if not os.path.isdir(options.tmpdir):
os.makedirs(options.tmpdir)
initialize_chain(options.tmpdir)
run_test(nodes, options.tmpdir)
success = True
except AssertionError as e:
print("Assertion failed: "+e.message)
except Exception as e:
print("Unexpected exception caught during testing: "+str(e))
traceback.print_tb(sys.exc_info()[2])
if not options.nocleanup:
print("Cleaning up")
stop_nodes(nodes)
wait_bitcoinds()
shutil.rmtree(options.tmpdir)
if success:
print("Tests successful")
sys.exit(0)
else:
print("Failed")
sys.exit(1)
if __name__ == '__main__':
main()

View file

@ -12,15 +12,19 @@ sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "python
from decimal import Decimal from decimal import Decimal
import json import json
import random
import shutil import shutil
import subprocess import subprocess
import time import time
import re
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
from util import * from util import *
START_P2P_PORT=11000 def p2p_port(n):
START_RPC_PORT=11100 return 11000 + n + os.getpid()%999
def rpc_port(n):
return 12000 + n + os.getpid()%999
def check_json_precision(): def check_json_precision():
"""Make sure json library being used does not lose precision converting BTC values""" """Make sure json library being used does not lose precision converting BTC values"""
@ -57,6 +61,18 @@ def sync_mempools(rpc_connections):
bitcoind_processes = [] bitcoind_processes = []
def initialize_datadir(dir, n):
datadir = os.path.join(dir, "node"+str(n))
if not os.path.isdir(datadir):
os.makedirs(datadir)
with open(os.path.join(datadir, "bitcoin.conf"), 'w') as f:
f.write("regtest=1\n");
f.write("rpcuser=rt\n");
f.write("rpcpassword=rt\n");
f.write("port="+str(p2p_port(n))+"\n");
f.write("rpcport="+str(rpc_port(n))+"\n");
return datadir
def initialize_chain(test_dir): def initialize_chain(test_dir):
""" """
Create (or copy from cache) a 200-block-long chain and Create (or copy from cache) a 200-block-long chain and
@ -68,17 +84,10 @@ def initialize_chain(test_dir):
devnull = open("/dev/null", "w+") devnull = open("/dev/null", "w+")
# Create cache directories, run bitcoinds: # Create cache directories, run bitcoinds:
for i in range(4): for i in range(4):
datadir = os.path.join("cache", "node"+str(i)) datadir=initialize_datadir("cache", i)
os.makedirs(datadir)
with open(os.path.join(datadir, "bitcoin.conf"), 'w') as f:
f.write("regtest=1\n");
f.write("rpcuser=rt\n");
f.write("rpcpassword=rt\n");
f.write("port="+str(START_P2P_PORT+i)+"\n");
f.write("rpcport="+str(START_RPC_PORT+i)+"\n");
args = [ "bitcoind", "-keypool=1", "-datadir="+datadir ] args = [ "bitcoind", "-keypool=1", "-datadir="+datadir ]
if i > 0: if i > 0:
args.append("-connect=127.0.0.1:"+str(START_P2P_PORT)) args.append("-connect=127.0.0.1:"+str(p2p_port(0)))
bitcoind_processes.append(subprocess.Popen(args)) bitcoind_processes.append(subprocess.Popen(args))
subprocess.check_call([ "bitcoin-cli", "-datadir="+datadir, subprocess.check_call([ "bitcoin-cli", "-datadir="+datadir,
"-rpcwait", "getblockcount"], stdout=devnull) "-rpcwait", "getblockcount"], stdout=devnull)
@ -86,7 +95,7 @@ def initialize_chain(test_dir):
rpcs = [] rpcs = []
for i in range(4): for i in range(4):
try: try:
url = "http://rt:rt@127.0.0.1:%d"%(START_RPC_PORT+i,) url = "http://rt:rt@127.0.0.1:%d"%(rpc_port(i),)
rpcs.append(AuthServiceProxy(url)) rpcs.append(AuthServiceProxy(url))
except: except:
sys.stderr.write("Error connecting to "+url+"\n") sys.stderr.write("Error connecting to "+url+"\n")
@ -111,23 +120,50 @@ def initialize_chain(test_dir):
from_dir = os.path.join("cache", "node"+str(i)) from_dir = os.path.join("cache", "node"+str(i))
to_dir = os.path.join(test_dir, "node"+str(i)) to_dir = os.path.join(test_dir, "node"+str(i))
shutil.copytree(from_dir, to_dir) shutil.copytree(from_dir, to_dir)
initialize_datadir(test_dir, i) # Overwrite port/rpcport in bitcoin.conf
def start_nodes(num_nodes, dir): def _rpchost_to_args(rpchost):
# Start bitcoinds, and wait for RPC interface to be up and running: '''Convert optional IP:port spec to rpcconnect/rpcport args'''
devnull = open("/dev/null", "w+") if rpchost is None:
for i in range(num_nodes): return []
match = re.match('(\[[0-9a-fA-f:]+\]|[^:]+)(?::([0-9]+))?$', rpchost)
if not match:
raise ValueError('Invalid RPC host spec ' + rpchost)
rpcconnect = match.group(1)
rpcport = match.group(2)
if rpcconnect.startswith('['): # remove IPv6 [...] wrapping
rpcconnect = rpcconnect[1:-1]
rv = ['-rpcconnect=' + rpcconnect]
if rpcport:
rv += ['-rpcport=' + rpcport]
return rv
def start_node(i, dir, extra_args=None, rpchost=None):
"""
Start a bitcoind and return RPC connection to it
"""
datadir = os.path.join(dir, "node"+str(i)) datadir = os.path.join(dir, "node"+str(i))
args = [ "bitcoind", "-datadir="+datadir ] args = [ "bitcoind", "-datadir="+datadir, "-keypool=1" ]
if extra_args is not None: args.extend(extra_args)
bitcoind_processes.append(subprocess.Popen(args)) bitcoind_processes.append(subprocess.Popen(args))
subprocess.check_call([ "bitcoin-cli", "-datadir="+datadir, devnull = open("/dev/null", "w+")
"-rpcwait", "getblockcount"], stdout=devnull) subprocess.check_call([ "bitcoin-cli", "-datadir="+datadir] +
_rpchost_to_args(rpchost) +
["-rpcwait", "getblockcount"], stdout=devnull)
devnull.close() devnull.close()
# Create&return JSON-RPC connections url = "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i))
rpc_connections = [] return AuthServiceProxy(url)
for i in range(num_nodes):
url = "http://rt:rt@127.0.0.1:%d"%(START_RPC_PORT+i,) def start_nodes(num_nodes, dir, extra_args=None, rpchost=None):
rpc_connections.append(AuthServiceProxy(url)) """
return rpc_connections Start multiple bitcoinds, return RPC connections to them
"""
if extra_args is None: extra_args = [ None for i in range(num_nodes) ]
return [ start_node(i, dir, extra_args[i], rpchost) for i in range(num_nodes) ]
def debug_log(dir, n_node): def debug_log(dir, n_node):
return os.path.join(dir, "node"+str(n_node), "regtest", "debug.log") return os.path.join(dir, "node"+str(n_node), "regtest", "debug.log")
@ -144,8 +180,114 @@ def wait_bitcoinds():
del bitcoind_processes[:] del bitcoind_processes[:]
def connect_nodes(from_connection, node_num): def connect_nodes(from_connection, node_num):
ip_port = "127.0.0.1:"+str(START_P2P_PORT+node_num) ip_port = "127.0.0.1:"+str(p2p_port(node_num))
from_connection.addnode(ip_port, "onetry") from_connection.addnode(ip_port, "onetry")
# poll until version handshake complete to avoid race conditions
# with transaction relaying
while any(peer['version'] == 0 for peer in from_connection.getpeerinfo()):
time.sleep(0.1)
def find_output(node, txid, amount):
"""
Return index to output of txid with value amount
Raises exception if there is none.
"""
txdata = node.getrawtransaction(txid, 1)
for i in range(len(txdata["vout"])):
if txdata["vout"][i]["value"] == amount:
return i
raise RuntimeError("find_output txid %s : %s not found"%(txid,str(amount)))
def gather_inputs(from_node, amount_needed):
"""
Return a random set of unspent txouts that are enough to pay amount_needed
"""
utxo = from_node.listunspent(1)
random.shuffle(utxo)
inputs = []
total_in = Decimal("0.00000000")
while total_in < amount_needed and len(utxo) > 0:
t = utxo.pop()
total_in += t["amount"]
inputs.append({ "txid" : t["txid"], "vout" : t["vout"], "address" : t["address"] } )
if total_in < amount_needed:
raise RuntimeError("Insufficient funds: need %d, have %d"%(amount+fee*2, total_in))
return (total_in, inputs)
def make_change(from_node, amount_in, amount_out, fee):
"""
Create change output(s), return them
"""
outputs = {}
amount = amount_out+fee
change = amount_in - amount
if change > amount*2:
# Create an extra change output to break up big inputs
outputs[from_node.getnewaddress()] = float(change/2)
change = change/2
if change > 0:
outputs[from_node.getnewaddress()] = float(change)
return outputs
def send_zeropri_transaction(from_node, to_node, amount, fee):
"""
Create&broadcast a zero-priority transaction.
Returns (txid, hex-encoded-txdata)
Ensures transaction is zero-priority by first creating a send-to-self,
then using it's output
"""
# Create a send-to-self with confirmed inputs:
self_address = from_node.getnewaddress()
(total_in, inputs) = gather_inputs(from_node, amount+fee*2)
outputs = make_change(from_node, total_in, amount+fee, fee)
outputs[self_address] = float(amount+fee)
self_rawtx = from_node.createrawtransaction(inputs, outputs)
self_signresult = from_node.signrawtransaction(self_rawtx)
self_txid = from_node.sendrawtransaction(self_signresult["hex"], True)
vout = find_output(from_node, self_txid, amount+fee)
# Now immediately spend the output to create a 1-input, 1-output
# zero-priority transaction:
inputs = [ { "txid" : self_txid, "vout" : vout } ]
outputs = { to_node.getnewaddress() : float(amount) }
rawtx = from_node.createrawtransaction(inputs, outputs)
signresult = from_node.signrawtransaction(rawtx)
txid = from_node.sendrawtransaction(signresult["hex"], True)
return (txid, signresult["hex"])
def random_zeropri_transaction(nodes, amount, min_fee, fee_increment, fee_variants):
"""
Create a random zero-priority transaction.
Returns (txid, hex-encoded-transaction-data, fee)
"""
from_node = random.choice(nodes)
to_node = random.choice(nodes)
fee = min_fee + fee_increment*random.randint(0,fee_variants)
(txid, txhex) = send_zeropri_transaction(from_node, to_node, amount, fee)
return (txid, txhex, fee)
def random_transaction(nodes, amount, min_fee, fee_increment, fee_variants):
"""
Create a random transaction.
Returns (txid, hex-encoded-transaction-data, fee)
"""
from_node = random.choice(nodes)
to_node = random.choice(nodes)
fee = min_fee + fee_increment*random.randint(0,fee_variants)
(total_in, inputs) = gather_inputs(from_node, amount+fee)
outputs = make_change(from_node, total_in, amount, fee)
outputs[to_node.getnewaddress()] = float(amount)
rawtx = from_node.createrawtransaction(inputs, outputs)
signresult = from_node.signrawtransaction(rawtx)
txid = from_node.sendrawtransaction(signresult["hex"], True)
return (txid, signresult["hex"], fee)
def assert_equal(thing1, thing2): def assert_equal(thing1, thing2):
if thing1 != thing2: if thing1 != thing2:

View file

@ -38,6 +38,10 @@ function AssertEqual {
if (( $( echo "$1 == $2" | bc ) == 0 )) if (( $( echo "$1 == $2" | bc ) == 0 ))
then then
echoerr "AssertEqual: $1 != $2" echoerr "AssertEqual: $1 != $2"
declare -f CleanUp > /dev/null 2>&1
if [[ $? -eq 0 ]] ; then
CleanUp
fi
exit 1 exit 1
fi fi
} }
@ -49,6 +53,10 @@ function CheckBalance {
if (( $( echo "$B == $EXPECT" | bc ) == 0 )) if (( $( echo "$B == $EXPECT" | bc ) == 0 ))
then then
echoerr "bad balance: $B (expected $2)" echoerr "bad balance: $B (expected $2)"
declare -f CleanUp > /dev/null 2>&1
if [[ $? -eq 0 ]] ; then
CleanUp
fi
exit 1 exit 1
fi fi
} }

161
qa/rpc-tests/zapwallettxes.sh Executable file
View file

@ -0,0 +1,161 @@
#!/usr/bin/env bash
# Test -zapwallettxes=<mode>
if [ $# -lt 1 ]; then
echo "Usage: $0 path_to_binaries"
echo "e.g. $0 ../../src"
exit 1
fi
set -f
BITCOIND=${1}/bitcoind
CLI=${1}/bitcoin-cli
DIR="${BASH_SOURCE%/*}"
SENDANDWAIT="${DIR}/send.sh"
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
. "$DIR/util.sh"
D=$(mktemp -d test.XXXXX)
D1=${D}/node1
CreateDataDir "$D1" port=11000 rpcport=11001
B1ARGS="-datadir=$D1"
$BITCOIND $B1ARGS &
B1PID=$!
D2=${D}/node2
CreateDataDir "$D2" port=11010 rpcport=11011
B2ARGS="-datadir=$D2"
$BITCOIND $B2ARGS &
B2PID=$!
function CleanUp {
$CLI $B2ARGS stop > /dev/null 2>&1
wait $B2PID
$CLI $B1ARGS stop > /dev/null 2>&1
wait $B1PID
rm -rf $D
}
# 110 blocks, 10 mature == 500 XBT
$CLI $B1ARGS setgenerate true 110
$CLI $B2ARGS setgenerate true 110
CheckBalance "$B1ARGS" 500
CheckBalance "$B2ARGS" 500
# Send 10 XBT
TXID1_DEFAULT=$($CLI $B1ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 10)
TXID2_DEFAULT=$($CLI $B2ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 10)
CheckBalance $B1ARGS 490
CheckBalance $B2ARGS 490
# Move 10 XBT to testaccount
TMP=$($CLI $B1ARGS move "" "testaccount" 10)
TMP=$($CLI $B2ARGS move "" "testaccount" 10)
CheckBalance $B1ARGS 10 "testaccount"
CheckBalance $B2ARGS 10 "testaccount"
# Send 1 XBT from testaccount
TXID1_TESTACCOUNT=$($CLI $B1ARGS sendfrom "testaccount" "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
TXID2_TESTACCOUNT=$($CLI $B2ARGS sendfrom "testaccount" "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
CheckBalance $B1ARGS 9 "testaccount"
CheckBalance $B2ARGS 9 "testaccount"
CheckBalance $B1ARGS 489
CheckBalance $B2ARGS 489
# Confirm transactions
$CLI $B1ARGS setgenerate true 1
$CLI $B2ARGS setgenerate true 1
# Create unconfirmed transaction
TXID1_UNCONFIRMED=$($CLI $B1ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
TXID2_UNCONFIRMED=$($CLI $B2ARGS sendtoaddress "mrhz5ZgSF3C1BSdyCKt3gEdhKoRL5BNfJV" 1)
# check balance (we created another 50 and spent 1 in the meantime)
CheckBalance $B1ARGS 538
CheckBalance $B2ARGS 538
# Safety check, if unconfirmed transactions are there
$CLI $B1ARGS gettransaction $TXID1_UNCONFIRMED > /dev/null 2>&1
if [[ $? -ne 0 ]] ; then
echoerr "gettransaction1_1: $TXID1_UNCONFIRMED failed"
CleanUp
exit 1
fi
$CLI $B2ARGS gettransaction $TXID2_UNCONFIRMED > /dev/null 2>&1
if [[ $? -ne 0 ]] ; then
echoerr "gettransaction2_1: $TXID2_UNCONFIRMED failed"
CleanUp
exit 1
fi
# stop nodes
$CLI $B2ARGS stop > /dev/null 2>&1
wait $B2PID
$CLI $B1ARGS stop > /dev/null 2>&1
wait $B1PID
# restart nodes with -zapwallettxes
$BITCOIND -zapwallettxes=1 $B1ARGS &
B1PID=$!
$BITCOIND -zapwallettxes=2 $B2ARGS &
B2PID=$!
# check if confirmed transactions are there
$CLI $B1ARGS gettransaction $TXID1_DEFAULT > /dev/null 2>&1
if [[ $? -ne 0 ]] ; then
echoerr "check confirmed transaction 1: $TXID1_DEFAULT failed"
CleanUp
exit 1
fi
$CLI $B2ARGS gettransaction $TXID2_DEFAULT > /dev/null 2>&1
if [[ $? -ne 0 ]] ; then
echoerr "check confirmed transaction 2: $TXID2_DEFAULT failed"
CleanUp
exit 1
fi
$CLI $B1ARGS gettransaction $TXID1_TESTACCOUNT > /dev/null 2>&1
if [[ $? -ne 0 ]] ; then
echoerr "check confirmed transaction 3: $TXID1_TESTACCOUNT failed"
CleanUp
exit 1
fi
$CLI $B2ARGS gettransaction $TXID2_TESTACCOUNT > /dev/null 2>&1
if [[ $? -ne 0 ]] ; then
echoerr "check confirmed transaction 4: $TXID2_TESTACCOUNT failed"
CleanUp
exit 1
fi
# check if unconfirmed transaction is gone
$CLI $B1ARGS gettransaction $TXID1_UNCONFIRMED > /dev/null 2>&1
if [[ $? -eq 0 ]] ; then
echoerr "check unconfirmed transaction 1: $TXID1_UNCONFIRMED failed"
CleanUp
exit 1
fi
$CLI $B2ARGS gettransaction $TXID2_UNCONFIRMED > /dev/null 2>&1
if [[ $? -eq 0 ]] ; then
echoerr "check unconfirmed transaction 2: $TXID2_UNCONFIRMED failed"
CleanUp
exit 1
fi
# check zapwallet mode 1, testaccount balance must be 9 (keeping transaction metadata)
CheckBalance $B1ARGS 9 "testaccount"
# check zapwallet mode 2, testaccount balance must be 10 (dropping transaction metadata)
CheckBalance $B2ARGS 10 "testaccount"
echo "Tests successful, cleaning up"
CleanUp
exit 0

View file

@ -16,7 +16,7 @@ fi
DESC="" DESC=""
SUFFIX="" SUFFIX=""
LAST_COMMIT_DATE="" LAST_COMMIT_DATE=""
if [ -e "$(which git)" -a -d ".git" ]; then if [ -e "$(which git 2>/dev/null)" -a -d ".git" ]; then
# clean 'dirty' status of touched files that haven't been modified # clean 'dirty' status of touched files that haven't been modified
git diff >/dev/null 2>/dev/null git diff >/dev/null 2>/dev/null

View file

@ -7,8 +7,9 @@ from subprocess import Popen, PIPE
import glob import glob
import operator import operator
import os import os
import sys
OUT_CPP="src/qt/bitcoinstrings.cpp" OUT_CPP="qt/bitcoinstrings.cpp"
EMPTY=['""'] EMPTY=['""']
def parse_po(text): def parse_po(text):
@ -47,7 +48,7 @@ def parse_po(text):
return messages return messages
files = glob.glob('src/*.cpp') + glob.glob('src/*.h') files = sys.argv[1:]
# xgettext -n --keyword=_ $FILES # xgettext -n --keyword=_ $FILES
XGETTEXT=os.getenv('XGETTEXT', 'xgettext') XGETTEXT=os.getenv('XGETTEXT', 'xgettext')

View file

@ -1,16 +1,54 @@
include Makefile.include AM_CPPFLAGS = $(INCLUDES)
AM_LDFLAGS = $(PTHREAD_CFLAGS)
AM_CPPFLAGS += -I$(builddir) if USE_LIBSECP256K1
secp256k1/libsecp256k1.la: $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*)
@$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
endif
if EMBEDDED_LEVELDB
LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include
LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/helpers/memenv
LIBLEVELDB += $(builddir)/leveldb/libleveldb.a
LIBMEMENV += $(builddir)/leveldb/libmemenv.a
# NOTE: This dependency is not strictly necessary, but without it make may try to build both in parallel, which breaks the LevelDB build system in a race
$(LIBLEVELDB): $(LIBMEMENV)
$(LIBLEVELDB) $(LIBMEMENV):
@echo "Building LevelDB ..." && $(MAKE) -C $(@D) $(@F) CXX="$(CXX)" \
CC="$(CC)" PLATFORM=$(TARGET_OS) AR="$(AR)" $(LEVELDB_TARGET_FLAGS) \
OPT="$(CXXFLAGS) $(CPPFLAGS)"
endif
BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config
BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS)
if USE_LIBSECP256K1
BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include
endif
LIBBITCOIN_SERVER=libbitcoin_server.a
LIBBITCOIN_WALLET=libbitcoin_wallet.a
LIBBITCOIN_COMMON=libbitcoin_common.a
LIBBITCOIN_CLI=libbitcoin_cli.a
LIBBITCOIN_UTIL=libbitcoin_util.a
LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
LIBBITCOINQT=qt/libbitcoinqt.a
noinst_LIBRARIES = \ noinst_LIBRARIES = \
libbitcoin_server.a \ libbitcoin_server.a \
libbitcoin_common.a \ libbitcoin_common.a \
libbitcoin_cli.a libbitcoin_cli.a \
libbitcoin_util.a \
crypto/libbitcoin_crypto.a
if ENABLE_WALLET if ENABLE_WALLET
BITCOIN_INCLUDES += $(BDB_CPPFLAGS)
noinst_LIBRARIES += libbitcoin_wallet.a noinst_LIBRARIES += libbitcoin_wallet.a
endif endif
bin_PROGRAMS = bin_PROGRAMS =
TESTS =
if BUILD_BITCOIND if BUILD_BITCOIND
bin_PROGRAMS += bitcoind bin_PROGRAMS += bitcoind
@ -20,17 +58,16 @@ if BUILD_BITCOIN_CLI
bin_PROGRAMS += bitcoin-cli bin_PROGRAMS += bitcoin-cli
endif endif
SUBDIRS = . $(BUILD_QT) $(BUILD_TEST)
DIST_SUBDIRS = . qt test
.PHONY: FORCE .PHONY: FORCE
# bitcoin core # # bitcoin core #
BITCOIN_CORE_H = \ BITCOIN_CORE_H = \
addrman.h \ addrman.h \
alert.h \ alert.h \
allocators.h \ allocators.h \
base58.h bignum.h \ base58.h \
bloom.h \ bloom.h \
chainparams.h \ chainparams.h \
chainparamsbase.h \
checkpoints.h \ checkpoints.h \
checkqueue.h \ checkqueue.h \
clientversion.h \ clientversion.h \
@ -52,6 +89,7 @@ BITCOIN_CORE_H = \
netbase.h \ netbase.h \
net.h \ net.h \
noui.h \ noui.h \
pow.h \
protocol.h \ protocol.h \
rpcclient.h \ rpcclient.h \
rpcprotocol.h \ rpcprotocol.h \
@ -60,6 +98,7 @@ BITCOIN_CORE_H = \
serialize.h \ serialize.h \
sync.h \ sync.h \
threadsafety.h \ threadsafety.h \
timedata.h \
tinyformat.h \ tinyformat.h \
txdb.h \ txdb.h \
txmempool.h \ txmempool.h \
@ -68,7 +107,8 @@ BITCOIN_CORE_H = \
util.h \ util.h \
version.h \ version.h \
walletdb.h \ walletdb.h \
wallet.h wallet.h \
compat/sanity.h
JSON_H = \ JSON_H = \
json/json_spirit.h \ json/json_spirit.h \
@ -82,35 +122,40 @@ JSON_H = \
json/json_spirit_writer_template.h json/json_spirit_writer_template.h
obj/build.h: FORCE obj/build.h: FORCE
@$(MKDIR_P) $(abs_top_builddir)/src/obj @$(MKDIR_P) $(builddir)/obj
@$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \ @$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \
$(abs_top_srcdir) $(abs_top_srcdir)
version.o: obj/build.h libbitcoin_util_a-version.$(OBJEXT): obj/build.h
# server: shared between bitcoind and bitcoin-qt
libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_server_a_SOURCES = \ libbitcoin_server_a_SOURCES = \
addrman.cpp \ addrman.cpp \
alert.cpp \ alert.cpp \
bloom.cpp \ bloom.cpp \
checkpoints.cpp \ checkpoints.cpp \
coins.cpp \
init.cpp \ init.cpp \
keystore.cpp \
leveldbwrapper.cpp \ leveldbwrapper.cpp \
main.cpp \ main.cpp \
miner.cpp \ miner.cpp \
net.cpp \ net.cpp \
noui.cpp \ noui.cpp \
pow.cpp \
rpcblockchain.cpp \ rpcblockchain.cpp \
rpcmining.cpp \ rpcmining.cpp \
rpcmisc.cpp \ rpcmisc.cpp \
rpcnet.cpp \ rpcnet.cpp \
rpcrawtransaction.cpp \ rpcrawtransaction.cpp \
rpcserver.cpp \ rpcserver.cpp \
timedata.cpp \
txdb.cpp \ txdb.cpp \
txmempool.cpp \ txmempool.cpp \
$(JSON_H) \ $(JSON_H) \
$(BITCOIN_CORE_H) $(BITCOIN_CORE_H)
# wallet: shared between bitcoind and bitcoin-qt, but only linked
# when wallet enabled
libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_wallet_a_SOURCES = \ libbitcoin_wallet_a_SOURCES = \
db.cpp \ db.cpp \
crypter.cpp \ crypter.cpp \
@ -120,41 +165,74 @@ libbitcoin_wallet_a_SOURCES = \
walletdb.cpp \ walletdb.cpp \
$(BITCOIN_CORE_H) $(BITCOIN_CORE_H)
# crypto primitives library
crypto_libbitcoin_crypto_a_CPPFLAGS = $(BITCOIN_CONFIG_INCLUDES)
crypto_libbitcoin_crypto_a_SOURCES = \
crypto/sha1.cpp \
crypto/sha2.cpp \
crypto/ripemd160.cpp \
crypto/common.h \
crypto/sha2.h \
crypto/sha1.h \
crypto/ripemd160.h
# common: shared between bitcoind, and bitcoin-qt and non-server tools
libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_common_a_SOURCES = \ libbitcoin_common_a_SOURCES = \
base58.cpp \
allocators.cpp \ allocators.cpp \
base58.cpp \
chainparams.cpp \ chainparams.cpp \
coins.cpp \
core.cpp \ core.cpp \
hash.cpp \ hash.cpp \
key.cpp \ key.cpp \
keystore.cpp \
netbase.cpp \ netbase.cpp \
protocol.cpp \ protocol.cpp \
rpcprotocol.cpp \
script.cpp \ script.cpp \
$(BITCOIN_CORE_H)
# util: shared between all executables.
# This library *must* be included to make sure that the glibc
# backward-compatibility objects and their sanity checks are linked.
libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES)
libbitcoin_util_a_SOURCES = \
chainparamsbase.cpp \
rpcprotocol.cpp \
sync.cpp \ sync.cpp \
uint256.cpp \
util.cpp \ util.cpp \
version.cpp \ version.cpp \
compat/glibc_sanity.cpp \
compat/glibcxx_sanity.cpp \
$(BITCOIN_CORE_H) $(BITCOIN_CORE_H)
if GLIBC_BACK_COMPAT if GLIBC_BACK_COMPAT
libbitcoin_common_a_SOURCES += compat/glibc_compat.cpp libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
libbitcoin_common_a_SOURCES += compat/glibcxx_compat.cpp libbitcoin_util_a_SOURCES += compat/glibcxx_compat.cpp
endif endif
# cli: shared between bitcoin-cli and bitcoin-qt
libbitcoin_cli_a_SOURCES = \ libbitcoin_cli_a_SOURCES = \
rpcclient.cpp \ rpcclient.cpp \
$(BITCOIN_CORE_H) $(BITCOIN_CORE_H)
nodist_libbitcoin_common_a_SOURCES = $(top_srcdir)/src/obj/build.h nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h
# #
# bitcoind binary # # bitcoind binary #
bitcoind_LDADD = \ bitcoind_LDADD = \
libbitcoin_server.a \ $(LIBBITCOIN_SERVER) \
libbitcoin_cli.a \ $(LIBBITCOIN_COMMON) \
libbitcoin_common.a \ $(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO) \
$(LIBLEVELDB) \ $(LIBLEVELDB) \
$(LIBMEMENV) $(LIBMEMENV)
if USE_LIBSECP256K1
bitcoind_LDADD += secp256k1/libsecp256k1.la
endif
if ENABLE_WALLET if ENABLE_WALLET
bitcoind_LDADD += libbitcoin_wallet.a bitcoind_LDADD += libbitcoin_wallet.a
endif endif
@ -165,39 +243,61 @@ if TARGET_WINDOWS
bitcoind_SOURCES += bitcoind-res.rc bitcoind_SOURCES += bitcoind-res.rc
endif endif
AM_CPPFLAGS += $(BDB_CPPFLAGS)
bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS)
bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES)
# bitcoin-cli binary # # bitcoin-cli binary #
bitcoin_cli_LDADD = \ bitcoin_cli_LDADD = \
libbitcoin_cli.a \ $(LIBBITCOIN_CLI) \
libbitcoin_common.a \ $(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO) \
$(BOOST_LIBS) $(BOOST_LIBS)
bitcoin_cli_SOURCES = bitcoin-cli.cpp bitcoin_cli_SOURCES = \
bitcoin-cli.cpp
if USE_LIBSECP256K1
bitcoin_cli_LDADD += secp256k1/libsecp256k1.la
endif
bitcoin_cli_CPPFLAGS = $(BITCOIN_INCLUDES)
# #
if TARGET_WINDOWS if TARGET_WINDOWS
bitcoin_cli_SOURCES += bitcoin-cli-res.rc bitcoin_cli_SOURCES += bitcoin-cli-res.rc
endif endif
# NOTE: This dependency is not strictly necessary, but without it make may try to build both in parallel, which breaks the LevelDB build system in a race
leveldb/libleveldb.a: leveldb/libmemenv.a
leveldb/%.a:
@echo "Building LevelDB ..." && $(MAKE) -C $(@D) $(@F) CXX="$(CXX)" \
CC="$(CC)" PLATFORM=$(TARGET_OS) AR="$(AR)" $(LEVELDB_TARGET_FLAGS) \
OPT="$(CXXFLAGS) $(CPPFLAGS)"
qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_common_a_SOURCES) $(libbitcoin_cli_a_SOURCES)
@test -n $(XGETTEXT) || echo "xgettext is required for updating translations"
@cd $(top_srcdir); XGETTEXT=$(XGETTEXT) share/qt/extract_strings_qt.py
CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno
DISTCLEANFILES = obj/build.h DISTCLEANFILES = obj/build.h
EXTRA_DIST = leveldb Makefile.include EXTRA_DIST = leveldb secp256k1
clean-local: clean-local:
-$(MAKE) -C leveldb clean -$(MAKE) -C leveldb clean
-$(MAKE) -C secp256k1 clean
rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno
-rm -f config.h
.rc.o:
@test -f $(WINDRES)
$(AM_V_GEN) $(WINDRES) -i $< -o $@
.mm.o:
$(AM_V_CXX) $(OBJCXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CXXFLAGS) $(QT_INCLUDES) $(CXXFLAGS) -c -o $@ $<
%.pb.cc %.pb.h: %.proto
@test -f $(PROTOC)
$(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$(abspath $(<D) $<)
if ENABLE_TESTS
include Makefile.test.include
endif
if ENABLE_QT
include Makefile.qt.include
endif
if ENABLE_QT_TESTS
include Makefile.qttest.include
endif

View file

@ -1,79 +0,0 @@
if EMBEDDED_LEVELDB
LEVELDB_CPPFLAGS += -I$(top_srcdir)/src/leveldb/include
LEVELDB_CPPFLAGS += -I$(top_srcdir)/src/leveldb/helpers/memenv
LIBLEVELDB += $(top_builddir)/src/leveldb/libleveldb.a
LIBMEMENV += $(top_builddir)/src/leveldb/libmemenv.a
endif
AM_CPPFLAGS = $(INCLUDES) \
-I$(top_builddir)/src/obj \
$(BDB_CPPFLAGS) \
$(BOOST_CPPFLAGS) $(BOOST_INCLUDES)
AM_CPPFLAGS += $(LEVELDB_CPPFLAGS)
AM_LDFLAGS = $(PTHREAD_CFLAGS)
LIBBITCOIN_SERVER=$(top_builddir)/src/libbitcoin_server.a
LIBBITCOIN_WALLET=$(top_builddir)/src/libbitcoin_wallet.a
LIBBITCOIN_COMMON=$(top_builddir)/src/libbitcoin_common.a
LIBBITCOIN_CLI=$(top_builddir)/src/libbitcoin_cli.a
LIBBITCOINQT=$(top_builddir)/src/qt/libbitcoinqt.a
$(LIBBITCOIN):
$(MAKE) -C $(top_builddir)/src $(@F)
if EMBEDDED_LEVELDB
$(LIBLEVELDB) $(LIBMEMENV):
$(MAKE) -C $(top_builddir)/src leveldb/$(@F)
endif
$(LIBBITCOINQT):
$(MAKE) -C $(top_builddir)/src/qt $(@F)
.mm.o:
$(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CXXFLAGS) $(QT_INCLUDES) $(CXXFLAGS) -c -o $@ $<
.rc.o:
@test -f $(WINDRES) && $(WINDRES) -i $< -o $@ || \
echo error: could not build $@
ui_%.h: %.ui
@test -d $(abs_builddir)/$(@D) || $(MKDIR_P) $(abs_builddir)/$(@D)
@test -f $(UIC) && QT_SELECT=$(QT_SELECT) $(UIC) -o $(abs_builddir)/$@ $(abs_srcdir)/$< || echo error: could not build $(abs_builddir)/$@
$(SED) -e '/^\*\*.*Created:/d' $(abs_builddir)/$@ > $(abs_builddir)/$@.n && mv $(abs_builddir)/$@{.n,}
$(SED) -e '/^\*\*.*by:/d' $(abs_builddir)/$@ > $(abs_builddir)/$@.n && mv $(abs_builddir)/$@{.n,}
%.moc: %.cpp
QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) -o $@ $<
$(SED) -e '/^\*\*.*Created:/d' $@ > $@.n && mv $@{.n,}
$(SED) -e '/^\*\*.*by:/d' $@ > $@.n && mv $@{.n,}
moc_%.cpp: %.h
QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) -o $@ $<
$(SED) -e '/^\*\*.*Created:/d' $@ > $@.n && mv $@{.n,}
$(SED) -e '/^\*\*.*by:/d' $@ > $@.n && mv $@{.n,}
%.qm: %.ts
@test -d $(abs_builddir)/$(@D) || $(MKDIR_P) $(abs_builddir)/$(@D)
@test -f $(LRELEASE) && QT_SELECT=$(QT_SELECT) $(LRELEASE) $(abs_srcdir)/$< -qm $(abs_builddir)/$@ || \
echo error: could not build $(abs_builddir)/$@
%.pb.cc %.pb.h: %.proto
test -f $(PROTOC) && $(PROTOC) --cpp_out=$(@D) --proto_path=$(abspath $(<D) $<) || \
echo error: could not build $@
%.json.h: %.json
@$(MKDIR_P) $(@D)
@echo "namespace json_tests{" > $@
@echo "static unsigned const char $(*F)[] = {" >> $@
@$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' >> $@
@echo "};};" >> $@
@echo "Generated $@"
%.raw.h: %.raw
@$(MKDIR_P) $(@D)
@echo "namespace alert_tests{" > $@
@echo "static unsigned const char $(*F)[] = {" >> $@
@$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' >> $@
@echo "};};" >> $@
@echo "Generated $@"

417
src/Makefile.qt.include Normal file
View file

@ -0,0 +1,417 @@
bin_PROGRAMS += qt/bitcoin-qt
noinst_LIBRARIES += qt/libbitcoinqt.a
# bitcoin qt core #
QT_TS = \
qt/locale/bitcoin_ach.ts \
qt/locale/bitcoin_af_ZA.ts \
qt/locale/bitcoin_ar.ts \
qt/locale/bitcoin_be_BY.ts \
qt/locale/bitcoin_bg.ts \
qt/locale/bitcoin_bs.ts \
qt/locale/bitcoin_ca_ES.ts \
qt/locale/bitcoin_ca.ts \
qt/locale/bitcoin_ca@valencia.ts \
qt/locale/bitcoin_cmn.ts \
qt/locale/bitcoin_cs.ts \
qt/locale/bitcoin_cy.ts \
qt/locale/bitcoin_da.ts \
qt/locale/bitcoin_de.ts \
qt/locale/bitcoin_el_GR.ts \
qt/locale/bitcoin_en.ts \
qt/locale/bitcoin_eo.ts \
qt/locale/bitcoin_es_CL.ts \
qt/locale/bitcoin_es_DO.ts \
qt/locale/bitcoin_es_MX.ts \
qt/locale/bitcoin_es.ts \
qt/locale/bitcoin_es_UY.ts \
qt/locale/bitcoin_et.ts \
qt/locale/bitcoin_eu_ES.ts \
qt/locale/bitcoin_fa_IR.ts \
qt/locale/bitcoin_fa.ts \
qt/locale/bitcoin_fi.ts \
qt/locale/bitcoin_fr_CA.ts \
qt/locale/bitcoin_fr.ts \
qt/locale/bitcoin_gl.ts \
qt/locale/bitcoin_gu_IN.ts \
qt/locale/bitcoin_he.ts \
qt/locale/bitcoin_hi_IN.ts \
qt/locale/bitcoin_hr.ts \
qt/locale/bitcoin_hu.ts \
qt/locale/bitcoin_id_ID.ts \
qt/locale/bitcoin_it.ts \
qt/locale/bitcoin_ja.ts \
qt/locale/bitcoin_ka.ts \
qt/locale/bitcoin_kk_KZ.ts \
qt/locale/bitcoin_ko_KR.ts \
qt/locale/bitcoin_ky.ts \
qt/locale/bitcoin_la.ts \
qt/locale/bitcoin_lt.ts \
qt/locale/bitcoin_lv_LV.ts \
qt/locale/bitcoin_mn.ts \
qt/locale/bitcoin_ms_MY.ts \
qt/locale/bitcoin_nb.ts \
qt/locale/bitcoin_nl.ts \
qt/locale/bitcoin_pam.ts \
qt/locale/bitcoin_pl.ts \
qt/locale/bitcoin_pt_BR.ts \
qt/locale/bitcoin_pt_PT.ts \
qt/locale/bitcoin_ro_RO.ts \
qt/locale/bitcoin_ru.ts \
qt/locale/bitcoin_sah.ts \
qt/locale/bitcoin_sk.ts \
qt/locale/bitcoin_sl_SI.ts \
qt/locale/bitcoin_sq.ts \
qt/locale/bitcoin_sr.ts \
qt/locale/bitcoin_sv.ts \
qt/locale/bitcoin_th_TH.ts \
qt/locale/bitcoin_tr.ts \
qt/locale/bitcoin_uk.ts \
qt/locale/bitcoin_ur_PK.ts \
qt/locale/bitcoin_uz@Cyrl.ts \
qt/locale/bitcoin_vi.ts \
qt/locale/bitcoin_vi_VN.ts \
qt/locale/bitcoin_zh_CN.ts \
qt/locale/bitcoin_zh_HK.ts \
qt/locale/bitcoin_zh_TW.ts
QT_FORMS_UI = \
qt/forms/addressbookpage.ui \
qt/forms/askpassphrasedialog.ui \
qt/forms/coincontroldialog.ui \
qt/forms/editaddressdialog.ui \
qt/forms/helpmessagedialog.ui \
qt/forms/intro.ui \
qt/forms/openuridialog.ui \
qt/forms/optionsdialog.ui \
qt/forms/overviewpage.ui \
qt/forms/receivecoinsdialog.ui \
qt/forms/receiverequestdialog.ui \
qt/forms/rpcconsole.ui \
qt/forms/sendcoinsdialog.ui \
qt/forms/sendcoinsentry.ui \
qt/forms/signverifymessagedialog.ui \
qt/forms/transactiondescdialog.ui
QT_MOC_CPP = \
qt/moc_addressbookpage.cpp \
qt/moc_addresstablemodel.cpp \
qt/moc_askpassphrasedialog.cpp \
qt/moc_bitcoinaddressvalidator.cpp \
qt/moc_bitcoinamountfield.cpp \
qt/moc_bitcoingui.cpp \
qt/moc_bitcoinunits.cpp \
qt/moc_clientmodel.cpp \
qt/moc_coincontroldialog.cpp \
qt/moc_coincontroltreewidget.cpp \
qt/moc_csvmodelwriter.cpp \
qt/moc_editaddressdialog.cpp \
qt/moc_guiutil.cpp \
qt/moc_intro.cpp \
qt/moc_macdockiconhandler.cpp \
qt/moc_macnotificationhandler.cpp \
qt/moc_monitoreddatamapper.cpp \
qt/moc_notificator.cpp \
qt/moc_openuridialog.cpp \
qt/moc_optionsdialog.cpp \
qt/moc_optionsmodel.cpp \
qt/moc_overviewpage.cpp \
qt/moc_peertablemodel.cpp \
qt/moc_paymentserver.cpp \
qt/moc_qvalidatedlineedit.cpp \
qt/moc_qvaluecombobox.cpp \
qt/moc_receivecoinsdialog.cpp \
qt/moc_receiverequestdialog.cpp \
qt/moc_recentrequeststablemodel.cpp \
qt/moc_rpcconsole.cpp \
qt/moc_sendcoinsdialog.cpp \
qt/moc_sendcoinsentry.cpp \
qt/moc_signverifymessagedialog.cpp \
qt/moc_splashscreen.cpp \
qt/moc_trafficgraphwidget.cpp \
qt/moc_transactiondesc.cpp \
qt/moc_transactiondescdialog.cpp \
qt/moc_transactionfilterproxy.cpp \
qt/moc_transactiontablemodel.cpp \
qt/moc_transactionview.cpp \
qt/moc_utilitydialog.cpp \
qt/moc_walletframe.cpp \
qt/moc_walletmodel.cpp \
qt/moc_walletview.cpp
BITCOIN_MM = \
qt/macdockiconhandler.mm \
qt/macnotificationhandler.mm
QT_MOC = \
qt/bitcoin.moc \
qt/intro.moc \
qt/overviewpage.moc \
qt/rpcconsole.moc
QT_QRC_CPP = qt/qrc_bitcoin.cpp
QT_QRC = qt/bitcoin.qrc
QT_QRC_LOCALE_CPP = qt/qrc_bitcoin_locale.cpp
QT_QRC_LOCALE = qt/bitcoin_locale.qrc
PROTOBUF_CC = qt/paymentrequest.pb.cc
PROTOBUF_H = qt/paymentrequest.pb.h
PROTOBUF_PROTO = qt/paymentrequest.proto
BITCOIN_QT_H = \
qt/addressbookpage.h \
qt/addresstablemodel.h \
qt/askpassphrasedialog.h \
qt/bitcoinaddressvalidator.h \
qt/bitcoinamountfield.h \
qt/bitcoingui.h \
qt/bitcoinunits.h \
qt/clientmodel.h \
qt/coincontroldialog.h \
qt/coincontroltreewidget.h \
qt/csvmodelwriter.h \
qt/editaddressdialog.h \
qt/guiconstants.h \
qt/guiutil.h \
qt/intro.h \
qt/macdockiconhandler.h \
qt/macnotificationhandler.h \
qt/monitoreddatamapper.h \
qt/notificator.h \
qt/openuridialog.h \
qt/optionsdialog.h \
qt/optionsmodel.h \
qt/overviewpage.h \
qt/paymentrequestplus.h \
qt/paymentserver.h \
qt/peertablemodel.h \
qt/qvalidatedlineedit.h \
qt/qvaluecombobox.h \
qt/receivecoinsdialog.h \
qt/receiverequestdialog.h \
qt/recentrequeststablemodel.h \
qt/rpcconsole.h \
qt/sendcoinsdialog.h \
qt/sendcoinsentry.h \
qt/signverifymessagedialog.h \
qt/splashscreen.h \
qt/trafficgraphwidget.h \
qt/transactiondesc.h \
qt/transactiondescdialog.h \
qt/transactionfilterproxy.h \
qt/transactionrecord.h \
qt/transactiontablemodel.h \
qt/transactionview.h \
qt/utilitydialog.h \
qt/walletframe.h \
qt/walletmodel.h \
qt/walletmodeltransaction.h \
qt/walletview.h \
qt/winshutdownmonitor.h
RES_ICONS = \
qt/res/icons/add.png \
qt/res/icons/address-book.png \
qt/res/icons/bitcoin.ico \
qt/res/icons/bitcoin.png \
qt/res/icons/bitcoin_testnet.ico \
qt/res/icons/bitcoin_testnet.png \
qt/res/icons/clock1.png \
qt/res/icons/clock2.png \
qt/res/icons/clock3.png \
qt/res/icons/clock4.png \
qt/res/icons/clock5.png \
qt/res/icons/configure.png \
qt/res/icons/connect0_16.png \
qt/res/icons/connect1_16.png \
qt/res/icons/connect2_16.png \
qt/res/icons/connect3_16.png \
qt/res/icons/connect4_16.png \
qt/res/icons/debugwindow.png \
qt/res/icons/edit.png \
qt/res/icons/editcopy.png \
qt/res/icons/editpaste.png \
qt/res/icons/export.png \
qt/res/icons/filesave.png \
qt/res/icons/history.png \
qt/res/icons/key.png \
qt/res/icons/lock_closed.png \
qt/res/icons/lock_open.png \
qt/res/icons/overview.png \
qt/res/icons/qrcode.png \
qt/res/icons/quit.png \
qt/res/icons/receive.png \
qt/res/icons/remove.png \
qt/res/icons/send.png \
qt/res/icons/synced.png \
qt/res/icons/toolbar.png \
qt/res/icons/toolbar_testnet.png \
qt/res/icons/transaction0.png \
qt/res/icons/transaction2.png \
qt/res/icons/transaction_conflicted.png \
qt/res/icons/tx_inout.png \
qt/res/icons/tx_input.png \
qt/res/icons/tx_output.png \
qt/res/icons/tx_mined.png \
qt/res/icons/unit_btc.png \
qt/res/icons/unit_mbtc.png \
qt/res/icons/unit_ubtc.png
BITCOIN_QT_CPP = \
qt/bitcoinaddressvalidator.cpp \
qt/bitcoinamountfield.cpp \
qt/bitcoingui.cpp \
qt/bitcoinunits.cpp \
qt/clientmodel.cpp \
qt/csvmodelwriter.cpp \
qt/guiutil.cpp \
qt/intro.cpp \
qt/monitoreddatamapper.cpp \
qt/notificator.cpp \
qt/optionsdialog.cpp \
qt/optionsmodel.cpp \
qt/peertablemodel.cpp \
qt/qvalidatedlineedit.cpp \
qt/qvaluecombobox.cpp \
qt/rpcconsole.cpp \
qt/splashscreen.cpp \
qt/trafficgraphwidget.cpp \
qt/utilitydialog.cpp \
qt/winshutdownmonitor.cpp
if ENABLE_WALLET
BITCOIN_QT_CPP += \
qt/addressbookpage.cpp \
qt/addresstablemodel.cpp \
qt/askpassphrasedialog.cpp \
qt/coincontroldialog.cpp \
qt/coincontroltreewidget.cpp \
qt/editaddressdialog.cpp \
qt/openuridialog.cpp \
qt/overviewpage.cpp \
qt/paymentrequestplus.cpp \
qt/paymentserver.cpp \
qt/receivecoinsdialog.cpp \
qt/receiverequestdialog.cpp \
qt/recentrequeststablemodel.cpp \
qt/sendcoinsdialog.cpp \
qt/sendcoinsentry.cpp \
qt/signverifymessagedialog.cpp \
qt/transactiondesc.cpp \
qt/transactiondescdialog.cpp \
qt/transactionfilterproxy.cpp \
qt/transactionrecord.cpp \
qt/transactiontablemodel.cpp \
qt/transactionview.cpp \
qt/walletframe.cpp \
qt/walletmodel.cpp \
qt/walletmodeltransaction.cpp \
qt/walletview.cpp
endif
RES_IMAGES = \
qt/res/images/about.png \
qt/res/images/splash.png \
qt/res/images/splash_testnet.png
RES_MOVIES = $(wildcard qt/res/movies/spinner-*.png)
BITCOIN_RC = qt/res/bitcoin-qt-res.rc
BITCOIN_QT_INCLUDES = -I$(builddir)/qt -I$(srcdir)/qt -I$(srcdir)/qt/forms \
-I$(builddir)/qt/forms
qt_libbitcoinqt_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
$(QT_INCLUDES) $(QT_DBUS_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS)
qt_libbitcoinqt_a_SOURCES = $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(QT_FORMS_UI) \
$(QT_QRC) $(QT_QRC_LOCALE) $(QT_TS) $(PROTOBUF_PROTO) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES)
nodist_qt_libbitcoinqt_a_SOURCES = $(QT_MOC_CPP) $(QT_MOC) $(PROTOBUF_CC) \
$(PROTOBUF_H) $(QT_QRC_CPP) $(QT_QRC_LOCALE_CPP)
# forms/foo.h -> forms/ui_foo.h
QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI:.ui=.h))))
# Most files will depend on the forms and moc files as includes. Generate them
# before anything else.
$(QT_MOC): $(QT_FORMS_H)
$(qt_libbitcoinqt_a_OBJECTS) $(qt_bitcoin_qt_OBJECTS) : | $(QT_MOC)
#Generating these with a half-written protobuf header leads to wacky results.
#This makes sure it's done.
$(QT_MOC): $(PROTOBUF_H)
$(QT_MOC_CPP): $(PROTOBUF_H)
# bitcoin-qt binary #
qt_bitcoin_qt_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
$(QT_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS)
qt_bitcoin_qt_SOURCES = qt/bitcoin.cpp
if TARGET_DARWIN
qt_bitcoin_qt_SOURCES += $(BITCOIN_MM)
endif
if TARGET_WINDOWS
qt_bitcoin_qt_SOURCES += $(BITCOIN_RC)
endif
qt_bitcoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER)
if ENABLE_WALLET
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
endif
qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBLEVELDB) $(LIBMEMENV) \
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
if USE_LIBSECP256K1
qt_bitcoin_qt_LDADD += secp256k1/libsecp256k1.la
endif
qt_bitcoin_qt_LDFLAGS = $(QT_LDFLAGS)
#locale/foo.ts -> locale/foo.qm
QT_QM=$(QT_TS:.ts=.qm)
.SECONDARY: $(QT_QM)
qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES)
@test -n $(XGETTEXT) || echo "xgettext is required for updating translations"
$(AM_V_GEN) cd $(srcdir); XGETTEXT=$(XGETTEXT) ../share/qt/extract_strings_qt.py $^
translate: qt/bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM)
@test -n $(LUPDATE) || echo "lupdate is required for updating translations"
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts qt/locale/bitcoin_en.ts
$(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM)
@test -f $(RCC)
@test -f $(@D)/$(<F) || cp -f $< $(@D)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin_locale $(@D)/$(<F) | \
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
$(QT_QRC_CPP): $(QT_QRC) $(QT_FORMS_H) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) $(PROTOBUF_H)
@test -f $(RCC)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin $< | \
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
CLEAN_QT = $(nodist_qt_libbitcoinqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno
CLEANFILES += $(CLEAN_QT)
bitcoin_qt_clean: FORCE
rm -f $(CLEAN_QT) $(qt_libbitcoinqt_a_OBJECTS) $(qt_bitcoin_qt_OBJECTS) qt/bitcoin-qt$(EXEEXT) $(LIBBITCOINQT)
bitcoin_qt : qt/bitcoin-qt$(EXEEXT)
ui_%.h: %.ui
@test -f $(UIC)
@$(MKDIR_P) $(@D)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(UIC) -o $@ $< || (echo "Error creating $@"; false)
%.moc: %.cpp
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) $< | \
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
moc_%.cpp: %.h
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(MOC) $(QT_INCLUDES) $(MOC_DEFS) $< | \
$(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@
%.qm: %.ts
@test -f $(LRELEASE)
@$(MKDIR_P) $(@D)
$(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LRELEASE) -silent $< -qm $@

View file

@ -0,0 +1,51 @@
bin_PROGRAMS += qt/test/test_bitcoin-qt
TESTS += qt/test/test_bitcoin-qt
TEST_QT_MOC_CPP = qt/test/moc_uritests.cpp
if ENABLE_WALLET
TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp
endif
TEST_QT_H = \
qt/test/uritests.h \
qt/test/paymentrequestdata.h \
qt/test/paymentservertests.h
qt_test_test_bitcoin_qt_CPPFLAGS = $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
$(QT_INCLUDES) $(QT_TEST_INCLUDES)
qt_test_test_bitcoin_qt_SOURCES = \
qt/test/test_main.cpp \
qt/test/uritests.cpp \
$(TEST_QT_H)
if ENABLE_WALLET
qt_test_test_bitcoin_qt_SOURCES += \
qt/test/paymentservertests.cpp
endif
nodist_qt_test_test_bitcoin_qt_SOURCES = $(TEST_QT_MOC_CPP)
qt_test_test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER)
if ENABLE_WALLET
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET)
endif
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBLEVELDB) \
$(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
$(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS)
if USE_LIBSECP256K1
qt_test_test_bitcoin_qt_LDADD += secp256k1/libsecp256k1.la
endif
qt_test_test_bitcoin_qt_LDFLAGS = $(QT_LDFLAGS)
CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno
CLEANFILES += $(CLEAN_BITCOIN_QT_TEST)
test_bitcoin_qt : qt/test/test_bitcoin-qt$(EXEEXT)
test_bitcoin_qt_check : qt/test/test_bitcoin-qt$(EXEEXT) FORCE
$(MAKE) check-TESTS TESTS=$^
test_bitcoin_qt_clean: FORCE
rm -f $(CLEAN_BITCOIN_QT_TEST) $(qt_test_test_bitcoin_qt_OBJECTS)

109
src/Makefile.test.include Normal file
View file

@ -0,0 +1,109 @@
TESTS += test/test_bitcoin
bin_PROGRAMS += test/test_bitcoin
TEST_SRCDIR = test
TEST_BINARY=test/test_bitcoin$(EXEEXT)
JSON_TEST_FILES = \
test/data/script_valid.json \
test/data/base58_keys_valid.json \
test/data/sig_canonical.json \
test/data/sig_noncanonical.json \
test/data/base58_encode_decode.json \
test/data/base58_keys_invalid.json \
test/data/script_invalid.json \
test/data/tx_invalid.json \
test/data/tx_valid.json \
test/data/sighash.json
RAW_TEST_FILES = test/data/alertTests.raw
GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h)
BITCOIN_TESTS =\
test/bignum.h \
test/alert_tests.cpp \
test/allocator_tests.cpp \
test/base32_tests.cpp \
test/base58_tests.cpp \
test/base64_tests.cpp \
test/bloom_tests.cpp \
test/canonical_tests.cpp \
test/checkblock_tests.cpp \
test/Checkpoints_tests.cpp \
test/compress_tests.cpp \
test/crypto_tests.cpp \
test/DoS_tests.cpp \
test/getarg_tests.cpp \
test/hash_tests.cpp \
test/key_tests.cpp \
test/main_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/script_P2SH_tests.cpp \
test/script_tests.cpp \
test/serialize_tests.cpp \
test/sigopcount_tests.cpp \
test/skiplist_tests.cpp \
test/test_bitcoin.cpp \
test/transaction_tests.cpp \
test/uint256_tests.cpp \
test/util_tests.cpp \
test/scriptnum_tests.cpp \
test/sighash_tests.cpp
if ENABLE_WALLET
BITCOIN_TESTS += \
test/accounting_tests.cpp \
test/wallet_tests.cpp \
test/rpc_wallet_tests.cpp
endif
test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
test_test_bitcoin_CPPFLAGS = $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS)
test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBLEVELDB) $(LIBMEMENV) \
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB)
if ENABLE_WALLET
test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
endif
if USE_LIBSECP256K1
test_test_bitcoin_LDADD += secp256k1/libsecp256k1.la
endif
test_test_bitcoin_LDADD += $(BDB_LIBS)
nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES)
$(BITCOIN_TESTS): $(GENERATED_TEST_FILES)
CLEAN_BITCOIN_TEST = test/*.gcda test/*.gcno $(GENERATED_TEST_FILES)
CLEANFILES += $(CLEAN_BITCOIN_TEST)
bitcoin_test: $(TEST_BINARY)
bitcoin_test_check: $(TEST_BINARY) FORCE
$(MAKE) check-TESTS TESTS=$^
bitcoin_test_clean : FORCE
rm -f $(CLEAN_BITCOIN_TEST) $(test_test_bitcoin_OBJECTS) $(TEST_BINARY)
%.json.h: %.json
@$(MKDIR_P) $(@D)
@echo "namespace json_tests{" > $@
@echo "static unsigned const char $(*F)[] = {" >> $@
@$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' >> $@
@echo "};};" >> $@
@echo "Generated $@"
%.raw.h: %.raw
@$(MKDIR_P) $(@D)
@echo "namespace alert_tests{" > $@
@echo "static unsigned const char $(*F)[] = {" >> $@
@$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' >> $@
@echo "};};" >> $@
@echo "Generated $@"

View file

@ -8,6 +8,7 @@
#include "netbase.h" #include "netbase.h"
#include "protocol.h" #include "protocol.h"
#include "sync.h" #include "sync.h"
#include "timedata.h"
#include "util.h" #include "util.h"
#include <map> #include <map>
@ -420,7 +421,7 @@ public:
Check(); Check();
} }
if (fRet) if (fRet)
LogPrint("addrman", "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort().c_str(), source.ToString().c_str(), nTried, nNew); LogPrint("addrman", "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort().c_str(), source.ToString(), nTried, nNew);
return fRet; return fRet;
} }
@ -436,7 +437,7 @@ public:
Check(); Check();
} }
if (nAdd) if (nAdd)
LogPrint("addrman", "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString().c_str(), nTried, nNew); LogPrint("addrman", "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew);
return nAdd > 0; return nAdd > 0;
} }

View file

@ -5,8 +5,10 @@
#include "alert.h" #include "alert.h"
#include "chainparams.h"
#include "key.h" #include "key.h"
#include "net.h" #include "net.h"
#include "timedata.h"
#include "ui_interface.h" #include "ui_interface.h"
#include "util.h" #include "util.h"

View file

@ -2,11 +2,18 @@
// Distributed under the MIT/X11 software license, see the accompanying // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "base58.h"
#include "hash.h"
#include "uint256.h"
#include <assert.h> #include <assert.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <vector> #include <vector>
#include <string> #include <string>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
/* All alphanumeric characters except for "0", "I", "O", and "l" */ /* All alphanumeric characters except for "0", "I", "O", and "l" */
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
@ -89,3 +96,180 @@ std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
str += pszBase58[*(it++)]; str += pszBase58[*(it++)];
return str; return str;
} }
std::string EncodeBase58(const std::vector<unsigned char>& vch) {
return EncodeBase58(&vch[0], &vch[0] + vch.size());
}
bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet) {
return DecodeBase58(str.c_str(), vchRet);
}
std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn) {
// add 4-byte hash check to the end
std::vector<unsigned char> vch(vchIn);
uint256 hash = Hash(vch.begin(), vch.end());
vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
return EncodeBase58(vch);
}
bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet) {
if (!DecodeBase58(psz, vchRet) ||
(vchRet.size() < 4))
{
vchRet.clear();
return false;
}
// re-calculate the checksum, insure it matches the included 4-byte checksum
uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);
if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
{
vchRet.clear();
return false;
}
vchRet.resize(vchRet.size()-4);
return true;
}
bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet) {
return DecodeBase58Check(str.c_str(), vchRet);
}
CBase58Data::CBase58Data() {
vchVersion.clear();
vchData.clear();
}
void CBase58Data::SetData(const std::vector<unsigned char> &vchVersionIn, const void* pdata, size_t nSize) {
vchVersion = vchVersionIn;
vchData.resize(nSize);
if (!vchData.empty())
memcpy(&vchData[0], pdata, nSize);
}
void CBase58Data::SetData(const std::vector<unsigned char> &vchVersionIn, const unsigned char *pbegin, const unsigned char *pend) {
SetData(vchVersionIn, (void*)pbegin, pend - pbegin);
}
bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes) {
std::vector<unsigned char> vchTemp;
bool rc58 = DecodeBase58Check(psz, vchTemp);
if ((!rc58) || (vchTemp.size() < nVersionBytes)) {
vchData.clear();
vchVersion.clear();
return false;
}
vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes);
vchData.resize(vchTemp.size() - nVersionBytes);
if (!vchData.empty())
memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
OPENSSL_cleanse(&vchTemp[0], vchData.size());
return true;
}
bool CBase58Data::SetString(const std::string& str) {
return SetString(str.c_str());
}
std::string CBase58Data::ToString() const {
std::vector<unsigned char> vch = vchVersion;
vch.insert(vch.end(), vchData.begin(), vchData.end());
return EncodeBase58Check(vch);
}
int CBase58Data::CompareTo(const CBase58Data& b58) const {
if (vchVersion < b58.vchVersion) return -1;
if (vchVersion > b58.vchVersion) return 1;
if (vchData < b58.vchData) return -1;
if (vchData > b58.vchData) return 1;
return 0;
}
namespace {
class CBitcoinAddressVisitor : public boost::static_visitor<bool> {
private:
CBitcoinAddress *addr;
public:
CBitcoinAddressVisitor(CBitcoinAddress *addrIn) : addr(addrIn) { }
bool operator()(const CKeyID &id) const { return addr->Set(id); }
bool operator()(const CScriptID &id) const { return addr->Set(id); }
bool operator()(const CNoDestination &no) const { return false; }
};
} // anon namespace
bool CBitcoinAddress::Set(const CKeyID &id) {
SetData(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS), &id, 20);
return true;
}
bool CBitcoinAddress::Set(const CScriptID &id) {
SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20);
return true;
}
bool CBitcoinAddress::Set(const CTxDestination &dest) {
return boost::apply_visitor(CBitcoinAddressVisitor(this), dest);
}
bool CBitcoinAddress::IsValid() const {
bool fCorrectSize = vchData.size() == 20;
bool fKnownVersion = vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
return fCorrectSize && fKnownVersion;
}
CTxDestination CBitcoinAddress::Get() const {
if (!IsValid())
return CNoDestination();
uint160 id;
memcpy(&id, &vchData[0], 20);
if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))
return CKeyID(id);
else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS))
return CScriptID(id);
else
return CNoDestination();
}
bool CBitcoinAddress::GetKeyID(CKeyID &keyID) const {
if (!IsValid() || vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))
return false;
uint160 id;
memcpy(&id, &vchData[0], 20);
keyID = CKeyID(id);
return true;
}
bool CBitcoinAddress::IsScript() const {
return IsValid() && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
}
void CBitcoinSecret::SetKey(const CKey& vchSecret) {
assert(vchSecret.IsValid());
SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size());
if (vchSecret.IsCompressed())
vchData.push_back(1);
}
CKey CBitcoinSecret::GetKey() {
CKey ret;
ret.Set(&vchData[0], &vchData[32], vchData.size() > 32 && vchData[32] == 1);
return ret;
}
bool CBitcoinSecret::IsValid() const {
bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1);
bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY);
return fExpectedFormat && fCorrectVersion;
}
bool CBitcoinSecret::SetString(const char* pszSecret) {
return CBase58Data::SetString(pszSecret) && IsValid();
}
bool CBitcoinSecret::SetString(const std::string& strSecret) {
return SetString(strSecret.c_str());
}

View file

@ -15,17 +15,12 @@
#define BITCOIN_BASE58_H #define BITCOIN_BASE58_H
#include "chainparams.h" #include "chainparams.h"
#include "hash.h"
#include "key.h" #include "key.h"
#include "script.h" #include "script.h"
#include "uint256.h"
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
/** /**
* Encode a byte sequence as a base58-encoded string. * Encode a byte sequence as a base58-encoded string.
* pbegin and pend cannot be NULL, unless both are. * pbegin and pend cannot be NULL, unless both are.
@ -35,10 +30,7 @@ std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
/** /**
* Encode a byte vector as a base58-encoded string * Encode a byte vector as a base58-encoded string
*/ */
inline std::string EncodeBase58(const std::vector<unsigned char>& vch) std::string EncodeBase58(const std::vector<unsigned char>& vch);
{
return EncodeBase58(&vch[0], &vch[0] + vch.size());
}
/** /**
* Decode a base58-encoded string (psz) into a byte vector (vchRet). * Decode a base58-encoded string (psz) into a byte vector (vchRet).
@ -51,55 +43,24 @@ bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet);
* Decode a base58-encoded string (str) into a byte vector (vchRet). * Decode a base58-encoded string (str) into a byte vector (vchRet).
* return true if decoding is successful. * return true if decoding is successful.
*/ */
inline bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet) bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet);
{
return DecodeBase58(str.c_str(), vchRet);
}
/** /**
* Encode a byte vector into a base58-encoded string, including checksum * Encode a byte vector into a base58-encoded string, including checksum
*/ */
inline std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn) std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn);
{
// add 4-byte hash check to the end
std::vector<unsigned char> vch(vchIn);
uint256 hash = Hash(vch.begin(), vch.end());
vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
return EncodeBase58(vch);
}
/** /**
* Decode a base58-encoded string (psz) that includes a checksum into a byte * Decode a base58-encoded string (psz) that includes a checksum into a byte
* vector (vchRet), return true if decoding is successful * vector (vchRet), return true if decoding is successful
*/ */
inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet) inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet);
{
if (!DecodeBase58(psz, vchRet))
return false;
if (vchRet.size() < 4)
{
vchRet.clear();
return false;
}
// re-calculate the checksum, insure it matches the included 4-byte checksum
uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);
if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
{
vchRet.clear();
return false;
}
vchRet.resize(vchRet.size()-4);
return true;
}
/** /**
* Decode a base58-encoded string (str) that includes a checksum into a byte * Decode a base58-encoded string (str) that includes a checksum into a byte
* vector (vchRet), return true if decoding is successful * vector (vchRet), return true if decoding is successful
*/ */
inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet) inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet);
{
return DecodeBase58Check(str.c_str(), vchRet);
}
/** /**
* Base class for all base58-encoded data * Base class for all base58-encoded data
@ -114,64 +75,15 @@ protected:
typedef std::vector<unsigned char, zero_after_free_allocator<unsigned char> > vector_uchar; typedef std::vector<unsigned char, zero_after_free_allocator<unsigned char> > vector_uchar;
vector_uchar vchData; vector_uchar vchData;
CBase58Data() CBase58Data();
{ void SetData(const std::vector<unsigned char> &vchVersionIn, const void* pdata, size_t nSize);
vchVersion.clear(); void SetData(const std::vector<unsigned char> &vchVersionIn, const unsigned char *pbegin, const unsigned char *pend);
vchData.clear();
}
void SetData(const std::vector<unsigned char> &vchVersionIn, const void* pdata, size_t nSize)
{
vchVersion = vchVersionIn;
vchData.resize(nSize);
if (!vchData.empty())
memcpy(&vchData[0], pdata, nSize);
}
void SetData(const std::vector<unsigned char> &vchVersionIn, const unsigned char *pbegin, const unsigned char *pend)
{
SetData(vchVersionIn, (void*)pbegin, pend - pbegin);
}
public: public:
bool SetString(const char* psz, unsigned int nVersionBytes = 1) bool SetString(const char* psz, unsigned int nVersionBytes = 1);
{ bool SetString(const std::string& str);
std::vector<unsigned char> vchTemp; std::string ToString() const;
DecodeBase58Check(psz, vchTemp); int CompareTo(const CBase58Data& b58) const;
if (vchTemp.size() < nVersionBytes)
{
vchData.clear();
vchVersion.clear();
return false;
}
vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes);
vchData.resize(vchTemp.size() - nVersionBytes);
if (!vchData.empty())
memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
OPENSSL_cleanse(&vchTemp[0], vchData.size());
return true;
}
bool SetString(const std::string& str)
{
return SetString(str.c_str());
}
std::string ToString() const
{
std::vector<unsigned char> vch = vchVersion;
vch.insert(vch.end(), vchData.begin(), vchData.end());
return EncodeBase58Check(vch);
}
int CompareTo(const CBase58Data& b58) const
{
if (vchVersion < b58.vchVersion) return -1;
if (vchVersion > b58.vchVersion) return 1;
if (vchData < b58.vchData) return -1;
if (vchData > b58.vchData) return 1;
return 0;
}
bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; } bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; }
bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; } bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; }
@ -186,140 +98,37 @@ public:
* Script-hash-addresses have version 5 (or 196 testnet). * Script-hash-addresses have version 5 (or 196 testnet).
* The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script. * The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
*/ */
class CBitcoinAddress; class CBitcoinAddress : public CBase58Data {
class CBitcoinAddressVisitor : public boost::static_visitor<bool>
{
private:
CBitcoinAddress *addr;
public: public:
CBitcoinAddressVisitor(CBitcoinAddress *addrIn) : addr(addrIn) { } bool Set(const CKeyID &id);
bool operator()(const CKeyID &id) const; bool Set(const CScriptID &id);
bool operator()(const CScriptID &id) const; bool Set(const CTxDestination &dest);
bool operator()(const CNoDestination &no) const; bool IsValid() const;
CBitcoinAddress() {}
CBitcoinAddress(const CTxDestination &dest) { Set(dest); }
CBitcoinAddress(const std::string& strAddress) { SetString(strAddress); }
CBitcoinAddress(const char* pszAddress) { SetString(pszAddress); }
CTxDestination Get() const;
bool GetKeyID(CKeyID &keyID) const;
bool IsScript() const;
}; };
class CBitcoinAddress : public CBase58Data
{
public:
bool Set(const CKeyID &id) {
SetData(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS), &id, 20);
return true;
}
bool Set(const CScriptID &id) {
SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20);
return true;
}
bool Set(const CTxDestination &dest)
{
return boost::apply_visitor(CBitcoinAddressVisitor(this), dest);
}
bool IsValid() const
{
bool fCorrectSize = vchData.size() == 20;
bool fKnownVersion = vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
return fCorrectSize && fKnownVersion;
}
CBitcoinAddress()
{
}
CBitcoinAddress(const CTxDestination &dest)
{
Set(dest);
}
CBitcoinAddress(const std::string& strAddress)
{
SetString(strAddress);
}
CBitcoinAddress(const char* pszAddress)
{
SetString(pszAddress);
}
CTxDestination Get() const {
if (!IsValid())
return CNoDestination();
uint160 id;
memcpy(&id, &vchData[0], 20);
if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))
return CKeyID(id);
else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS))
return CScriptID(id);
else
return CNoDestination();
}
bool GetKeyID(CKeyID &keyID) const {
if (!IsValid() || vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))
return false;
uint160 id;
memcpy(&id, &vchData[0], 20);
keyID = CKeyID(id);
return true;
}
bool IsScript() const {
return IsValid() && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
}
};
bool inline CBitcoinAddressVisitor::operator()(const CKeyID &id) const { return addr->Set(id); }
bool inline CBitcoinAddressVisitor::operator()(const CScriptID &id) const { return addr->Set(id); }
bool inline CBitcoinAddressVisitor::operator()(const CNoDestination &id) const { return false; }
/** /**
* A base58-encoded secret key * A base58-encoded secret key
*/ */
class CBitcoinSecret : public CBase58Data class CBitcoinSecret : public CBase58Data
{ {
public: public:
void SetKey(const CKey& vchSecret) void SetKey(const CKey& vchSecret);
{ CKey GetKey();
assert(vchSecret.IsValid()); bool IsValid() const;
SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size()); bool SetString(const char* pszSecret);
if (vchSecret.IsCompressed()) bool SetString(const std::string& strSecret);
vchData.push_back(1);
}
CKey GetKey() CBitcoinSecret(const CKey& vchSecret) { SetKey(vchSecret); }
{ CBitcoinSecret() {}
CKey ret;
ret.Set(&vchData[0], &vchData[32], vchData.size() > 32 && vchData[32] == 1);
return ret;
}
bool IsValid() const
{
bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1);
bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY);
return fExpectedFormat && fCorrectVersion;
}
bool SetString(const char* pszSecret)
{
return CBase58Data::SetString(pszSecret) && IsValid();
}
bool SetString(const std::string& strSecret)
{
return SetString(strSecret.c_str());
}
CBitcoinSecret(const CKey& vchSecret)
{
SetKey(vchSecret);
}
CBitcoinSecret()
{
}
}; };
template<typename K, int Size, CChainParams::Base58Type Type> class CBitcoinExtKeyBase : public CBase58Data template<typename K, int Size, CChainParams::Base58Type Type> class CBitcoinExtKeyBase : public CBase58Data

View file

@ -1,595 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2013 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_BIGNUM_H
#define BITCOIN_BIGNUM_H
#include "serialize.h"
#include "uint256.h"
#include "version.h"
#include <stdexcept>
#include <stdint.h>
#include <vector>
#include <openssl/bn.h>
/** Errors thrown by the bignum class */
class bignum_error : public std::runtime_error
{
public:
explicit bignum_error(const std::string& str) : std::runtime_error(str) {}
};
/** RAII encapsulated BN_CTX (OpenSSL bignum context) */
class CAutoBN_CTX
{
protected:
BN_CTX* pctx;
BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; }
public:
CAutoBN_CTX()
{
pctx = BN_CTX_new();
if (pctx == NULL)
throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");
}
~CAutoBN_CTX()
{
if (pctx != NULL)
BN_CTX_free(pctx);
}
operator BN_CTX*() { return pctx; }
BN_CTX& operator*() { return *pctx; }
BN_CTX** operator&() { return &pctx; }
bool operator!() { return (pctx == NULL); }
};
/** C++ wrapper for BIGNUM (OpenSSL bignum) */
class CBigNum : public BIGNUM
{
public:
CBigNum()
{
BN_init(this);
}
CBigNum(const CBigNum& b)
{
BN_init(this);
if (!BN_copy(this, &b))
{
BN_clear_free(this);
throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
}
}
CBigNum& operator=(const CBigNum& b)
{
if (!BN_copy(this, &b))
throw bignum_error("CBigNum::operator= : BN_copy failed");
return (*this);
}
~CBigNum()
{
BN_clear_free(this);
}
//CBigNum(char n) is not portable. Use 'signed char' or 'unsigned char'.
CBigNum(signed char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); }
CBigNum(long long n) { BN_init(this); setint64(n); }
CBigNum(unsigned char n) { BN_init(this); setulong(n); }
CBigNum(unsigned short n) { BN_init(this); setulong(n); }
CBigNum(unsigned int n) { BN_init(this); setulong(n); }
CBigNum(unsigned long n) { BN_init(this); setulong(n); }
CBigNum(unsigned long long n) { BN_init(this); setuint64(n); }
explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); }
explicit CBigNum(const std::vector<unsigned char>& vch)
{
BN_init(this);
setvch(vch);
}
void setulong(unsigned long n)
{
if (!BN_set_word(this, n))
throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed");
}
unsigned long getulong() const
{
return BN_get_word(this);
}
unsigned int getuint() const
{
return BN_get_word(this);
}
int getint() const
{
unsigned long n = BN_get_word(this);
if (!BN_is_negative(this))
return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
else
return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n);
}
void setint64(int64_t sn)
{
unsigned char pch[sizeof(sn) + 6];
unsigned char* p = pch + 4;
bool fNegative;
uint64_t n;
if (sn < (int64_t)0)
{
// Since the minimum signed integer cannot be represented as positive so long as its type is signed,
// and it's not well-defined what happens if you make it unsigned before negating it,
// we instead increment the negative integer by 1, convert it, then increment the (now positive) unsigned integer by 1 to compensate
n = -(sn + 1);
++n;
fNegative = true;
} else {
n = sn;
fNegative = false;
}
bool fLeadingZeroes = true;
for (int i = 0; i < 8; i++)
{
unsigned char c = (n >> 56) & 0xff;
n <<= 8;
if (fLeadingZeroes)
{
if (c == 0)
continue;
if (c & 0x80)
*p++ = (fNegative ? 0x80 : 0);
else if (fNegative)
c |= 0x80;
fLeadingZeroes = false;
}
*p++ = c;
}
unsigned int nSize = p - (pch + 4);
pch[0] = (nSize >> 24) & 0xff;
pch[1] = (nSize >> 16) & 0xff;
pch[2] = (nSize >> 8) & 0xff;
pch[3] = (nSize) & 0xff;
BN_mpi2bn(pch, p - pch, this);
}
void setuint64(uint64_t n)
{
unsigned char pch[sizeof(n) + 6];
unsigned char* p = pch + 4;
bool fLeadingZeroes = true;
for (int i = 0; i < 8; i++)
{
unsigned char c = (n >> 56) & 0xff;
n <<= 8;
if (fLeadingZeroes)
{
if (c == 0)
continue;
if (c & 0x80)
*p++ = 0;
fLeadingZeroes = false;
}
*p++ = c;
}
unsigned int nSize = p - (pch + 4);
pch[0] = (nSize >> 24) & 0xff;
pch[1] = (nSize >> 16) & 0xff;
pch[2] = (nSize >> 8) & 0xff;
pch[3] = (nSize) & 0xff;
BN_mpi2bn(pch, p - pch, this);
}
void setuint256(uint256 n)
{
unsigned char pch[sizeof(n) + 6];
unsigned char* p = pch + 4;
bool fLeadingZeroes = true;
unsigned char* pbegin = (unsigned char*)&n;
unsigned char* psrc = pbegin + sizeof(n);
while (psrc != pbegin)
{
unsigned char c = *(--psrc);
if (fLeadingZeroes)
{
if (c == 0)
continue;
if (c & 0x80)
*p++ = 0;
fLeadingZeroes = false;
}
*p++ = c;
}
unsigned int nSize = p - (pch + 4);
pch[0] = (nSize >> 24) & 0xff;
pch[1] = (nSize >> 16) & 0xff;
pch[2] = (nSize >> 8) & 0xff;
pch[3] = (nSize >> 0) & 0xff;
BN_mpi2bn(pch, p - pch, this);
}
uint256 getuint256() const
{
unsigned int nSize = BN_bn2mpi(this, NULL);
if (nSize < 4)
return 0;
std::vector<unsigned char> vch(nSize);
BN_bn2mpi(this, &vch[0]);
if (vch.size() > 4)
vch[4] &= 0x7f;
uint256 n = 0;
for (unsigned int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--)
((unsigned char*)&n)[i] = vch[j];
return n;
}
void setvch(const std::vector<unsigned char>& vch)
{
std::vector<unsigned char> vch2(vch.size() + 4);
unsigned int nSize = vch.size();
// BIGNUM's byte stream format expects 4 bytes of
// big endian size data info at the front
vch2[0] = (nSize >> 24) & 0xff;
vch2[1] = (nSize >> 16) & 0xff;
vch2[2] = (nSize >> 8) & 0xff;
vch2[3] = (nSize >> 0) & 0xff;
// swap data to big endian
reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
BN_mpi2bn(&vch2[0], vch2.size(), this);
}
std::vector<unsigned char> getvch() const
{
unsigned int nSize = BN_bn2mpi(this, NULL);
if (nSize <= 4)
return std::vector<unsigned char>();
std::vector<unsigned char> vch(nSize);
BN_bn2mpi(this, &vch[0]);
vch.erase(vch.begin(), vch.begin() + 4);
reverse(vch.begin(), vch.end());
return vch;
}
// The "compact" format is a representation of a whole
// number N using an unsigned 32bit number similar to a
// floating point format.
// The most significant 8 bits are the unsigned exponent of base 256.
// This exponent can be thought of as "number of bytes of N".
// The lower 23 bits are the mantissa.
// Bit number 24 (0x800000) represents the sign of N.
// N = (-1^sign) * mantissa * 256^(exponent-3)
//
// Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn().
// MPI uses the most significant bit of the first byte as sign.
// Thus 0x1234560000 is compact (0x05123456)
// and 0xc0de000000 is compact (0x0600c0de)
// (0x05c0de00) would be -0x40de000000
//
// Bitcoin only uses this "compact" format for encoding difficulty
// targets, which are unsigned 256bit quantities. Thus, all the
// complexities of the sign bit and using base 256 are probably an
// implementation accident.
//
// This implementation directly uses shifts instead of going
// through an intermediate MPI representation.
CBigNum& SetCompact(unsigned int nCompact)
{
unsigned int nSize = nCompact >> 24;
bool fNegative =(nCompact & 0x00800000) != 0;
unsigned int nWord = nCompact & 0x007fffff;
if (nSize <= 3)
{
nWord >>= 8*(3-nSize);
BN_set_word(this, nWord);
}
else
{
BN_set_word(this, nWord);
BN_lshift(this, this, 8*(nSize-3));
}
BN_set_negative(this, fNegative);
return *this;
}
unsigned int GetCompact() const
{
unsigned int nSize = BN_num_bytes(this);
unsigned int nCompact = 0;
if (nSize <= 3)
nCompact = BN_get_word(this) << 8*(3-nSize);
else
{
CBigNum bn;
BN_rshift(&bn, this, 8*(nSize-3));
nCompact = BN_get_word(&bn);
}
// The 0x00800000 bit denotes the sign.
// Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
if (nCompact & 0x00800000)
{
nCompact >>= 8;
nSize++;
}
nCompact |= nSize << 24;
nCompact |= (BN_is_negative(this) ? 0x00800000 : 0);
return nCompact;
}
void SetHex(const std::string& str)
{
// skip 0x
const char* psz = str.c_str();
while (isspace(*psz))
psz++;
bool fNegative = false;
if (*psz == '-')
{
fNegative = true;
psz++;
}
if (psz[0] == '0' && tolower(psz[1]) == 'x')
psz += 2;
while (isspace(*psz))
psz++;
// hex string to bignum
*this = 0;
int n;
while ((n = HexDigit(*psz)) != -1)
{
*this <<= 4;
*this += n;
++psz;
}
if (fNegative)
*this = 0 - *this;
}
std::string ToString(int nBase=10) const
{
CAutoBN_CTX pctx;
CBigNum bnBase = nBase;
CBigNum bn0 = 0;
std::string str;
CBigNum bn = *this;
BN_set_negative(&bn, false);
CBigNum dv;
CBigNum rem;
if (BN_cmp(&bn, &bn0) == 0)
return "0";
while (BN_cmp(&bn, &bn0) > 0)
{
if (!BN_div(&dv, &rem, &bn, &bnBase, pctx))
throw bignum_error("CBigNum::ToString() : BN_div failed");
bn = dv;
unsigned int c = rem.getulong();
str += "0123456789abcdef"[c];
}
if (BN_is_negative(this))
str += "-";
reverse(str.begin(), str.end());
return str;
}
std::string GetHex() const
{
return ToString(16);
}
unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION) const
{
return ::GetSerializeSize(getvch(), nType, nVersion);
}
template<typename Stream>
void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION) const
{
::Serialize(s, getvch(), nType, nVersion);
}
template<typename Stream>
void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)
{
std::vector<unsigned char> vch;
::Unserialize(s, vch, nType, nVersion);
setvch(vch);
}
bool operator!() const
{
return BN_is_zero(this);
}
CBigNum& operator+=(const CBigNum& b)
{
if (!BN_add(this, this, &b))
throw bignum_error("CBigNum::operator+= : BN_add failed");
return *this;
}
CBigNum& operator-=(const CBigNum& b)
{
*this = *this - b;
return *this;
}
CBigNum& operator*=(const CBigNum& b)
{
CAutoBN_CTX pctx;
if (!BN_mul(this, this, &b, pctx))
throw bignum_error("CBigNum::operator*= : BN_mul failed");
return *this;
}
CBigNum& operator/=(const CBigNum& b)
{
*this = *this / b;
return *this;
}
CBigNum& operator%=(const CBigNum& b)
{
*this = *this % b;
return *this;
}
CBigNum& operator<<=(unsigned int shift)
{
if (!BN_lshift(this, this, shift))
throw bignum_error("CBigNum:operator<<= : BN_lshift failed");
return *this;
}
CBigNum& operator>>=(unsigned int shift)
{
// Note: BN_rshift segfaults on 64-bit if 2^shift is greater than the number
// if built on ubuntu 9.04 or 9.10, probably depends on version of OpenSSL
CBigNum a = 1;
a <<= shift;
if (BN_cmp(&a, this) > 0)
{
*this = 0;
return *this;
}
if (!BN_rshift(this, this, shift))
throw bignum_error("CBigNum:operator>>= : BN_rshift failed");
return *this;
}
CBigNum& operator++()
{
// prefix operator
if (!BN_add(this, this, BN_value_one()))
throw bignum_error("CBigNum::operator++ : BN_add failed");
return *this;
}
const CBigNum operator++(int)
{
// postfix operator
const CBigNum ret = *this;
++(*this);
return ret;
}
CBigNum& operator--()
{
// prefix operator
CBigNum r;
if (!BN_sub(&r, this, BN_value_one()))
throw bignum_error("CBigNum::operator-- : BN_sub failed");
*this = r;
return *this;
}
const CBigNum operator--(int)
{
// postfix operator
const CBigNum ret = *this;
--(*this);
return ret;
}
friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b);
friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b);
friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b);
};
inline const CBigNum operator+(const CBigNum& a, const CBigNum& b)
{
CBigNum r;
if (!BN_add(&r, &a, &b))
throw bignum_error("CBigNum::operator+ : BN_add failed");
return r;
}
inline const CBigNum operator-(const CBigNum& a, const CBigNum& b)
{
CBigNum r;
if (!BN_sub(&r, &a, &b))
throw bignum_error("CBigNum::operator- : BN_sub failed");
return r;
}
inline const CBigNum operator-(const CBigNum& a)
{
CBigNum r(a);
BN_set_negative(&r, !BN_is_negative(&r));
return r;
}
inline const CBigNum operator*(const CBigNum& a, const CBigNum& b)
{
CAutoBN_CTX pctx;
CBigNum r;
if (!BN_mul(&r, &a, &b, pctx))
throw bignum_error("CBigNum::operator* : BN_mul failed");
return r;
}
inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
{
CAutoBN_CTX pctx;
CBigNum r;
if (!BN_div(&r, NULL, &a, &b, pctx))
throw bignum_error("CBigNum::operator/ : BN_div failed");
return r;
}
inline const CBigNum operator%(const CBigNum& a, const CBigNum& b)
{
CAutoBN_CTX pctx;
CBigNum r;
if (!BN_mod(&r, &a, &b, pctx))
throw bignum_error("CBigNum::operator% : BN_div failed");
return r;
}
inline const CBigNum operator<<(const CBigNum& a, unsigned int shift)
{
CBigNum r;
if (!BN_lshift(&r, &a, shift))
throw bignum_error("CBigNum:operator<< : BN_lshift failed");
return r;
}
inline const CBigNum operator>>(const CBigNum& a, unsigned int shift)
{
CBigNum r = a;
r >>= shift;
return r;
}
inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); }
inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); }
inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); }
inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); }
inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); }
inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); }
#endif

View file

@ -5,7 +5,6 @@
#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD) #define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD)
#define VER_FILEVERSION VER_PRODUCTVERSION #define VER_FILEVERSION VER_PRODUCTVERSION
#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR #define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core developers"
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION FILEVERSION VER_FILEVERSION

View file

@ -7,11 +7,39 @@
#include "init.h" #include "init.h"
#include "rpcclient.h" #include "rpcclient.h"
#include "rpcprotocol.h" #include "rpcprotocol.h"
#include "ui_interface.h" /* for _(...) */ #include "chainparamsbase.h"
#include "chainparams.h"
#include <boost/filesystem/operations.hpp> #include <boost/filesystem/operations.hpp>
#define _(x) std::string(x) /* Keep the _() around in case gettext or such will be used later to translate non-UI */
using namespace std;
using namespace boost;
using namespace boost::asio;
using namespace json_spirit;
std::string HelpMessageCli()
{
string strUsage;
strUsage += _("Options:") + "\n";
strUsage += " -? " + _("This help message") + "\n";
strUsage += " -conf=<file> " + _("Specify configuration file (default: bitcoin.conf)") + "\n";
strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
strUsage += " -testnet " + _("Use the test network") + "\n";
strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be "
"solved instantly. This is intended for regression testing tools and app development.") + "\n";
strUsage += " -rpcconnect=<ip> " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n";
strUsage += " -rpcport=<port> " + _("Connect to JSON-RPC on <port> (default: 8332 or testnet: 18332)") + "\n";
strUsage += " -rpcwait " + _("Wait for RPC server to start") + "\n";
strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
strUsage += "\n" + _("SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
return strUsage;
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
// Start // Start
@ -33,22 +61,23 @@ static bool AppInitRPC(int argc, char* argv[])
fprintf(stderr,"Error reading configuration file: %s\n", e.what()); fprintf(stderr,"Error reading configuration file: %s\n", e.what());
return false; return false;
} }
// Check for -testnet or -regtest parameter (TestNet() calls are only valid after this clause) // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause)
if (!SelectParamsFromCommandLine()) { if (!SelectBaseParamsFromCommandLine()) {
fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n"); fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
return false; return false;
} }
if (argc<2 || mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version"))
if (argc<2 || mapArgs.count("-?") || mapArgs.count("--help"))
{ {
// First part of help message is specific to RPC client std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n";
std::string strUsage = _("Bitcoin Core RPC client version") + " " + FormatFullVersion() + "\n\n" + if (!mapArgs.count("-version"))
_("Usage:") + "\n" + {
strUsage += "\n" + _("Usage:") + "\n" +
" bitcoin-cli [options] <command> [params] " + _("Send command to Bitcoin Core") + "\n" + " bitcoin-cli [options] <command> [params] " + _("Send command to Bitcoin Core") + "\n" +
" bitcoin-cli [options] help " + _("List commands") + "\n" + " bitcoin-cli [options] help " + _("List commands") + "\n" +
" bitcoin-cli [options] help <command> " + _("Get help for a command") + "\n"; " bitcoin-cli [options] help <command> " + _("Get help for a command") + "\n";
strUsage += "\n" + HelpMessageCli(true); strUsage += "\n" + HelpMessageCli();
}
fprintf(stdout, "%s", strUsage.c_str()); fprintf(stdout, "%s", strUsage.c_str());
return false; return false;
@ -56,22 +85,154 @@ static bool AppInitRPC(int argc, char* argv[])
return true; return true;
} }
Object CallRPC(const string& strMethod, const Array& params)
{
if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
throw runtime_error(strprintf(
_("You must set rpcpassword=<password> in the configuration file:\n%s\n"
"If the file does not exist, create it with owner-readable-only file permissions."),
GetConfigFile().string().c_str()));
// Connect to localhost
bool fUseSSL = GetBoolArg("-rpcssl", false);
asio::io_service io_service;
ssl::context context(io_service, ssl::context::sslv23);
context.set_options(ssl::context::no_sslv2);
asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context);
SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL);
iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
bool fWait = GetBoolArg("-rpcwait", false); // -rpcwait means try until server has started
do {
bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort())));
if (fConnected) break;
if (fWait)
MilliSleep(1000);
else
throw runtime_error("couldn't connect to server");
} while (fWait);
// HTTP basic authentication
string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
map<string, string> mapRequestHeaders;
mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64;
// Send request
string strRequest = JSONRPCRequest(strMethod, params, 1);
string strPost = HTTPPost(strRequest, mapRequestHeaders);
stream << strPost << std::flush;
// Receive HTTP reply status
int nProto = 0;
int nStatus = ReadHTTPStatus(stream, nProto);
// Receive HTTP reply message headers and body
map<string, string> mapHeaders;
string strReply;
ReadHTTPMessage(stream, mapHeaders, strReply, nProto);
if (nStatus == HTTP_UNAUTHORIZED)
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR)
throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
else if (strReply.empty())
throw runtime_error("no response from server");
// Parse reply
Value valReply;
if (!read_string(strReply, valReply))
throw runtime_error("couldn't parse reply from server");
const Object& reply = valReply.get_obj();
if (reply.empty())
throw runtime_error("expected reply to have result, error and id properties");
return reply;
}
int CommandLineRPC(int argc, char *argv[])
{
string strPrint;
int nRet = 0;
try
{
// Skip switches
while (argc > 1 && IsSwitchChar(argv[1][0]))
{
argc--;
argv++;
}
// Method
if (argc < 2)
throw runtime_error("too few parameters");
string strMethod = argv[1];
// Parameters default to strings
std::vector<std::string> strParams(&argv[2], &argv[argc]);
Array params = RPCConvertValues(strMethod, strParams);
// Execute
Object reply = CallRPC(strMethod, params);
// Parse reply
const Value& result = find_value(reply, "result");
const Value& error = find_value(reply, "error");
if (error.type() != null_type)
{
// Error
strPrint = "error: " + write_string(error, false);
int code = find_value(error.get_obj(), "code").get_int();
nRet = abs(code);
}
else
{
// Result
if (result.type() == null_type)
strPrint = "";
else if (result.type() == str_type)
strPrint = result.get_str();
else
strPrint = write_string(result, true);
}
}
catch (boost::thread_interrupted) {
throw;
}
catch (std::exception& e) {
strPrint = string("error: ") + e.what();
nRet = EXIT_FAILURE;
}
catch (...) {
PrintExceptionContinue(NULL, "CommandLineRPC()");
throw;
}
if (strPrint != "")
{
fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
}
return nRet;
}
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
SetupEnvironment();
try try
{ {
if(!AppInitRPC(argc, argv)) if(!AppInitRPC(argc, argv))
return abs(RPC_MISC_ERROR); return EXIT_FAILURE;
} }
catch (std::exception& e) { catch (std::exception& e) {
PrintExceptionContinue(&e, "AppInitRPC()"); PrintExceptionContinue(&e, "AppInitRPC()");
return abs(RPC_MISC_ERROR); return EXIT_FAILURE;
} catch (...) { } catch (...) {
PrintExceptionContinue(NULL, "AppInitRPC()"); PrintExceptionContinue(NULL, "AppInitRPC()");
return abs(RPC_MISC_ERROR); return EXIT_FAILURE;
} }
int ret = abs(RPC_MISC_ERROR); int ret = EXIT_FAILURE;
try try
{ {
ret = CommandLineRPC(argc, argv); ret = CommandLineRPC(argc, argv);

View file

@ -5,7 +5,6 @@
#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD) #define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD)
#define VER_FILEVERSION VER_PRODUCTVERSION #define VER_FILEVERSION VER_PRODUCTVERSION
#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR #define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core developers"
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION FILEVERSION VER_FILEVERSION

View file

@ -4,7 +4,6 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "rpcserver.h" #include "rpcserver.h"
#include "rpcclient.h"
#include "init.h" #include "init.h"
#include "main.h" #include "main.h"
#include "noui.h" #include "noui.h"
@ -77,25 +76,27 @@ bool AppInit(int argc, char* argv[])
fprintf(stderr,"Error reading configuration file: %s\n", e.what()); fprintf(stderr,"Error reading configuration file: %s\n", e.what());
return false; return false;
} }
// Check for -testnet or -regtest parameter (TestNet() calls are only valid after this clause) // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
if (!SelectParamsFromCommandLine()) { if (!SelectParamsFromCommandLine()) {
fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n"); fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
return false; return false;
} }
if (mapArgs.count("-?") || mapArgs.count("--help")) if (mapArgs.count("-?") || mapArgs.count("-help") || mapArgs.count("-version"))
{ {
// First part of help message is specific to bitcoind / RPC client std::string strUsage = _("Bitcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n";
std::string strUsage = _("Bitcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n\n" +
_("Usage:") + "\n" + if (mapArgs.count("-version"))
" bitcoind [options] " + _("Start Bitcoin Core Daemon") + "\n" + {
_("Usage (deprecated, use bitcoin-cli):") + "\n" + strUsage += LicenseInfo();
" bitcoind [options] <command> [params] " + _("Send command to Bitcoin Core") + "\n" + }
" bitcoind [options] help " + _("List commands") + "\n" + else
" bitcoind [options] help <command> " + _("Get help for a command") + "\n"; {
strUsage += "\n" + _("Usage:") + "\n" +
" bitcoind [options] " + _("Start Bitcoin Core Daemon") + "\n";
strUsage += "\n" + HelpMessage(HMM_BITCOIND); strUsage += "\n" + HelpMessage(HMM_BITCOIND);
strUsage += "\n" + HelpMessageCli(false); }
fprintf(stdout, "%s", strUsage.c_str()); fprintf(stdout, "%s", strUsage.c_str());
return false; return false;
@ -109,8 +110,8 @@ bool AppInit(int argc, char* argv[])
if (fCommandLine) if (fCommandLine)
{ {
int ret = CommandLineRPC(argc, argv); fprintf(stderr, "Error: There is no RPC client functionality in bitcoind anymore. Use the bitcoin-cli utility instead.\n");
exit(ret); exit(1);
} }
#ifndef WIN32 #ifndef WIN32
fDaemon = GetBoolArg("-daemon", false); fDaemon = GetBoolArg("-daemon", false);
@ -172,15 +173,10 @@ bool AppInit(int argc, char* argv[])
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
bool fRet = false; SetupEnvironment();
// Connect bitcoind signal handlers // Connect bitcoind signal handlers
noui_connect(); noui_connect();
fRet = AppInit(argc, argv); return (AppInit(argc, argv) ? 0 : 1);
if (fRet && fDaemon)
return 0;
return (fRet ? 0 : 1);
} }

View file

@ -94,12 +94,19 @@ bool CBloomFilter::contains(const uint256& hash) const
return contains(data); return contains(data);
} }
void CBloomFilter::clear()
{
vData.assign(vData.size(),0);
isFull = false;
isEmpty = true;
}
bool CBloomFilter::IsWithinSizeConstraints() const bool CBloomFilter::IsWithinSizeConstraints() const
{ {
return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS; return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS;
} }
bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx, const uint256& hash) bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx)
{ {
bool fFound = false; bool fFound = false;
// Match if the filter contains the hash of tx // Match if the filter contains the hash of tx
@ -108,6 +115,7 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx, const uint256& ha
return true; return true;
if (isEmpty) if (isEmpty)
return false; return false;
const uint256& hash = tx.GetHash();
if (contains(hash)) if (contains(hash))
fFound = true; fFound = true;

View file

@ -78,12 +78,14 @@ public:
bool contains(const COutPoint& outpoint) const; bool contains(const COutPoint& outpoint) const;
bool contains(const uint256& hash) const; bool contains(const uint256& hash) const;
void clear();
// True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS // True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS
// (catch a filter which was just deserialized which was too big) // (catch a filter which was just deserialized which was too big)
bool IsWithinSizeConstraints() const; bool IsWithinSizeConstraints() const;
// Also adds any outputs which match the filter to the filter (to match their spending txes) // Also adds any outputs which match the filter to the filter (to match their spending txes)
bool IsRelevantAndUpdate(const CTransaction& tx, const uint256& hash); bool IsRelevantAndUpdate(const CTransaction& tx);
// Checks for empty and full filters to avoid wasting cpu // Checks for empty and full filters to avoid wasting cpu
void UpdateEmptyFull(); void UpdateEmptyFull();

View file

@ -6,12 +6,11 @@
#include "chainparams.h" #include "chainparams.h"
#include "assert.h" #include "assert.h"
#include "core.h"
#include "protocol.h"
#include "util.h" #include "util.h"
#include <boost/assign/list_of.hpp> #include <boost/assign/list_of.hpp>
using namespace std;
using namespace boost::assign; using namespace boost::assign;
// //
@ -100,6 +99,8 @@ unsigned int pnSeed[] =
class CMainParams : public CChainParams { class CMainParams : public CChainParams {
public: public:
CMainParams() { CMainParams() {
networkID = CBaseChainParams::MAIN;
strNetworkID = "main";
// The message start string is designed to be unlikely to occur in normal data. // The message start string is designed to be unlikely to occur in normal data.
// The characters are rarely used upper ASCII, not valid as UTF-8, and produce // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
// a large 4-byte int at any alignment. // a large 4-byte int at any alignment.
@ -109,9 +110,14 @@ public:
pchMessageStart[3] = 0xd9; pchMessageStart[3] = 0xd9;
vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284");
nDefaultPort = 8333; nDefaultPort = 8333;
nRPCPort = 8332; bnProofOfWorkLimit = ~uint256(0) >> 32;
bnProofOfWorkLimit = CBigNum(~uint256(0) >> 32);
nSubsidyHalvingInterval = 210000; nSubsidyHalvingInterval = 210000;
nEnforceBlockUpgradeMajority = 750;
nRejectBlockOutdatedMajority = 950;
nToCheckBlockUpgradeMajority = 1000;
nMinerThreads = 0;
nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
nTargetSpacing = 10 * 60;
// Build the genesis block. Note that the output of the genesis coinbase cannot // Build the genesis block. Note that the output of the genesis coinbase cannot
// be spent as it did not originally exist in the database. // be spent as it did not originally exist in the database.
@ -122,10 +128,10 @@ public:
// CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) // CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
// vMerkleTree: 4a5e1e // vMerkleTree: 4a5e1e
const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
CTransaction txNew; CMutableTransaction txNew;
txNew.vin.resize(1); txNew.vin.resize(1);
txNew.vout.resize(1); txNew.vout.resize(1);
txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
txNew.vout[0].nValue = 50 * COIN; txNew.vout[0].nValue = 50 * COIN;
txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
genesis.vtx.push_back(txNew); genesis.vtx.push_back(txNew);
@ -167,27 +173,25 @@ public:
addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek; addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
vFixedSeeds.push_back(addr); vFixedSeeds.push_back(addr);
} }
}
virtual const CBlock& GenesisBlock() const { return genesis; } fRequireRPCPassword = true;
virtual Network NetworkID() const { return CChainParams::MAIN; } fMiningRequiresPeers = true;
fDefaultCheckMemPool = false;
virtual const vector<CAddress>& FixedSeeds() const { fAllowMinDifficultyBlocks = false;
return vFixedSeeds; fRequireStandard = true;
fMineBlocksOnDemand = false;
} }
protected:
CBlock genesis;
vector<CAddress> vFixedSeeds;
}; };
static CMainParams mainParams; static CMainParams mainParams;
// //
// Testnet (v3) // Testnet (v3)
// //
class CTestNetParams : public CMainParams { class CTestNetParams : public CMainParams {
public: public:
CTestNetParams() { CTestNetParams() {
networkID = CBaseChainParams::TESTNET;
strNetworkID = "test";
// The message start string is designed to be unlikely to occur in normal data. // The message start string is designed to be unlikely to occur in normal data.
// The characters are rarely used upper ASCII, not valid as UTF-8, and produce // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
// a large 4-byte int at any alignment. // a large 4-byte int at any alignment.
@ -197,8 +201,12 @@ public:
pchMessageStart[3] = 0x07; pchMessageStart[3] = 0x07;
vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"); vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a");
nDefaultPort = 18333; nDefaultPort = 18333;
nRPCPort = 18332; nEnforceBlockUpgradeMajority = 51;
strDataDir = "testnet3"; nRejectBlockOutdatedMajority = 75;
nToCheckBlockUpgradeMajority = 100;
nMinerThreads = 0;
nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
nTargetSpacing = 10 * 60;
// Modify the testnet genesis block so the timestamp is valid for a later start. // Modify the testnet genesis block so the timestamp is valid for a later start.
genesis.nTime = 1296688602; genesis.nTime = 1296688602;
@ -208,6 +216,7 @@ public:
vFixedSeeds.clear(); vFixedSeeds.clear();
vSeeds.clear(); vSeeds.clear();
vSeeds.push_back(CDNSSeedData("alexykot.me", "testnet-seed.alexykot.me"));
vSeeds.push_back(CDNSSeedData("bitcoin.petertodd.org", "testnet-seed.bitcoin.petertodd.org")); vSeeds.push_back(CDNSSeedData("bitcoin.petertodd.org", "testnet-seed.bitcoin.petertodd.org"));
vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me")); vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me"));
@ -216,55 +225,73 @@ public:
base58Prefixes[SECRET_KEY] = list_of(239); base58Prefixes[SECRET_KEY] = list_of(239);
base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x35)(0x87)(0xCF); base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x35)(0x87)(0xCF);
base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x35)(0x83)(0x94); base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x35)(0x83)(0x94);
fRequireRPCPassword = true;
fMiningRequiresPeers = true;
fDefaultCheckMemPool = false;
fAllowMinDifficultyBlocks = true;
fRequireStandard = false;
fMineBlocksOnDemand = false;
} }
virtual Network NetworkID() const { return CChainParams::TESTNET; }
}; };
static CTestNetParams testNetParams; static CTestNetParams testNetParams;
// //
// Regression test // Regression test
// //
class CRegTestParams : public CTestNetParams { class CRegTestParams : public CTestNetParams {
public: public:
CRegTestParams() { CRegTestParams() {
networkID = CBaseChainParams::REGTEST;
strNetworkID = "regtest";
pchMessageStart[0] = 0xfa; pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf; pchMessageStart[1] = 0xbf;
pchMessageStart[2] = 0xb5; pchMessageStart[2] = 0xb5;
pchMessageStart[3] = 0xda; pchMessageStart[3] = 0xda;
nSubsidyHalvingInterval = 150; nSubsidyHalvingInterval = 150;
bnProofOfWorkLimit = CBigNum(~uint256(0) >> 1); nEnforceBlockUpgradeMajority = 750;
nRejectBlockOutdatedMajority = 950;
nToCheckBlockUpgradeMajority = 1000;
nMinerThreads = 1;
nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
nTargetSpacing = 10 * 60;
bnProofOfWorkLimit = ~uint256(0) >> 1;
genesis.nTime = 1296688602; genesis.nTime = 1296688602;
genesis.nBits = 0x207fffff; genesis.nBits = 0x207fffff;
genesis.nNonce = 2; genesis.nNonce = 2;
hashGenesisBlock = genesis.GetHash(); hashGenesisBlock = genesis.GetHash();
nDefaultPort = 18444; nDefaultPort = 18444;
strDataDir = "regtest";
assert(hashGenesisBlock == uint256("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); assert(hashGenesisBlock == uint256("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
vSeeds.clear(); // Regtest mode doesn't have any DNS seeds. vSeeds.clear(); // Regtest mode doesn't have any DNS seeds.
}
virtual bool RequireRPCPassword() const { return false; } fRequireRPCPassword = false;
virtual Network NetworkID() const { return CChainParams::REGTEST; } fMiningRequiresPeers = false;
fDefaultCheckMemPool = true;
fAllowMinDifficultyBlocks = true;
fRequireStandard = false;
fMineBlocksOnDemand = true;
}
}; };
static CRegTestParams regTestParams; static CRegTestParams regTestParams;
static CChainParams *pCurrentParams = &mainParams; static CChainParams *pCurrentParams = 0;
const CChainParams &Params() { const CChainParams &Params() {
assert(pCurrentParams);
return *pCurrentParams; return *pCurrentParams;
} }
void SelectParams(CChainParams::Network network) { void SelectParams(CBaseChainParams::Network network) {
SelectBaseParams(network);
switch (network) { switch (network) {
case CChainParams::MAIN: case CBaseChainParams::MAIN:
pCurrentParams = &mainParams; pCurrentParams = &mainParams;
break; break;
case CChainParams::TESTNET: case CBaseChainParams::TESTNET:
pCurrentParams = &testNetParams; pCurrentParams = &testNetParams;
break; break;
case CChainParams::REGTEST: case CBaseChainParams::REGTEST:
pCurrentParams = &regTestParams; pCurrentParams = &regTestParams;
break; break;
default: default:
@ -274,19 +301,9 @@ void SelectParams(CChainParams::Network network) {
} }
bool SelectParamsFromCommandLine() { bool SelectParamsFromCommandLine() {
bool fRegTest = GetBoolArg("-regtest", false); if (!SelectBaseParamsFromCommandLine())
bool fTestNet = GetBoolArg("-testnet", false);
if (fTestNet && fRegTest) {
return false; return false;
}
if (fRegTest) { SelectParams(BaseParams().NetworkID());
SelectParams(CChainParams::REGTEST);
} else if (fTestNet) {
SelectParams(CChainParams::TESTNET);
} else {
SelectParams(CChainParams::MAIN);
}
return true; return true;
} }

View file

@ -6,22 +6,18 @@
#ifndef BITCOIN_CHAIN_PARAMS_H #ifndef BITCOIN_CHAIN_PARAMS_H
#define BITCOIN_CHAIN_PARAMS_H #define BITCOIN_CHAIN_PARAMS_H
#include "bignum.h" #include "core.h"
#include "chainparamsbase.h"
#include "protocol.h"
#include "uint256.h" #include "uint256.h"
#include <vector> #include <vector>
using namespace std;
#define MESSAGE_START_SIZE 4
typedef unsigned char MessageStartChars[MESSAGE_START_SIZE]; typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
class CAddress;
class CBlock;
struct CDNSSeedData { struct CDNSSeedData {
string name, host; std::string name, host;
CDNSSeedData(const string &strName, const string &strHost) : name(strName), host(strHost) {} CDNSSeedData(const std::string &strName, const std::string &strHost) : name(strName), host(strHost) {}
}; };
/** /**
@ -34,14 +30,6 @@ struct CDNSSeedData {
class CChainParams class CChainParams
{ {
public: public:
enum Network {
MAIN,
TESTNET,
REGTEST,
MAX_NETWORK_TYPES
};
enum Base58Type { enum Base58Type {
PUBKEY_ADDRESS, PUBKEY_ADDRESS,
SCRIPT_ADDRESS, SCRIPT_ADDRESS,
@ -54,32 +42,67 @@ public:
const uint256& HashGenesisBlock() const { return hashGenesisBlock; } const uint256& HashGenesisBlock() const { return hashGenesisBlock; }
const MessageStartChars& MessageStart() const { return pchMessageStart; } const MessageStartChars& MessageStart() const { return pchMessageStart; }
const vector<unsigned char>& AlertKey() const { return vAlertPubKey; } const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
int GetDefaultPort() const { return nDefaultPort; } int GetDefaultPort() const { return nDefaultPort; }
const CBigNum& ProofOfWorkLimit() const { return bnProofOfWorkLimit; } const uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; } int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; }
virtual const CBlock& GenesisBlock() const = 0; /* Used to check majorities for block version upgrade */
virtual bool RequireRPCPassword() const { return true; } int EnforceBlockUpgradeMajority() const { return nEnforceBlockUpgradeMajority; }
const string& DataDir() const { return strDataDir; } int RejectBlockOutdatedMajority() const { return nRejectBlockOutdatedMajority; }
virtual Network NetworkID() const = 0; int ToCheckBlockUpgradeMajority() const { return nToCheckBlockUpgradeMajority; }
const vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
const std::vector<unsigned char> &Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } /* Used if GenerateBitcoins is called with a negative number of threads */
virtual const vector<CAddress>& FixedSeeds() const = 0; int DefaultMinerThreads() const { return nMinerThreads; }
int RPCPort() const { return nRPCPort; } const CBlock& GenesisBlock() const { return genesis; }
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; }
/* Allow mining of a min-difficulty block */
bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; }
/* Make standard checks */
bool RequireStandard() const { return fRequireStandard; }
int64_t TargetTimespan() const { return nTargetTimespan; }
int64_t TargetSpacing() const { return nTargetSpacing; }
int64_t Interval() const { return nTargetTimespan / nTargetSpacing; }
/* Make miner stop after a block is found. In RPC, don't return
* until nGenProcLimit blocks are generated */
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
CBaseChainParams::Network NetworkID() const { return networkID; }
/* Return the BIP70 network string (main, test or regtest) */
std::string NetworkIDString() const { return strNetworkID; }
const std::vector<CDNSSeedData>& DNSSeeds() const { return vSeeds; }
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
const std::vector<CAddress>& FixedSeeds() const { return vFixedSeeds; }
protected: protected:
CChainParams() {} CChainParams() {}
uint256 hashGenesisBlock; uint256 hashGenesisBlock;
MessageStartChars pchMessageStart; MessageStartChars pchMessageStart;
// Raw pub key bytes for the broadcast alert signing key. // Raw pub key bytes for the broadcast alert signing key.
vector<unsigned char> vAlertPubKey; std::vector<unsigned char> vAlertPubKey;
int nDefaultPort; int nDefaultPort;
int nRPCPort; uint256 bnProofOfWorkLimit;
CBigNum bnProofOfWorkLimit;
int nSubsidyHalvingInterval; int nSubsidyHalvingInterval;
string strDataDir; int nEnforceBlockUpgradeMajority;
vector<CDNSSeedData> vSeeds; int nRejectBlockOutdatedMajority;
int nToCheckBlockUpgradeMajority;
int64_t nTargetTimespan;
int64_t nTargetSpacing;
int nMinerThreads;
std::vector<CDNSSeedData> vSeeds;
std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES]; std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES];
CBaseChainParams::Network networkID;
std::string strNetworkID;
CBlock genesis;
std::vector<CAddress> vFixedSeeds;
bool fRequireRPCPassword;
bool fMiningRequiresPeers;
bool fDefaultCheckMemPool;
bool fAllowMinDifficultyBlocks;
bool fRequireStandard;
bool fMineBlocksOnDemand;
}; };
/** /**
@ -89,7 +112,7 @@ protected:
const CChainParams &Params(); const CChainParams &Params();
/** Sets the params returned by Params() to those for the given network. */ /** Sets the params returned by Params() to those for the given network. */
void SelectParams(CChainParams::Network network); void SelectParams(CBaseChainParams::Network network);
/** /**
* Looks for -regtest or -testnet and then calls SelectParams as appropriate. * Looks for -regtest or -testnet and then calls SelectParams as appropriate.
@ -97,13 +120,4 @@ void SelectParams(CChainParams::Network network);
*/ */
bool SelectParamsFromCommandLine(); bool SelectParamsFromCommandLine();
inline bool TestNet() {
// Note: it's deliberate that this returns "false" for regression test mode.
return Params().NetworkID() == CChainParams::TESTNET;
}
inline bool RegTest() {
return Params().NetworkID() == CChainParams::REGTEST;
}
#endif #endif

93
src/chainparamsbase.cpp Normal file
View file

@ -0,0 +1,93 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "chainparamsbase.h"
#include "assert.h"
#include "util.h"
#include <boost/assign/list_of.hpp>
using namespace boost::assign;
//
// Main network
//
class CBaseMainParams : public CBaseChainParams {
public:
CBaseMainParams() {
networkID = CBaseChainParams::MAIN;
nRPCPort = 8332;
}
};
static CBaseMainParams mainParams;
//
// Testnet (v3)
//
class CBaseTestNetParams : public CBaseMainParams {
public:
CBaseTestNetParams() {
networkID = CBaseChainParams::TESTNET;
nRPCPort = 18332;
strDataDir = "testnet3";
}
};
static CBaseTestNetParams testNetParams;
//
// Regression test
//
class CBaseRegTestParams : public CBaseTestNetParams {
public:
CBaseRegTestParams() {
networkID = CBaseChainParams::REGTEST;
strDataDir = "regtest";
}
};
static CBaseRegTestParams regTestParams;
static CBaseChainParams *pCurrentBaseParams = 0;
const CBaseChainParams &BaseParams() {
assert(pCurrentBaseParams);
return *pCurrentBaseParams;
}
void SelectBaseParams(CBaseChainParams::Network network) {
switch (network) {
case CBaseChainParams::MAIN:
pCurrentBaseParams = &mainParams;
break;
case CBaseChainParams::TESTNET:
pCurrentBaseParams = &testNetParams;
break;
case CBaseChainParams::REGTEST:
pCurrentBaseParams = &regTestParams;
break;
default:
assert(false && "Unimplemented network");
return;
}
}
bool SelectBaseParamsFromCommandLine() {
bool fRegTest = GetBoolArg("-regtest", false);
bool fTestNet = GetBoolArg("-testnet", false);
if (fTestNet && fRegTest) {
return false;
}
if (fRegTest) {
SelectBaseParams(CBaseChainParams::REGTEST);
} else if (fTestNet) {
SelectBaseParams(CBaseChainParams::TESTNET);
} else {
SelectBaseParams(CBaseChainParams::MAIN);
}
return true;
}

52
src/chainparamsbase.h Normal file
View file

@ -0,0 +1,52 @@
// Copyright (c) 2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_CHAIN_PARAMS_BASE_H
#define BITCOIN_CHAIN_PARAMS_BASE_H
#include <vector>
#include <string>
/**
* CBaseChainParams defines the base parameters (shared between bitcoin-cli and bitcoind)
* of a given instance of the Bitcoin system.
*/
class CBaseChainParams
{
public:
enum Network {
MAIN,
TESTNET,
REGTEST,
MAX_NETWORK_TYPES
};
const std::string& DataDir() const { return strDataDir; }
int RPCPort() const { return nRPCPort; }
Network NetworkID() const { return networkID; }
protected:
CBaseChainParams() {}
int nRPCPort;
std::string strDataDir;
Network networkID;
};
/**
* Return the currently selected parameters. This won't change after app startup
* outside of the unit tests.
*/
const CBaseChainParams &BaseParams();
/** Sets the params returned by Params() to those for the given network. */
void SelectBaseParams(CBaseChainParams::Network network);
/**
* Looks for -regtest or -testnet and then calls SelectParams as appropriate.
* Returns false if an invalid combination is given.
*/
bool SelectBaseParamsFromCommandLine();
#endif

View file

@ -12,8 +12,8 @@
#include <boost/assign/list_of.hpp> // for 'map_list_of()' #include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
namespace Checkpoints namespace Checkpoints {
{
typedef std::map<int, uint256> MapCheckpoints; typedef std::map<int, uint256> MapCheckpoints;
// How many times we expect transactions after the last checkpoint to // How many times we expect transactions after the last checkpoint to
@ -66,8 +66,8 @@ namespace Checkpoints
; ;
static const CCheckpointData dataTestnet = { static const CCheckpointData dataTestnet = {
&mapCheckpointsTestnet, &mapCheckpointsTestnet,
1338180505, 1337966069,
16341, 1488,
300 300
}; };
@ -83,9 +83,9 @@ namespace Checkpoints
}; };
const CCheckpointData &Checkpoints() { const CCheckpointData &Checkpoints() {
if (Params().NetworkID() == CChainParams::TESTNET) if (Params().NetworkID() == CBaseChainParams::TESTNET)
return dataTestnet; return dataTestnet;
else if (Params().NetworkID() == CChainParams::MAIN) else if (Params().NetworkID() == CBaseChainParams::MAIN)
return data; return data;
else else
return dataRegtest; return dataRegtest;
@ -127,7 +127,7 @@ namespace Checkpoints
} else { } else {
double nCheapBefore = data.nTransactionsLastCheckpoint; double nCheapBefore = data.nTransactionsLastCheckpoint;
double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint; double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay; double nExpensiveAfter = (nNow - pindex->GetBlockTime())/86400.0*data.fTransactionsPerDay;
fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor; fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor; fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
} }
@ -161,4 +161,5 @@ namespace Checkpoints
} }
return NULL; return NULL;
} }
}
} // namespace Checkpoints

View file

@ -13,8 +13,8 @@ class uint256;
/** Block-chain checkpoints are compiled-in sanity checks. /** Block-chain checkpoints are compiled-in sanity checks.
* They are updated every release or three. * They are updated every release or three.
*/ */
namespace Checkpoints namespace Checkpoints {
{
// Returns true if block passes checkpoint checks // Returns true if block passes checkpoint checks
bool CheckBlock(int nHeight, const uint256& hash); bool CheckBlock(int nHeight, const uint256& hash);
@ -27,6 +27,7 @@ namespace Checkpoints
double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks = true); double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks = true);
extern bool fEnabled; extern bool fEnabled;
}
} //namespace Checkpoints
#endif #endif

View file

@ -2,13 +2,13 @@
#define CLIENTVERSION_H #define CLIENTVERSION_H
#if defined(HAVE_CONFIG_H) #if defined(HAVE_CONFIG_H)
#include "bitcoin-config.h" #include "config/bitcoin-config.h"
#else #else
// //
// client versioning and copyright year // client versioning and copyright year
// //
// These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it // These need to be macros, as version.cpp's and bitcoin*-res.rc's voodoo requires it
#define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MAJOR 0
#define CLIENT_VERSION_MINOR 9 #define CLIENT_VERSION_MINOR 9
#define CLIENT_VERSION_REVISION 99 #define CLIENT_VERSION_REVISION 99
@ -28,4 +28,7 @@
#define STRINGIZE(X) DO_STRINGIZE(X) #define STRINGIZE(X) DO_STRINGIZE(X)
#define DO_STRINGIZE(X) #X #define DO_STRINGIZE(X) #X
// Copyright string used in Windows .rc files
#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core Developers"
#endif // CLIENTVERSION_H #endif // CLIENTVERSION_H

View file

@ -55,7 +55,7 @@ bool CCoinsView::SetCoins(const uint256 &txid, const CCoins &coins) { return fal
bool CCoinsView::HaveCoins(const uint256 &txid) { return false; } bool CCoinsView::HaveCoins(const uint256 &txid) { return false; }
uint256 CCoinsView::GetBestBlock() { return uint256(0); } uint256 CCoinsView::GetBestBlock() { return uint256(0); }
bool CCoinsView::SetBestBlock(const uint256 &hashBlock) { return false; } bool CCoinsView::SetBestBlock(const uint256 &hashBlock) { return false; }
bool CCoinsView::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock) { return false; } bool CCoinsView::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
bool CCoinsView::GetStats(CCoinsStats &stats) { return false; } bool CCoinsView::GetStats(CCoinsStats &stats) { return false; }
@ -66,7 +66,7 @@ bool CCoinsViewBacked::HaveCoins(const uint256 &txid) { return base->HaveCoins(t
uint256 CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); } uint256 CCoinsViewBacked::GetBestBlock() { return base->GetBestBlock(); }
bool CCoinsViewBacked::SetBestBlock(const uint256 &hashBlock) { return base->SetBestBlock(hashBlock); } bool CCoinsViewBacked::SetBestBlock(const uint256 &hashBlock) { return base->SetBestBlock(hashBlock); }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
bool CCoinsViewBacked::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); } bool CCoinsViewBacked::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stats); } bool CCoinsViewBacked::GetStats(CCoinsStats &stats) { return base->GetStats(stats); }
CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), hashBlock(0) { } CCoinsViewCache::CCoinsViewCache(CCoinsView &baseIn, bool fDummy) : CCoinsViewBacked(baseIn), hashBlock(0) { }
@ -83,20 +83,20 @@ bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) {
return false; return false;
} }
std::map<uint256,CCoins>::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) { CCoinsMap::iterator CCoinsViewCache::FetchCoins(const uint256 &txid) {
std::map<uint256,CCoins>::iterator it = cacheCoins.lower_bound(txid); CCoinsMap::iterator it = cacheCoins.lower_bound(txid);
if (it != cacheCoins.end() && it->first == txid) if (it != cacheCoins.end() && it->first == txid)
return it; return it;
CCoins tmp; CCoins tmp;
if (!base->GetCoins(txid,tmp)) if (!base->GetCoins(txid,tmp))
return cacheCoins.end(); return cacheCoins.end();
std::map<uint256,CCoins>::iterator ret = cacheCoins.insert(it, std::make_pair(txid, CCoins())); CCoinsMap::iterator ret = cacheCoins.insert(it, std::make_pair(txid, CCoins()));
tmp.swap(ret->second); tmp.swap(ret->second);
return ret; return ret;
} }
CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) { CCoins &CCoinsViewCache::GetCoins(const uint256 &txid) {
std::map<uint256,CCoins>::iterator it = FetchCoins(txid); CCoinsMap::iterator it = FetchCoins(txid);
assert(it != cacheCoins.end()); assert(it != cacheCoins.end());
return it->second; return it->second;
} }
@ -121,8 +121,8 @@ bool CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
return true; return true;
} }
bool CCoinsViewCache::BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlockIn) { bool CCoinsViewCache::BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
for (std::map<uint256, CCoins>::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++) for (CCoinsMap::const_iterator it = mapCoins.begin(); it != mapCoins.end(); it++)
cacheCoins[it->first] = it->second; cacheCoins[it->first] = it->second;
hashBlock = hashBlockIn; hashBlock = hashBlockIn;
return true; return true;

View file

@ -239,6 +239,7 @@ public:
} }
}; };
typedef std::map<uint256,CCoins> CCoinsMap;
struct CCoinsStats struct CCoinsStats
{ {
@ -275,7 +276,7 @@ public:
virtual bool SetBestBlock(const uint256 &hashBlock); virtual bool SetBestBlock(const uint256 &hashBlock);
// Do a bulk modification (multiple SetCoins + one SetBestBlock) // Do a bulk modification (multiple SetCoins + one SetBestBlock)
virtual bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock); virtual bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
// Calculate statistics about the unspent transaction output set // Calculate statistics about the unspent transaction output set
virtual bool GetStats(CCoinsStats &stats); virtual bool GetStats(CCoinsStats &stats);
@ -299,7 +300,7 @@ public:
uint256 GetBestBlock(); uint256 GetBestBlock();
bool SetBestBlock(const uint256 &hashBlock); bool SetBestBlock(const uint256 &hashBlock);
void SetBackend(CCoinsView &viewIn); void SetBackend(CCoinsView &viewIn);
bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock); bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
bool GetStats(CCoinsStats &stats); bool GetStats(CCoinsStats &stats);
}; };
@ -309,7 +310,7 @@ class CCoinsViewCache : public CCoinsViewBacked
{ {
protected: protected:
uint256 hashBlock; uint256 hashBlock;
std::map<uint256,CCoins> cacheCoins; CCoinsMap cacheCoins;
public: public:
CCoinsViewCache(CCoinsView &baseIn, bool fDummy = false); CCoinsViewCache(CCoinsView &baseIn, bool fDummy = false);
@ -320,7 +321,7 @@ public:
bool HaveCoins(const uint256 &txid); bool HaveCoins(const uint256 &txid);
uint256 GetBestBlock(); uint256 GetBestBlock();
bool SetBestBlock(const uint256 &hashBlock); bool SetBestBlock(const uint256 &hashBlock);
bool BatchWrite(const std::map<uint256, CCoins> &mapCoins, const uint256 &hashBlock); bool BatchWrite(const CCoinsMap &mapCoins, const uint256 &hashBlock);
// Return a modifiable reference to a CCoins. Check HaveCoins first. // Return a modifiable reference to a CCoins. Check HaveCoins first.
// Many methods explicitly require a CCoinsViewCache because of this method, to reduce // Many methods explicitly require a CCoinsViewCache because of this method, to reduce
@ -352,7 +353,7 @@ public:
const CTxOut &GetOutputFor(const CTxIn& input); const CTxOut &GetOutputFor(const CTxIn& input);
private: private:
std::map<uint256,CCoins>::iterator FetchCoins(const uint256 &txid); CCoinsMap::iterator FetchCoins(const uint256 &txid);
}; };
#endif #endif

View file

@ -1,6 +1,15 @@
#include "bitcoin-config.h" // Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include "config/bitcoin-config.h"
#endif
#include <cstddef> #include <cstddef>
#if defined(HAVE_SYS_SELECT_H)
#include <sys/select.h> #include <sys/select.h>
#endif
// Prior to GLIBC_2.14, memcpy was aliased to memmove. // Prior to GLIBC_2.14, memcpy was aliased to memmove.
extern "C" void* memmove(void* a, const void* b, size_t c); extern "C" void* memmove(void* a, const void* b, size_t c);

View file

@ -0,0 +1,67 @@
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include "config/bitcoin-config.h"
#endif
#include <cstddef>
#if defined(HAVE_SYS_SELECT_H)
#include <sys/select.h>
#endif
extern "C" void* memcpy(void* a, const void* b, size_t c);
void* memcpy_int(void* a, const void* b, size_t c)
{
return memcpy(a,b,c);
}
namespace {
// trigger: Use the memcpy_int wrapper which calls our internal memcpy.
// A direct call to memcpy may be optimized away by the compiler.
// test: Fill an array with a sequence of integers. memcpy to a new empty array.
// Verify that the arrays are equal. Use an odd size to decrease the odds of
// the call being optimized away.
template <unsigned int T>
bool sanity_test_memcpy()
{
unsigned int memcpy_test[T];
unsigned int memcpy_verify[T] = {};
for (unsigned int i = 0; i != T; ++i)
memcpy_test[i] = i;
memcpy_int(memcpy_verify,memcpy_test,sizeof(memcpy_test));
for (unsigned int i = 0; i != T; ++i)
{
if(memcpy_verify[i] != i)
return false;
}
return true;
}
#if defined(HAVE_SYS_SELECT_H)
// trigger: Call FD_SET to trigger __fdelt_chk. FORTIFY_SOURCE must be defined
// as >0 and optimizations must be set to at least -O2.
// test: Add a file descriptor to an empty fd_set. Verify that it has been
// correctly added.
bool sanity_test_fdelt()
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(0, &fds);
return FD_ISSET(0,&fds);
}
#endif
} // anon namespace
bool glibc_sanity_test()
{
#if defined(HAVE_SYS_SELECT_H)
if (!sanity_test_fdelt())
return false;
#endif
return sanity_test_memcpy<1025>();
}

View file

@ -1,10 +1,14 @@
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <cstddef> #include <cstddef>
#include <istream> #include <istream>
#include <stdexcept> #include <stdexcept>
#include <typeinfo> #include <typeinfo>
#ifndef _GLIBCXX_USE_NOEXCEPT #ifndef _GLIBCXX_USE_NOEXCEPT
#define _GLIBCXX_USE_NOEXCEPT throw() #define _GLIBCXX_USE_NOEXCEPT throw()
#endif #endif
namespace std { namespace std {
@ -35,6 +39,7 @@ struct _List_node_base
__position->_M_prev->_M_next = this; __position->_M_prev->_M_next = this;
__position->_M_prev = this; __position->_M_prev = this;
} }
void _M_unhook() __attribute__((used)) void _M_unhook() __attribute__((used))
{ {
_List_node_base* const __next_node = _M_next; _List_node_base* const __next_node = _M_next;
@ -42,6 +47,7 @@ struct _List_node_base
__prev_node->_M_next = __next_node; __prev_node->_M_next = __next_node;
__next_node->_M_prev = __prev_node; __next_node->_M_prev = __prev_node;
} }
_List_node_base* _M_next; _List_node_base* _M_next;
_List_node_base* _M_prev; _List_node_base* _M_prev;
}; };
@ -61,8 +67,8 @@ out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { }
// Used with permission. // Used with permission.
// See: https://github.com/madlib/madlib/commit/c3db418c0d34d6813608f2137fef1012ce03043d // See: https://github.com/madlib/madlib/commit/c3db418c0d34d6813608f2137fef1012ce03043d
void void ctype<char>::_M_widen_init() const
ctype<char>::_M_widen_init() const { {
char __tmp[sizeof(_M_widen)]; char __tmp[sizeof(_M_widen)];
for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i) for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i)
__tmp[__i] = __i; __tmp[__i] = __i;

View file

@ -0,0 +1,65 @@
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <list>
#include <locale>
#include <stdexcept>
namespace{
// trigger: use ctype<char>::widen to trigger ctype<char>::_M_widen_init().
// test: convert a char from narrow to wide and back. Verify that the result
// matches the original.
bool sanity_test_widen(char testchar)
{
const std::ctype<char>& test(std::use_facet< std::ctype<char> >(std::locale()));
return test.narrow(test.widen(testchar),'b') == testchar;
}
// trigger: use list::push_back and list::pop_back to trigger _M_hook and
// _M_unhook.
// test: Push a sequence of integers into a list. Pop them off and verify that
// they match the original sequence.
bool sanity_test_list(unsigned int size)
{
std::list<unsigned int> test;
for (unsigned int i = 0; i != size; ++i)
test.push_back(i+1);
if (test.size() != size)
return false;
while (!test.empty())
{
if(test.back() != test.size())
return false;
test.pop_back();
}
return true;
}
} // anon namespace
// trigger: string::at(x) on an empty string to trigger __throw_out_of_range_fmt.
// test: force std::string to throw an out_of_range exception. Verify that
// it's caught correctly.
bool sanity_test_range_fmt()
{
std::string test;
try
{
test.at(1);
}
catch (const std::out_of_range&)
{
return true;
}
catch (...){}
return false;
}
bool glibcxx_sanity_test()
{
return sanity_test_widen('a') && sanity_test_list(100) && sanity_test_range_fmt();
}

11
src/compat/sanity.h Normal file
View file

@ -0,0 +1,11 @@
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCON_COMPAT_SANITY_H
#define BITCON_COMPAT_SANITY_H
bool glibc_sanity_test();
bool glibcxx_sanity_test();
#endif // BITCON_COMPAT_SANITY_H

0
src/config/.empty Normal file
View file

View file

@ -72,38 +72,67 @@ void CTxOut::print() const
LogPrintf("%s\n", ToString()); LogPrintf("%s\n", ToString());
} }
uint256 CTransaction::GetHash() const CFeeRate::CFeeRate(int64_t nFeePaid, size_t nSize)
{
if (nSize > 0)
nSatoshisPerK = nFeePaid*1000/nSize;
else
nSatoshisPerK = 0;
}
int64_t CFeeRate::GetFee(size_t nSize) const
{
return nSatoshisPerK*nSize / 1000;
}
std::string CFeeRate::ToString() const
{
std::string result = FormatMoney(nSatoshisPerK) + " BTC/kB";
return result;
}
CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}
CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {}
uint256 CMutableTransaction::GetHash() const
{ {
return SerializeHash(*this); return SerializeHash(*this);
} }
bool CTransaction::IsNewerThan(const CTransaction& old) const void CTransaction::UpdateHash() const
{ {
if (vin.size() != old.vin.size()) *const_cast<uint256*>(&hash) = SerializeHash(*this);
return false; }
for (unsigned int i = 0; i < vin.size(); i++)
if (vin[i].prevout != old.vin[i].prevout)
return false;
bool fNewer = false; CTransaction::CTransaction() : hash(0), nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) { }
unsigned int nLowest = std::numeric_limits<unsigned int>::max();
CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {
UpdateHash();
}
CTransaction& CTransaction::operator=(const CTransaction &tx) {
*const_cast<int*>(&nVersion) = tx.nVersion;
*const_cast<std::vector<CTxIn>*>(&vin) = tx.vin;
*const_cast<std::vector<CTxOut>*>(&vout) = tx.vout;
*const_cast<unsigned int*>(&nLockTime) = tx.nLockTime;
*const_cast<uint256*>(&hash) = tx.hash;
return *this;
}
bool CTransaction::IsEquivalentTo(const CTransaction& tx) const
{
if (nVersion != tx.nVersion ||
nLockTime != tx.nLockTime ||
vin.size() != tx.vin.size() ||
vout != tx.vout)
return false;
for (unsigned int i = 0; i < vin.size(); i++) for (unsigned int i = 0; i < vin.size(); i++)
{ {
if (vin[i].nSequence != old.vin[i].nSequence) if (vin[i].nSequence != tx.vin[i].nSequence ||
{ vin[i].prevout != tx.vin[i].prevout)
if (vin[i].nSequence <= nLowest) return false;
{
fNewer = false;
nLowest = vin[i].nSequence;
} }
if (old.vin[i].nSequence < nLowest) return true;
{
fNewer = true;
nLowest = old.vin[i].nSequence;
}
}
}
return fNewer;
} }
int64_t CTransaction::GetValueOut() const int64_t CTransaction::GetValueOut() const
@ -140,7 +169,7 @@ double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSiz
std::string CTransaction::ToString() const std::string CTransaction::ToString() const
{ {
std::string str; std::string str;
str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%"PRIszu", vout.size=%"PRIszu", nLockTime=%u)\n", str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
GetHash().ToString().substr(0,10), GetHash().ToString().substr(0,10),
nVersion, nVersion,
vin.size(), vin.size(),
@ -269,7 +298,7 @@ uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMer
void CBlock::print() const void CBlock::print() const
{ {
LogPrintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%"PRIszu")\n", LogPrintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
GetHash().ToString(), GetHash().ToString(),
nVersion, nVersion,
hashPrevBlock.ToString(), hashPrevBlock.ToString(),

View file

@ -112,6 +112,32 @@ public:
/** Type-safe wrapper class to for fee rates
* (how much to pay based on transaction size)
*/
class CFeeRate
{
private:
int64_t nSatoshisPerK; // unit is satoshis-per-1,000-bytes
public:
CFeeRate() : nSatoshisPerK(0) { }
explicit CFeeRate(int64_t _nSatoshisPerK): nSatoshisPerK(_nSatoshisPerK) { }
CFeeRate(int64_t nFeePaid, size_t nSize);
CFeeRate(const CFeeRate& other) { nSatoshisPerK = other.nSatoshisPerK; }
int64_t GetFee(size_t size) const; // unit returned is satoshis
int64_t GetFeePerK() const { return GetFee(1000); } // satoshis-per-1000-bytes
friend bool operator<(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK < b.nSatoshisPerK; }
friend bool operator>(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK > b.nSatoshisPerK; }
friend bool operator==(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK == b.nSatoshisPerK; }
friend bool operator<=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK <= b.nSatoshisPerK; }
friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; }
std::string ToString() const;
IMPLEMENT_SERIALIZE( READWRITE(nSatoshisPerK); )
};
/** An output of a transaction. It contains the public key that the next input /** An output of a transaction. It contains the public key that the next input
* must be able to sign with to claim it. * must be able to sign with to claim it.
@ -148,17 +174,18 @@ public:
uint256 GetHash() const; uint256 GetHash() const;
bool IsDust(int64_t nMinRelayTxFee) const bool IsDust(CFeeRate minRelayTxFee) const
{ {
// "Dust" is defined in terms of CTransaction::nMinRelayTxFee, // "Dust" is defined in terms of CTransaction::minRelayTxFee,
// which has units satoshis-per-kilobyte. // which has units satoshis-per-kilobyte.
// If you'd pay more than 1/3 in fees // If you'd pay more than 1/3 in fees
// to spend something, then we consider it dust. // to spend something, then we consider it dust.
// A typical txout is 34 bytes big, and will // A typical txout is 34 bytes big, and will
// need a CTxIn of at least 148 bytes to spend, // need a CTxIn of at least 148 bytes to spend:
// so dust is a txout less than 546 satoshis // so dust is a txout less than 546 satoshis
// with default nMinRelayTxFee. // with default minRelayTxFee.
return ((nValue*1000)/(3*((int)GetSerializeSize(SER_DISK,0)+148)) < nMinRelayTxFee); size_t nSize = GetSerializeSize(SER_DISK,0)+148u;
return (nValue < 3*minRelayTxFee.GetFee(nSize));
} }
friend bool operator==(const CTxOut& a, const CTxOut& b) friend bool operator==(const CTxOut& a, const CTxOut& b)
@ -177,49 +204,59 @@ public:
}; };
struct CMutableTransaction;
/** The basic transaction that is broadcasted on the network and contained in /** The basic transaction that is broadcasted on the network and contained in
* blocks. A transaction can contain multiple inputs and outputs. * blocks. A transaction can contain multiple inputs and outputs.
*/ */
class CTransaction class CTransaction
{ {
private:
/** Memory only. */
const uint256 hash;
void UpdateHash() const;
public: public:
static int64_t nMinTxFee;
static int64_t nMinRelayTxFee;
static const int CURRENT_VERSION=1; static const int CURRENT_VERSION=1;
int nVersion;
std::vector<CTxIn> vin;
std::vector<CTxOut> vout;
unsigned int nLockTime;
CTransaction() // The local variables are made const to prevent unintended modification
{ // without updating the cached hash value. However, CTransaction is not
SetNull(); // actually immutable; deserialization and assignment are implemented,
} // and bypass the constness. This is safe, as they update the entire
// structure, including the hash.
const int nVersion;
const std::vector<CTxIn> vin;
const std::vector<CTxOut> vout;
const unsigned int nLockTime;
IMPLEMENT_SERIALIZE /** Construct a CTransaction that qualifies as IsNull() */
( CTransaction();
READWRITE(this->nVersion);
/** Convert a CMutableTransaction into a CTransaction. */
CTransaction(const CMutableTransaction &tx);
CTransaction& operator=(const CTransaction& tx);
IMPLEMENT_SERIALIZE(
READWRITE(*const_cast<int*>(&this->nVersion));
nVersion = this->nVersion; nVersion = this->nVersion;
READWRITE(vin); READWRITE(*const_cast<std::vector<CTxIn>*>(&vin));
READWRITE(vout); READWRITE(*const_cast<std::vector<CTxOut>*>(&vout));
READWRITE(nLockTime); READWRITE(*const_cast<unsigned int*>(&nLockTime));
if (fRead)
UpdateHash();
) )
void SetNull() bool IsNull() const {
{ return vin.empty() && vout.empty();
nVersion = CTransaction::CURRENT_VERSION;
vin.clear();
vout.clear();
nLockTime = 0;
} }
bool IsNull() const const uint256& GetHash() const {
{ return hash;
return (vin.empty() && vout.empty());
} }
uint256 GetHash() const; // True if only scriptSigs are different
bool IsNewerThan(const CTransaction& old) const; bool IsEquivalentTo(const CTransaction& tx) const;
// Return sum of txouts. // Return sum of txouts.
int64_t GetValueOut() const; int64_t GetValueOut() const;
@ -236,22 +273,43 @@ public:
friend bool operator==(const CTransaction& a, const CTransaction& b) friend bool operator==(const CTransaction& a, const CTransaction& b)
{ {
return (a.nVersion == b.nVersion && return a.hash == b.hash;
a.vin == b.vin &&
a.vout == b.vout &&
a.nLockTime == b.nLockTime);
} }
friend bool operator!=(const CTransaction& a, const CTransaction& b) friend bool operator!=(const CTransaction& a, const CTransaction& b)
{ {
return !(a == b); return a.hash != b.hash;
} }
std::string ToString() const; std::string ToString() const;
void print() const; void print() const;
}; };
/** A mutable version of CTransaction. */
struct CMutableTransaction
{
int nVersion;
std::vector<CTxIn> vin;
std::vector<CTxOut> vout;
unsigned int nLockTime;
CMutableTransaction();
CMutableTransaction(const CTransaction& tx);
IMPLEMENT_SERIALIZE(
READWRITE(this->nVersion);
nVersion = this->nVersion;
READWRITE(vin);
READWRITE(vout);
READWRITE(nLockTime);
)
/** Compute the hash of this CMutableTransaction. This is computed on the
* fly, as opposed to GetHash() in CTransaction, which uses a cached result.
*/
uint256 GetHash() const;
};
/** wrapper for CTxOut that provides a more compact serialization */ /** wrapper for CTxOut that provides a more compact serialization */
class CTxOutCompressor class CTxOutCompressor
{ {
@ -440,12 +498,6 @@ public:
uint256 BuildMerkleTree() const; uint256 BuildMerkleTree() const;
const uint256 &GetTxHash(unsigned int nIndex) const {
assert(vMerkleTree.size() > 0); // BuildMerkleTree must have been called first
assert(nIndex < vtx.size());
return vMerkleTree[nIndex];
}
std::vector<uint256> GetMerkleBranch(int nIndex) const; std::vector<uint256> GetMerkleBranch(int nIndex) const;
static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex); static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex);
void print() const; void print() const;

93
src/crypto/common.h Normal file
View file

@ -0,0 +1,93 @@
// Copyright (c) 2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_CRYPTO_COMMON_H
#define BITCOIN_CRYPTO_COMMON_H
#if defined(HAVE_CONFIG_H)
#include "bitcoin-config.h"
#endif
#include <stdint.h>
#if defined(HAVE_ENDIAN_H)
#include <endian.h>
#endif
uint32_t static inline ReadLE32(const unsigned char *ptr) {
#if HAVE_DECL_LE32TOH == 1
return le32toh(*((uint32_t*)ptr));
#elif !defined(WORDS_BIGENDIAN)
return *((uint32_t*)ptr);
#else
return ((uint32_t)ptr[3] << 24 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[0]);
#endif
}
uint64_t static inline ReadLE64(const unsigned char *ptr) {
#if HAVE_DECL_LE64TOH == 1
return le64toh(*((uint64_t*)ptr));
#elif !defined(WORDS_BIGENDIAN)
return *((uint64_t*)ptr);
#else
return ((uint64_t)ptr[7] << 56 | (uint64_t)ptr[6] << 48 | (uint64_t)ptr[5] << 40 | (uint64_t)ptr[4] << 32 |
(uint64_t)ptr[3] << 24 | (uint64_t)ptr[2] << 16 | (uint64_t)ptr[1] << 8 | (uint64_t)ptr[0]);
#endif
}
void static inline WriteLE32(unsigned char *ptr, uint32_t x) {
#if HAVE_DECL_HTOLE32 == 1
*((uint32_t*)ptr) = htole32(x);
#elif !defined(WORDS_BIGENDIAN)
*((uint32_t*)ptr) = x;
#else
ptr[3] = x >> 24; ptr[2] = x >> 16; ptr[1] = x >> 8; ptr[0] = x;
#endif
}
void static inline WriteLE64(unsigned char *ptr, uint64_t x) {
#if HAVE_DECL_HTOLE64 == 1
*((uint64_t*)ptr) = htole64(x);
#elif !defined(WORDS_BIGENDIAN)
*((uint64_t*)ptr) = x;
#else
ptr[7] = x >> 56; ptr[6] = x >> 48; ptr[5] = x >> 40; ptr[4] = x >> 32;
ptr[3] = x >> 24; ptr[2] = x >> 16; ptr[1] = x >> 8; ptr[0] = x;
#endif
}
uint32_t static inline ReadBE32(const unsigned char *ptr) {
#if HAVE_DECL_BE32TOH == 1
return be32toh(*((uint32_t*)ptr));
#else
return ((uint32_t)ptr[0] << 24 | (uint32_t)ptr[1] << 16 | (uint32_t)ptr[2] << 8 | (uint32_t)ptr[3]);
#endif
}
uint64_t static inline ReadBE64(const unsigned char *ptr) {
#if HAVE_DECL_BE64TOH == 1
return be64toh(*((uint64_t*)ptr));
#else
return ((uint64_t)ptr[0] << 56 | (uint64_t)ptr[1] << 48 | (uint64_t)ptr[2] << 40 | (uint64_t)ptr[3] << 32 |
(uint64_t)ptr[4] << 24 | (uint64_t)ptr[5] << 16 | (uint64_t)ptr[6] << 8 | (uint64_t)ptr[7]);
#endif
}
void static inline WriteBE32(unsigned char *ptr, uint32_t x) {
#if HAVE_DECL_HTOBE32 == 1
*((uint32_t*)ptr) = htobe32(x);
#else
ptr[0] = x >> 24; ptr[1] = x >> 16; ptr[2] = x >> 8; ptr[3] = x;
#endif
}
void static inline WriteBE64(unsigned char *ptr, uint64_t x) {
#if HAVE_DECL_HTOBE64 == 1
*((uint64_t*)ptr) = htobe64(x);
#else
ptr[0] = x >> 56; ptr[1] = x >> 48; ptr[2] = x >> 40; ptr[3] = x >> 32;
ptr[4] = x >> 24; ptr[5] = x >> 16; ptr[6] = x >> 8; ptr[7] = x;
#endif
}
#endif

204
src/crypto/ripemd160.cpp Normal file
View file

@ -0,0 +1,204 @@
// Copyright (c) 2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "crypto/ripemd160.h"
#include "crypto/common.h"
#include <string.h>
// Internal implementation code.
namespace {
/// Internal RIPEMD-160 implementation.
namespace ripemd160 {
uint32_t inline f1(uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; }
uint32_t inline f2(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (~x & z); }
uint32_t inline f3(uint32_t x, uint32_t y, uint32_t z) { return (x | ~y) ^ z; }
uint32_t inline f4(uint32_t x, uint32_t y, uint32_t z) { return (x & z) | (y & ~z); }
uint32_t inline f5(uint32_t x, uint32_t y, uint32_t z) { return x ^ (y | ~z); }
/** Initialize RIPEMD-160 state. */
void inline Initialize(uint32_t *s) {
s[0] = 0x67452301ul;
s[1] = 0xEFCDAB89ul;
s[2] = 0x98BADCFEul;
s[3] = 0x10325476ul;
s[4] = 0xC3D2E1F0ul;
}
uint32_t inline rol(uint32_t x, int i) { return (x << i) | (x >> (32-i)); }
void inline Round(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t f, uint32_t x, uint32_t k, int r) {
a = rol(a + f + x + k, r) + e;
c = rol(c, 10);
}
void inline R11(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); }
void inline R21(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r); }
void inline R31(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r); }
void inline R41(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r); }
void inline R51(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r); }
void inline R12(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r); }
void inline R22(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r); }
void inline R32(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r); }
void inline R42(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r); }
void inline R52(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); }
/** Perform a RIPEMD-160 transformation, processing a 64-byte chunk. */
void Transform(uint32_t *s, const unsigned char *chunk) {
uint32_t a1 = s[0], b1 = s[1], c1 = s[2], d1 = s[3], e1 = s[4];
uint32_t a2 = a1 , b2 = b1 , c2 = c1 , d2 = d1 , e2 = e1 ;
uint32_t w0 = ReadLE32(chunk + 0), w1 = ReadLE32(chunk + 4), w2 = ReadLE32(chunk + 8), w3 = ReadLE32(chunk + 12);
uint32_t w4 = ReadLE32(chunk + 16), w5 = ReadLE32(chunk + 20), w6 = ReadLE32(chunk + 24), w7 = ReadLE32(chunk + 28);
uint32_t w8 = ReadLE32(chunk + 32), w9 = ReadLE32(chunk + 36), w10 = ReadLE32(chunk + 40), w11 = ReadLE32(chunk + 44);
uint32_t w12 = ReadLE32(chunk + 48), w13 = ReadLE32(chunk + 52), w14 = ReadLE32(chunk + 56), w15 = ReadLE32(chunk + 60);
R11(a1, b1, c1, d1, e1, w0 , 11); R12(a2, b2, c2, d2, e2, w5 , 8);
R11(e1, a1, b1, c1, d1, w1 , 14); R12(e2, a2, b2, c2, d2, w14, 9);
R11(d1, e1, a1, b1, c1, w2 , 15); R12(d2, e2, a2, b2, c2, w7 , 9);
R11(c1, d1, e1, a1, b1, w3 , 12); R12(c2, d2, e2, a2, b2, w0 , 11);
R11(b1, c1, d1, e1, a1, w4 , 5); R12(b2, c2, d2, e2, a2, w9 , 13);
R11(a1, b1, c1, d1, e1, w5 , 8); R12(a2, b2, c2, d2, e2, w2 , 15);
R11(e1, a1, b1, c1, d1, w6 , 7); R12(e2, a2, b2, c2, d2, w11, 15);
R11(d1, e1, a1, b1, c1, w7 , 9); R12(d2, e2, a2, b2, c2, w4 , 5);
R11(c1, d1, e1, a1, b1, w8 , 11); R12(c2, d2, e2, a2, b2, w13, 7);
R11(b1, c1, d1, e1, a1, w9 , 13); R12(b2, c2, d2, e2, a2, w6 , 7);
R11(a1, b1, c1, d1, e1, w10, 14); R12(a2, b2, c2, d2, e2, w15, 8);
R11(e1, a1, b1, c1, d1, w11, 15); R12(e2, a2, b2, c2, d2, w8 , 11);
R11(d1, e1, a1, b1, c1, w12, 6); R12(d2, e2, a2, b2, c2, w1 , 14);
R11(c1, d1, e1, a1, b1, w13, 7); R12(c2, d2, e2, a2, b2, w10, 14);
R11(b1, c1, d1, e1, a1, w14, 9); R12(b2, c2, d2, e2, a2, w3 , 12);
R11(a1, b1, c1, d1, e1, w15, 8); R12(a2, b2, c2, d2, e2, w12, 6);
R21(e1, a1, b1, c1, d1, w7 , 7); R22(e2, a2, b2, c2, d2, w6 , 9);
R21(d1, e1, a1, b1, c1, w4 , 6); R22(d2, e2, a2, b2, c2, w11, 13);
R21(c1, d1, e1, a1, b1, w13, 8); R22(c2, d2, e2, a2, b2, w3 , 15);
R21(b1, c1, d1, e1, a1, w1 , 13); R22(b2, c2, d2, e2, a2, w7 , 7);
R21(a1, b1, c1, d1, e1, w10, 11); R22(a2, b2, c2, d2, e2, w0 , 12);
R21(e1, a1, b1, c1, d1, w6 , 9); R22(e2, a2, b2, c2, d2, w13, 8);
R21(d1, e1, a1, b1, c1, w15, 7); R22(d2, e2, a2, b2, c2, w5 , 9);
R21(c1, d1, e1, a1, b1, w3 , 15); R22(c2, d2, e2, a2, b2, w10, 11);
R21(b1, c1, d1, e1, a1, w12, 7); R22(b2, c2, d2, e2, a2, w14, 7);
R21(a1, b1, c1, d1, e1, w0 , 12); R22(a2, b2, c2, d2, e2, w15, 7);
R21(e1, a1, b1, c1, d1, w9 , 15); R22(e2, a2, b2, c2, d2, w8 , 12);
R21(d1, e1, a1, b1, c1, w5 , 9); R22(d2, e2, a2, b2, c2, w12, 7);
R21(c1, d1, e1, a1, b1, w2 , 11); R22(c2, d2, e2, a2, b2, w4 , 6);
R21(b1, c1, d1, e1, a1, w14, 7); R22(b2, c2, d2, e2, a2, w9 , 15);
R21(a1, b1, c1, d1, e1, w11, 13); R22(a2, b2, c2, d2, e2, w1 , 13);
R21(e1, a1, b1, c1, d1, w8 , 12); R22(e2, a2, b2, c2, d2, w2 , 11);
R31(d1, e1, a1, b1, c1, w3 , 11); R32(d2, e2, a2, b2, c2, w15, 9);
R31(c1, d1, e1, a1, b1, w10, 13); R32(c2, d2, e2, a2, b2, w5 , 7);
R31(b1, c1, d1, e1, a1, w14, 6); R32(b2, c2, d2, e2, a2, w1 , 15);
R31(a1, b1, c1, d1, e1, w4 , 7); R32(a2, b2, c2, d2, e2, w3 , 11);
R31(e1, a1, b1, c1, d1, w9 , 14); R32(e2, a2, b2, c2, d2, w7 , 8);
R31(d1, e1, a1, b1, c1, w15, 9); R32(d2, e2, a2, b2, c2, w14, 6);
R31(c1, d1, e1, a1, b1, w8 , 13); R32(c2, d2, e2, a2, b2, w6 , 6);
R31(b1, c1, d1, e1, a1, w1 , 15); R32(b2, c2, d2, e2, a2, w9 , 14);
R31(a1, b1, c1, d1, e1, w2 , 14); R32(a2, b2, c2, d2, e2, w11, 12);
R31(e1, a1, b1, c1, d1, w7 , 8); R32(e2, a2, b2, c2, d2, w8 , 13);
R31(d1, e1, a1, b1, c1, w0 , 13); R32(d2, e2, a2, b2, c2, w12, 5);
R31(c1, d1, e1, a1, b1, w6 , 6); R32(c2, d2, e2, a2, b2, w2 , 14);
R31(b1, c1, d1, e1, a1, w13, 5); R32(b2, c2, d2, e2, a2, w10, 13);
R31(a1, b1, c1, d1, e1, w11, 12); R32(a2, b2, c2, d2, e2, w0 , 13);
R31(e1, a1, b1, c1, d1, w5 , 7); R32(e2, a2, b2, c2, d2, w4 , 7);
R31(d1, e1, a1, b1, c1, w12, 5); R32(d2, e2, a2, b2, c2, w13, 5);
R41(c1, d1, e1, a1, b1, w1 , 11); R42(c2, d2, e2, a2, b2, w8 , 15);
R41(b1, c1, d1, e1, a1, w9 , 12); R42(b2, c2, d2, e2, a2, w6 , 5);
R41(a1, b1, c1, d1, e1, w11, 14); R42(a2, b2, c2, d2, e2, w4 , 8);
R41(e1, a1, b1, c1, d1, w10, 15); R42(e2, a2, b2, c2, d2, w1 , 11);
R41(d1, e1, a1, b1, c1, w0 , 14); R42(d2, e2, a2, b2, c2, w3 , 14);
R41(c1, d1, e1, a1, b1, w8 , 15); R42(c2, d2, e2, a2, b2, w11, 14);
R41(b1, c1, d1, e1, a1, w12, 9); R42(b2, c2, d2, e2, a2, w15, 6);
R41(a1, b1, c1, d1, e1, w4 , 8); R42(a2, b2, c2, d2, e2, w0 , 14);
R41(e1, a1, b1, c1, d1, w13, 9); R42(e2, a2, b2, c2, d2, w5 , 6);
R41(d1, e1, a1, b1, c1, w3 , 14); R42(d2, e2, a2, b2, c2, w12, 9);
R41(c1, d1, e1, a1, b1, w7 , 5); R42(c2, d2, e2, a2, b2, w2 , 12);
R41(b1, c1, d1, e1, a1, w15, 6); R42(b2, c2, d2, e2, a2, w13, 9);
R41(a1, b1, c1, d1, e1, w14, 8); R42(a2, b2, c2, d2, e2, w9 , 12);
R41(e1, a1, b1, c1, d1, w5 , 6); R42(e2, a2, b2, c2, d2, w7 , 5);
R41(d1, e1, a1, b1, c1, w6 , 5); R42(d2, e2, a2, b2, c2, w10, 15);
R41(c1, d1, e1, a1, b1, w2 , 12); R42(c2, d2, e2, a2, b2, w14, 8);
R51(b1, c1, d1, e1, a1, w4 , 9); R52(b2, c2, d2, e2, a2, w12, 8);
R51(a1, b1, c1, d1, e1, w0 , 15); R52(a2, b2, c2, d2, e2, w15, 5);
R51(e1, a1, b1, c1, d1, w5 , 5); R52(e2, a2, b2, c2, d2, w10, 12);
R51(d1, e1, a1, b1, c1, w9 , 11); R52(d2, e2, a2, b2, c2, w4 , 9);
R51(c1, d1, e1, a1, b1, w7 , 6); R52(c2, d2, e2, a2, b2, w1 , 12);
R51(b1, c1, d1, e1, a1, w12, 8); R52(b2, c2, d2, e2, a2, w5 , 5);
R51(a1, b1, c1, d1, e1, w2 , 13); R52(a2, b2, c2, d2, e2, w8 , 14);
R51(e1, a1, b1, c1, d1, w10, 12); R52(e2, a2, b2, c2, d2, w7 , 6);
R51(d1, e1, a1, b1, c1, w14, 5); R52(d2, e2, a2, b2, c2, w6 , 8);
R51(c1, d1, e1, a1, b1, w1 , 12); R52(c2, d2, e2, a2, b2, w2 , 13);
R51(b1, c1, d1, e1, a1, w3 , 13); R52(b2, c2, d2, e2, a2, w13, 6);
R51(a1, b1, c1, d1, e1, w8 , 14); R52(a2, b2, c2, d2, e2, w14, 5);
R51(e1, a1, b1, c1, d1, w11, 11); R52(e2, a2, b2, c2, d2, w0 , 15);
R51(d1, e1, a1, b1, c1, w6 , 8); R52(d2, e2, a2, b2, c2, w3 , 13);
R51(c1, d1, e1, a1, b1, w15, 5); R52(c2, d2, e2, a2, b2, w9 , 11);
R51(b1, c1, d1, e1, a1, w13, 6); R52(b2, c2, d2, e2, a2, w11, 11);
uint32_t t = s[0];
s[0] = s[1] + c1 + d2;
s[1] = s[2] + d1 + e2;
s[2] = s[3] + e1 + a2;
s[3] = s[4] + a1 + b2;
s[4] = t + b1 + c2;
}
} // namespace ripemd160
} // namespace
////// RIPEMD160
CRIPEMD160::CRIPEMD160() : bytes(0) {
ripemd160::Initialize(s);
}
CRIPEMD160& CRIPEMD160::Write(const unsigned char *data, size_t len) {
const unsigned char *end = data + len;
size_t bufsize = bytes % 64;
if (bufsize && bufsize + len >= 64) {
// Fill the buffer, and process it.
memcpy(buf + bufsize, data, 64 - bufsize);
bytes += 64 - bufsize;
data += 64 - bufsize;
ripemd160::Transform(s, buf);
bufsize = 0;
}
while (end >= data + 64) {
// Process full chunks directly from the source.
ripemd160::Transform(s, data);
bytes += 64;
data += 64;
}
if (end > data) {
// Fill the buffer with what remains.
memcpy(buf + bufsize, data, end - data);
bytes += end - data;
}
return *this;
}
void CRIPEMD160::Finalize(unsigned char hash[OUTPUT_SIZE]) {
static const unsigned char pad[64] = {0x80};
unsigned char sizedesc[8];
WriteLE64(sizedesc, bytes << 3);
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
Write(sizedesc, 8);
WriteLE32(hash, s[0]);
WriteLE32(hash+4, s[1]);
WriteLE32(hash+8, s[2]);
WriteLE32(hash+12, s[3]);
WriteLE32(hash+16, s[4]);
}
CRIPEMD160& CRIPEMD160::Reset() {
bytes = 0;
ripemd160::Initialize(s);
return *this;
}

27
src/crypto/ripemd160.h Normal file
View file

@ -0,0 +1,27 @@
// Copyright (c) 2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_RIPEMD160_H
#define BITCOIN_RIPEMD160_H
#include <stdint.h>
#include <stdlib.h>
/** A hasher class for RIPEMD-160. */
class CRIPEMD160 {
private:
uint32_t s[5];
unsigned char buf[64];
size_t bytes;
public:
static const size_t OUTPUT_SIZE = 20;
CRIPEMD160();
CRIPEMD160& Write(const unsigned char *data, size_t len);
void Finalize(unsigned char hash[OUTPUT_SIZE]);
CRIPEMD160& Reset();
};
#endif

192
src/crypto/sha1.cpp Normal file
View file

@ -0,0 +1,192 @@
// Copyright (c) 2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "crypto/sha1.h"
#include "crypto/common.h"
#include <string.h>
// Internal implementation code.
namespace {
/// Internal SHA-1 implementation.
namespace sha1 {
/** One round of SHA-1. */
void inline Round(uint32_t a, uint32_t &b, uint32_t c, uint32_t d, uint32_t &e,
uint32_t f, uint32_t k, uint32_t w) {
e += ((a << 5) | (a >> 27)) + f + k + w;
b = (b << 30) | (b >> 2);
}
uint32_t inline f1(uint32_t b, uint32_t c, uint32_t d) { return d ^ (b & (c ^ d)); }
uint32_t inline f2(uint32_t b, uint32_t c, uint32_t d) { return b ^ c ^ d; }
uint32_t inline f3(uint32_t b, uint32_t c, uint32_t d) { return (b & c) | (d & (b | c)); }
uint32_t inline left(uint32_t x) { return (x << 1) | (x >> 31); }
/** Initialize SHA-1 state. */
void inline Initialize(uint32_t *s) {
s[0] = 0x67452301ul;
s[1] = 0xEFCDAB89ul;
s[2] = 0x98BADCFEul;
s[3] = 0x10325476ul;
s[4] = 0xC3D2E1F0ul;
}
const uint32_t k1 = 0x5A827999ul;
const uint32_t k2 = 0x6ED9EBA1ul;
const uint32_t k3 = 0x8F1BBCDCul;
const uint32_t k4 = 0xCA62C1D6ul;
/** Perform a SHA-1 transformation, processing a 64-byte chunk. */
void Transform(uint32_t *s, const unsigned char *chunk) {
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4];
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
Round(a, b, c, d, e, f1(b, c, d), k1, w0 = ReadBE32(chunk + 0));
Round(e, a, b, c, d, f1(a, b, c), k1, w1 = ReadBE32(chunk + 4));
Round(d, e, a, b, c, f1(e, a, b), k1, w2 = ReadBE32(chunk + 8));
Round(c, d, e, a, b, f1(d, e, a), k1, w3 = ReadBE32(chunk + 12));
Round(b, c, d, e, a, f1(c, d, e), k1, w4 = ReadBE32(chunk + 16));
Round(a, b, c, d, e, f1(b, c, d), k1, w5 = ReadBE32(chunk + 20));
Round(e, a, b, c, d, f1(a, b, c), k1, w6 = ReadBE32(chunk + 24));
Round(d, e, a, b, c, f1(e, a, b), k1, w7 = ReadBE32(chunk + 28));
Round(c, d, e, a, b, f1(d, e, a), k1, w8 = ReadBE32(chunk + 32));
Round(b, c, d, e, a, f1(c, d, e), k1, w9 = ReadBE32(chunk + 36));
Round(a, b, c, d, e, f1(b, c, d), k1, w10 = ReadBE32(chunk + 40));
Round(e, a, b, c, d, f1(a, b, c), k1, w11 = ReadBE32(chunk + 44));
Round(d, e, a, b, c, f1(e, a, b), k1, w12 = ReadBE32(chunk + 48));
Round(c, d, e, a, b, f1(d, e, a), k1, w13 = ReadBE32(chunk + 52));
Round(b, c, d, e, a, f1(c, d, e), k1, w14 = ReadBE32(chunk + 56));
Round(a, b, c, d, e, f1(b, c, d), k1, w15 = ReadBE32(chunk + 60));
Round(e, a, b, c, d, f1(a, b, c), k1, w0 = left(w0 ^ w13 ^ w8 ^ w2 ));
Round(d, e, a, b, c, f1(e, a, b), k1, w1 = left(w1 ^ w14 ^ w9 ^ w3 ));
Round(c, d, e, a, b, f1(d, e, a), k1, w2 = left(w2 ^ w15 ^ w10 ^ w4 ));
Round(b, c, d, e, a, f1(c, d, e), k1, w3 = left(w3 ^ w0 ^ w11 ^ w5 ));
Round(a, b, c, d, e, f2(b, c, d), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6 ));
Round(e, a, b, c, d, f2(a, b, c), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7 ));
Round(d, e, a, b, c, f2(e, a, b), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8 ));
Round(c, d, e, a, b, f2(d, e, a), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9 ));
Round(b, c, d, e, a, f2(c, d, e), k2, w8 = left(w8 ^ w5 ^ w0 ^ w10));
Round(a, b, c, d, e, f2(b, c, d), k2, w9 = left(w9 ^ w6 ^ w1 ^ w11));
Round(e, a, b, c, d, f2(a, b, c), k2, w10 = left(w10 ^ w7 ^ w2 ^ w12));
Round(d, e, a, b, c, f2(e, a, b), k2, w11 = left(w11 ^ w8 ^ w3 ^ w13));
Round(c, d, e, a, b, f2(d, e, a), k2, w12 = left(w12 ^ w9 ^ w4 ^ w14));
Round(b, c, d, e, a, f2(c, d, e), k2, w13 = left(w13 ^ w10 ^ w5 ^ w15));
Round(a, b, c, d, e, f2(b, c, d), k2, w14 = left(w14 ^ w11 ^ w6 ^ w0 ));
Round(e, a, b, c, d, f2(a, b, c), k2, w15 = left(w15 ^ w12 ^ w7 ^ w1 ));
Round(d, e, a, b, c, f2(e, a, b), k2, w0 = left(w0 ^ w13 ^ w8 ^ w2 ));
Round(c, d, e, a, b, f2(d, e, a), k2, w1 = left(w1 ^ w14 ^ w9 ^ w3 ));
Round(b, c, d, e, a, f2(c, d, e), k2, w2 = left(w2 ^ w15 ^ w10 ^ w4 ));
Round(a, b, c, d, e, f2(b, c, d), k2, w3 = left(w3 ^ w0 ^ w11 ^ w5 ));
Round(e, a, b, c, d, f2(a, b, c), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6 ));
Round(d, e, a, b, c, f2(e, a, b), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7 ));
Round(c, d, e, a, b, f2(d, e, a), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8 ));
Round(b, c, d, e, a, f2(c, d, e), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9 ));
Round(a, b, c, d, e, f3(b, c, d), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));
Round(e, a, b, c, d, f3(a, b, c), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));
Round(d, e, a, b, c, f3(e, a, b), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));
Round(c, d, e, a, b, f3(d, e, a), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));
Round(b, c, d, e, a, f3(c, d, e), k3, w12 = left(w12 ^ w9 ^ w4 ^ w14));
Round(a, b, c, d, e, f3(b, c, d), k3, w13 = left(w13 ^ w10 ^ w5 ^ w15));
Round(e, a, b, c, d, f3(a, b, c), k3, w14 = left(w14 ^ w11 ^ w6 ^ w0 ));
Round(d, e, a, b, c, f3(e, a, b), k3, w15 = left(w15 ^ w12 ^ w7 ^ w1 ));
Round(c, d, e, a, b, f3(d, e, a), k3, w0 = left(w0 ^ w13 ^ w8 ^ w2 ));
Round(b, c, d, e, a, f3(c, d, e), k3, w1 = left(w1 ^ w14 ^ w9 ^ w3 ));
Round(a, b, c, d, e, f3(b, c, d), k3, w2 = left(w2 ^ w15 ^ w10 ^ w4 ));
Round(e, a, b, c, d, f3(a, b, c), k3, w3 = left(w3 ^ w0 ^ w11 ^ w5 ));
Round(d, e, a, b, c, f3(e, a, b), k3, w4 = left(w4 ^ w1 ^ w12 ^ w6 ));
Round(c, d, e, a, b, f3(d, e, a), k3, w5 = left(w5 ^ w2 ^ w13 ^ w7 ));
Round(b, c, d, e, a, f3(c, d, e), k3, w6 = left(w6 ^ w3 ^ w14 ^ w8 ));
Round(a, b, c, d, e, f3(b, c, d), k3, w7 = left(w7 ^ w4 ^ w15 ^ w9 ));
Round(e, a, b, c, d, f3(a, b, c), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));
Round(d, e, a, b, c, f3(e, a, b), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));
Round(c, d, e, a, b, f3(d, e, a), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));
Round(b, c, d, e, a, f3(c, d, e), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));
Round(a, b, c, d, e, f2(b, c, d), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));
Round(e, a, b, c, d, f2(a, b, c), k4, w13 = left(w13 ^ w10 ^ w5 ^ w15));
Round(d, e, a, b, c, f2(e, a, b), k4, w14 = left(w14 ^ w11 ^ w6 ^ w0 ));
Round(c, d, e, a, b, f2(d, e, a), k4, w15 = left(w15 ^ w12 ^ w7 ^ w1 ));
Round(b, c, d, e, a, f2(c, d, e), k4, w0 = left(w0 ^ w13 ^ w8 ^ w2 ));
Round(a, b, c, d, e, f2(b, c, d), k4, w1 = left(w1 ^ w14 ^ w9 ^ w3 ));
Round(e, a, b, c, d, f2(a, b, c), k4, w2 = left(w2 ^ w15 ^ w10 ^ w4 ));
Round(d, e, a, b, c, f2(e, a, b), k4, w3 = left(w3 ^ w0 ^ w11 ^ w5 ));
Round(c, d, e, a, b, f2(d, e, a), k4, w4 = left(w4 ^ w1 ^ w12 ^ w6 ));
Round(b, c, d, e, a, f2(c, d, e), k4, w5 = left(w5 ^ w2 ^ w13 ^ w7 ));
Round(a, b, c, d, e, f2(b, c, d), k4, w6 = left(w6 ^ w3 ^ w14 ^ w8 ));
Round(e, a, b, c, d, f2(a, b, c), k4, w7 = left(w7 ^ w4 ^ w15 ^ w9 ));
Round(d, e, a, b, c, f2(e, a, b), k4, w8 = left(w8 ^ w5 ^ w0 ^ w10));
Round(c, d, e, a, b, f2(d, e, a), k4, w9 = left(w9 ^ w6 ^ w1 ^ w11));
Round(b, c, d, e, a, f2(c, d, e), k4, w10 = left(w10 ^ w7 ^ w2 ^ w12));
Round(a, b, c, d, e, f2(b, c, d), k4, w11 = left(w11 ^ w8 ^ w3 ^ w13));
Round(e, a, b, c, d, f2(a, b, c), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));
Round(d, e, a, b, c, f2(e, a, b), k4, left(w13 ^ w10 ^ w5 ^ w15));
Round(c, d, e, a, b, f2(d, e, a), k4, left(w14 ^ w11 ^ w6 ^ w0 ));
Round(b, c, d, e, a, f2(c, d, e), k4, left(w15 ^ w12 ^ w7 ^ w1 ));
s[0] += a;
s[1] += b;
s[2] += c;
s[3] += d;
s[4] += e;
}
} // namespace sha1
} // namespace
////// SHA1
CSHA1::CSHA1() : bytes(0) {
sha1::Initialize(s);
}
CSHA1& CSHA1::Write(const unsigned char *data, size_t len) {
const unsigned char *end = data + len;
size_t bufsize = bytes % 64;
if (bufsize && bufsize + len >= 64) {
// Fill the buffer, and process it.
memcpy(buf + bufsize, data, 64 - bufsize);
bytes += 64 - bufsize;
data += 64 - bufsize;
sha1::Transform(s, buf);
bufsize = 0;
}
while (end >= data + 64) {
// Process full chunks directly from the source.
sha1::Transform(s, data);
bytes += 64;
data += 64;
}
if (end > data) {
// Fill the buffer with what remains.
memcpy(buf + bufsize, data, end - data);
bytes += end - data;
}
return *this;
}
void CSHA1::Finalize(unsigned char hash[OUTPUT_SIZE]) {
static const unsigned char pad[64] = {0x80};
unsigned char sizedesc[8];
WriteBE64(sizedesc, bytes << 3);
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
Write(sizedesc, 8);
WriteBE32(hash, s[0]);
WriteBE32(hash+4, s[1]);
WriteBE32(hash+8, s[2]);
WriteBE32(hash+12, s[3]);
WriteBE32(hash+16, s[4]);
}
CSHA1& CSHA1::Reset() {
bytes = 0;
sha1::Initialize(s);
return *this;
}

27
src/crypto/sha1.h Normal file
View file

@ -0,0 +1,27 @@
// Copyright (c) 2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SHA1_H
#define BITCOIN_SHA1_H
#include <stdint.h>
#include <stdlib.h>
/** A hasher class for SHA1. */
class CSHA1 {
private:
uint32_t s[5];
unsigned char buf[64];
size_t bytes;
public:
static const size_t OUTPUT_SIZE = 20;
CSHA1();
CSHA1& Write(const unsigned char *data, size_t len);
void Finalize(unsigned char hash[OUTPUT_SIZE]);
CSHA1& Reset();
};
#endif

398
src/crypto/sha2.cpp Normal file
View file

@ -0,0 +1,398 @@
// Copyright (c) 2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "crypto/sha2.h"
#include "crypto/common.h"
#include <string.h>
// Internal implementation code.
namespace {
/// Internal SHA-256 implementation.
namespace sha256 {
uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }
uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }
uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
/** One round of SHA-256. */
void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t &d,
uint32_t e, uint32_t f, uint32_t g, uint32_t &h,
uint32_t k, uint32_t w) {
uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
uint32_t t2 = Sigma0(a) + Maj(a, b, c);
d += t1;
h = t1 + t2;
}
/** Initialize SHA-256 state. */
void inline Initialize(uint32_t *s) {
s[0] = 0x6a09e667ul;
s[1] = 0xbb67ae85ul;
s[2] = 0x3c6ef372ul;
s[3] = 0xa54ff53aul;
s[4] = 0x510e527ful;
s[5] = 0x9b05688cul;
s[6] = 0x1f83d9abul;
s[7] = 0x5be0cd19ul;
}
/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
void Transform(uint32_t *s, const unsigned char *chunk) {
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0));
Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4));
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8));
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12));
Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16));
Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20));
Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24));
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28));
Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32));
Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36));
Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40));
Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44));
Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48));
Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52));
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56));
Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60));
Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0( w1));
Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0( w2));
Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1( w0) + w11 + sigma0( w3));
Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1( w1) + w12 + sigma0( w4));
Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1( w2) + w13 + sigma0( w5));
Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1( w3) + w14 + sigma0( w6));
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1( w4) + w15 + sigma0( w7));
Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1( w5) + w0 + sigma0( w8));
Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1( w6) + w1 + sigma0( w9));
Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1( w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1( w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1( w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0( w0));
Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0( w1));
Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0( w2));
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1( w0) + w11 + sigma0( w3));
Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1( w1) + w12 + sigma0( w4));
Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1( w2) + w13 + sigma0( w5));
Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1( w3) + w14 + sigma0( w6));
Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1( w4) + w15 + sigma0( w7));
Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1( w5) + w0 + sigma0( w8));
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1( w6) + w1 + sigma0( w9));
Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1( w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1( w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1( w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0( w0));
Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0( w1));
Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0( w2));
Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1( w0) + w11 + sigma0( w3));
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1( w1) + w12 + sigma0( w4));
Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1( w2) + w13 + sigma0( w5));
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1( w3) + w14 + sigma0( w6));
Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1( w4) + w15 + sigma0( w7));
Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1( w5) + w0 + sigma0( w8));
Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1( w6) + w1 + sigma0( w9));
Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1( w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1( w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1( w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0( w0));
s[0] += a;
s[1] += b;
s[2] += c;
s[3] += d;
s[4] += e;
s[5] += f;
s[6] += g;
s[7] += h;
}
} // namespace sha256
/// Internal SHA-512 implementation.
namespace sha512 {
uint64_t inline Ch(uint64_t x, uint64_t y, uint64_t z) { return z ^ (x & (y ^ z)); }
uint64_t inline Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) | (z & (x | y)); }
uint64_t inline Sigma0(uint64_t x) { return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25); }
uint64_t inline Sigma1(uint64_t x) { return (x >> 14 | x << 50) ^ (x >> 18 | x << 46) ^ (x >> 41 | x << 23); }
uint64_t inline sigma0(uint64_t x) { return (x >> 1 | x << 63) ^ (x >> 8 | x << 56) ^ (x >> 7); }
uint64_t inline sigma1(uint64_t x) { return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6); }
/** One round of SHA-512. */
void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t &d,
uint64_t e, uint64_t f, uint64_t g, uint64_t &h,
uint64_t k, uint64_t w) {
uint64_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
uint64_t t2 = Sigma0(a) + Maj(a, b, c);
d += t1;
h = t1 + t2;
}
/** Initialize SHA-256 state. */
void inline Initialize(uint64_t *s) {
s[0] = 0x6a09e667f3bcc908ull;
s[1] = 0xbb67ae8584caa73bull;
s[2] = 0x3c6ef372fe94f82bull;
s[3] = 0xa54ff53a5f1d36f1ull;
s[4] = 0x510e527fade682d1ull;
s[5] = 0x9b05688c2b3e6c1full;
s[6] = 0x1f83d9abfb41bd6bull;
s[7] = 0x5be0cd19137e2179ull;
}
/** Perform one SHA-512 transformation, processing a 128-byte chunk. */
void Transform(uint64_t *s, const unsigned char *chunk) {
uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
Round(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22ull, w0 = ReadBE64(chunk + 0));
Round(h, a, b, c, d, e, f, g, 0x7137449123ef65cdull, w1 = ReadBE64(chunk + 8));
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2full, w2 = ReadBE64(chunk + 16));
Round(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbcull, w3 = ReadBE64(chunk + 24));
Round(e, f, g, h, a, b, c, d, 0x3956c25bf348b538ull, w4 = ReadBE64(chunk + 32));
Round(d, e, f, g, h, a, b, c, 0x59f111f1b605d019ull, w5 = ReadBE64(chunk + 40));
Round(c, d, e, f, g, h, a, b, 0x923f82a4af194f9bull, w6 = ReadBE64(chunk + 48));
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118ull, w7 = ReadBE64(chunk + 56));
Round(a, b, c, d, e, f, g, h, 0xd807aa98a3030242ull, w8 = ReadBE64(chunk + 64));
Round(h, a, b, c, d, e, f, g, 0x12835b0145706fbeull, w9 = ReadBE64(chunk + 72));
Round(g, h, a, b, c, d, e, f, 0x243185be4ee4b28cull, w10 = ReadBE64(chunk + 80));
Round(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2ull, w11 = ReadBE64(chunk + 88));
Round(e, f, g, h, a, b, c, d, 0x72be5d74f27b896full, w12 = ReadBE64(chunk + 96));
Round(d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1ull, w13 = ReadBE64(chunk + 104));
Round(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235ull, w14 = ReadBE64(chunk + 112));
Round(b, c, d, e, f, g, h, a, 0xc19bf174cf692694ull, w15 = ReadBE64(chunk + 120));
Round(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0( w1));
Round(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0( w2));
Round(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1( w0) + w11 + sigma0( w3));
Round(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65ull, w3 += sigma1( w1) + w12 + sigma0( w4));
Round(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275ull, w4 += sigma1( w2) + w13 + sigma0( w5));
Round(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483ull, w5 += sigma1( w3) + w14 + sigma0( w6));
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1( w4) + w15 + sigma0( w7));
Round(b, c, d, e, f, g, h, a, 0x76f988da831153b5ull, w7 += sigma1( w5) + w0 + sigma0( w8));
Round(a, b, c, d, e, f, g, h, 0x983e5152ee66dfabull, w8 += sigma1( w6) + w1 + sigma0( w9));
Round(h, a, b, c, d, e, f, g, 0xa831c66d2db43210ull, w9 += sigma1( w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0xb00327c898fb213full, w10 += sigma1( w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4ull, w11 += sigma1( w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0( w0));
Round(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0( w1));
Round(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0( w2));
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aedull, w2 += sigma1( w0) + w11 + sigma0( w3));
Round(f, g, h, a, b, c, d, e, 0x53380d139d95b3dfull, w3 += sigma1( w1) + w12 + sigma0( w4));
Round(e, f, g, h, a, b, c, d, 0x650a73548baf63deull, w4 += sigma1( w2) + w13 + sigma0( w5));
Round(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8ull, w5 += sigma1( w3) + w14 + sigma0( w6));
Round(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6ull, w6 += sigma1( w4) + w15 + sigma0( w7));
Round(b, c, d, e, f, g, h, a, 0x92722c851482353bull, w7 += sigma1( w5) + w0 + sigma0( w8));
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364ull, w8 += sigma1( w6) + w1 + sigma0( w9));
Round(h, a, b, c, d, e, f, g, 0xa81a664bbc423001ull, w9 += sigma1( w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791ull, w10 += sigma1( w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0xc76c51a30654be30ull, w11 += sigma1( w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0( w0));
Round(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0( w1));
Round(h, a, b, c, d, e, f, g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0( w2));
Round(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99ull, w2 += sigma1( w0) + w11 + sigma0( w3));
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8ull, w3 += sigma1( w1) + w12 + sigma0( w4));
Round(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63ull, w4 += sigma1( w2) + w13 + sigma0( w5));
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acbull, w5 += sigma1( w3) + w14 + sigma0( w6));
Round(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373ull, w6 += sigma1( w4) + w15 + sigma0( w7));
Round(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1( w5) + w0 + sigma0( w8));
Round(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fcull, w8 += sigma1( w6) + w1 + sigma0( w9));
Round(h, a, b, c, d, e, f, g, 0x78a5636f43172f60ull, w9 += sigma1( w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72ull, w10 += sigma1( w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0x8cc702081a6439ecull, w11 += sigma1( w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0( w0));
Round(a, b, c, d, e, f, g, h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0( w1));
Round(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0( w2));
Round(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1eull, w2 += sigma1( w0) + w11 + sigma0( w3));
Round(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178ull, w3 += sigma1( w1) + w12 + sigma0( w4));
Round(e, f, g, h, a, b, c, d, 0x06f067aa72176fbaull, w4 += sigma1( w2) + w13 + sigma0( w5));
Round(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6ull, w5 += sigma1( w3) + w14 + sigma0( w6));
Round(c, d, e, f, g, h, a, b, 0x113f9804bef90daeull, w6 += sigma1( w4) + w15 + sigma0( w7));
Round(b, c, d, e, f, g, h, a, 0x1b710b35131c471bull, w7 += sigma1( w5) + w0 + sigma0( w8));
Round(a, b, c, d, e, f, g, h, 0x28db77f523047d84ull, w8 += sigma1( w6) + w1 + sigma0( w9));
Round(h, a, b, c, d, e, f, g, 0x32caab7b40c72493ull, w9 += sigma1( w7) + w2 + sigma0(w10));
Round(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebcull, w10 += sigma1( w8) + w3 + sigma0(w11));
Round(f, g, h, a, b, c, d, e, 0x431d67c49c100d4cull, w11 += sigma1( w9) + w4 + sigma0(w12));
Round(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13));
Round(d, e, f, g, h, a, b, c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14));
Round(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faecull, w14 += sigma1(w12) + w7 + sigma0(w15));
Round(b, c, d, e, f, g, h, a, 0x6c44198c4a475817ull, w15 += sigma1(w13) + w8 + sigma0( w0));
s[0] += a;
s[1] += b;
s[2] += c;
s[3] += d;
s[4] += e;
s[5] += f;
s[6] += g;
s[7] += h;
}
} // namespace sha512
} // namespace
////// SHA-256
CSHA256::CSHA256() : bytes(0) {
sha256::Initialize(s);
}
CSHA256& CSHA256::Write(const unsigned char *data, size_t len) {
const unsigned char *end = data + len;
size_t bufsize = bytes % 64;
if (bufsize && bufsize + len >= 64) {
// Fill the buffer, and process it.
memcpy(buf + bufsize, data, 64 - bufsize);
bytes += 64 - bufsize;
data += 64 - bufsize;
sha256::Transform(s, buf);
bufsize = 0;
}
while (end >= data + 64) {
// Process full chunks directly from the source.
sha256::Transform(s, data);
bytes += 64;
data += 64;
}
if (end > data) {
// Fill the buffer with what remains.
memcpy(buf + bufsize, data, end - data);
bytes += end - data;
}
return *this;
}
void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE]) {
static const unsigned char pad[64] = {0x80};
unsigned char sizedesc[8];
WriteBE64(sizedesc, bytes << 3);
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
Write(sizedesc, 8);
WriteBE32(hash, s[0]);
WriteBE32(hash+4, s[1]);
WriteBE32(hash+8, s[2]);
WriteBE32(hash+12, s[3]);
WriteBE32(hash+16, s[4]);
WriteBE32(hash+20, s[5]);
WriteBE32(hash+24, s[6]);
WriteBE32(hash+28, s[7]);
}
CSHA256& CSHA256::Reset() {
bytes = 0;
sha256::Initialize(s);
return *this;
}
////// SHA-512
CSHA512::CSHA512() : bytes(0) {
sha512::Initialize(s);
}
CSHA512& CSHA512::Write(const unsigned char *data, size_t len) {
const unsigned char *end = data + len;
size_t bufsize = bytes % 128;
if (bufsize && bufsize + len >= 128) {
// Fill the buffer, and process it.
memcpy(buf + bufsize, data, 128 - bufsize);
bytes += 128 - bufsize;
data += 128 - bufsize;
sha512::Transform(s, buf);
bufsize = 0;
}
while (end >= data + 128) {
// Process full chunks directly from the source.
sha512::Transform(s, data);
data += 128;
bytes += 128;
}
if (end > data) {
// Fill the buffer with what remains.
memcpy(buf + bufsize, data, end - data);
bytes += end - data;
}
return *this;
}
void CSHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) {
static const unsigned char pad[128] = {0x80};
unsigned char sizedesc[16] = {0x00};
WriteBE64(sizedesc+8, bytes << 3);
Write(pad, 1 + ((239 - (bytes % 128)) % 128));
Write(sizedesc, 16);
WriteBE64(hash, s[0]);
WriteBE64(hash+8, s[1]);
WriteBE64(hash+16, s[2]);
WriteBE64(hash+24, s[3]);
WriteBE64(hash+32, s[4]);
WriteBE64(hash+40, s[5]);
WriteBE64(hash+48, s[6]);
WriteBE64(hash+56, s[7]);
}
CSHA512& CSHA512::Reset() {
bytes = 0;
sha512::Initialize(s);
return *this;
}
////// HMAC-SHA-512
CHMAC_SHA512::CHMAC_SHA512(const unsigned char *key, size_t keylen) {
unsigned char rkey[128];
if (keylen <= 128) {
memcpy(rkey, key, keylen);
memset(rkey + keylen, 0, 128 - keylen);
} else {
CSHA512().Write(key, keylen).Finalize(rkey);
memset(rkey + 64, 0, 64);
}
for (int n=0; n<128; n++)
rkey[n] ^= 0x5c;
outer.Write(rkey, 128);
for (int n=0; n<128; n++)
rkey[n] ^= 0x5c ^ 0x36;
inner.Write(rkey, 128);
}
void CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) {
unsigned char temp[64];
inner.Finalize(temp);
outer.Write(temp, 64).Finalize(hash);
}

60
src/crypto/sha2.h Normal file
View file

@ -0,0 +1,60 @@
// Copyright (c) 2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SHA2_H
#define BITCOIN_SHA2_H
#include <stdint.h>
#include <stdlib.h>
/** A hasher class for SHA-256. */
class CSHA256 {
private:
uint32_t s[8];
unsigned char buf[64];
size_t bytes;
public:
static const size_t OUTPUT_SIZE = 32;
CSHA256();
CSHA256& Write(const unsigned char *data, size_t len);
void Finalize(unsigned char hash[OUTPUT_SIZE]);
CSHA256& Reset();
};
/** A hasher class for SHA-512. */
class CSHA512 {
private:
uint64_t s[8];
unsigned char buf[128];
size_t bytes;
public:
static const size_t OUTPUT_SIZE = 64;
CSHA512();
CSHA512& Write(const unsigned char *data, size_t len);
void Finalize(unsigned char hash[OUTPUT_SIZE]);
CSHA512& Reset();
};
/** A hasher class for HMAC-SHA-512. */
class CHMAC_SHA512 {
private:
CSHA512 outer;
CSHA512 inner;
public:
static const size_t OUTPUT_SIZE = 64;
CHMAC_SHA512(const unsigned char *key, size_t keylen);
CHMAC_SHA512& Write(const unsigned char *data, size_t len) {
inner.Write(data, len);
return *this;
}
void Finalize(unsigned char hash[OUTPUT_SIZE]);
};
#endif

View file

@ -56,44 +56,3 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
return h1; return h1;
} }
int HMAC_SHA512_Init(HMAC_SHA512_CTX *pctx, const void *pkey, size_t len)
{
unsigned char key[128];
if (len <= 128)
{
memcpy(key, pkey, len);
memset(key + len, 0, 128-len);
}
else
{
SHA512_CTX ctxKey;
SHA512_Init(&ctxKey);
SHA512_Update(&ctxKey, pkey, len);
SHA512_Final(key, &ctxKey);
memset(key + 64, 0, 64);
}
for (int n=0; n<128; n++)
key[n] ^= 0x5c;
SHA512_Init(&pctx->ctxOuter);
SHA512_Update(&pctx->ctxOuter, key, 128);
for (int n=0; n<128; n++)
key[n] ^= 0x5c ^ 0x36;
SHA512_Init(&pctx->ctxInner);
return SHA512_Update(&pctx->ctxInner, key, 128);
}
int HMAC_SHA512_Update(HMAC_SHA512_CTX *pctx, const void *pdata, size_t len)
{
return SHA512_Update(&pctx->ctxInner, pdata, len);
}
int HMAC_SHA512_Final(unsigned char *pmd, HMAC_SHA512_CTX *pctx)
{
unsigned char buf[64];
SHA512_Final(buf, &pctx->ctxInner);
SHA512_Update(&pctx->ctxOuter, buf, 64);
return SHA512_Final(pmd, &pctx->ctxOuter);
}

View file

@ -6,55 +6,138 @@
#ifndef BITCOIN_HASH_H #ifndef BITCOIN_HASH_H
#define BITCOIN_HASH_H #define BITCOIN_HASH_H
#include "crypto/sha2.h"
#include "crypto/ripemd160.h"
#include "serialize.h" #include "serialize.h"
#include "uint256.h" #include "uint256.h"
#include "version.h" #include "version.h"
#include <vector> #include <vector>
#include <openssl/ripemd.h> /** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */
#include <openssl/sha.h> class CHash256 {
private:
CSHA256 sha;
public:
static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;
void Finalize(unsigned char hash[OUTPUT_SIZE]) {
unsigned char buf[sha.OUTPUT_SIZE];
sha.Finalize(buf);
sha.Reset().Write(buf, sha.OUTPUT_SIZE).Finalize(hash);
}
CHash256& Write(const unsigned char *data, size_t len) {
sha.Write(data, len);
return *this;
}
CHash256& Reset() {
sha.Reset();
return *this;
}
};
/** A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160). */
class CHash160 {
private:
CSHA256 sha;
public:
static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE;
void Finalize(unsigned char hash[OUTPUT_SIZE]) {
unsigned char buf[sha.OUTPUT_SIZE];
sha.Finalize(buf);
CRIPEMD160().Write(buf, sha.OUTPUT_SIZE).Finalize(hash);
}
CHash160& Write(const unsigned char *data, size_t len) {
sha.Write(data, len);
return *this;
}
CHash160& Reset() {
sha.Reset();
return *this;
}
};
/** Compute the 256-bit hash of an object. */
template<typename T1> template<typename T1>
inline uint256 Hash(const T1 pbegin, const T1 pend) inline uint256 Hash(const T1 pbegin, const T1 pend)
{ {
static unsigned char pblank[1]; static const unsigned char pblank[1] = {};
uint256 hash1; uint256 result;
SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1); CHash256().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
uint256 hash2; .Finalize((unsigned char*)&result);
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); return result;
return hash2;
} }
/** Compute the 256-bit hash of the concatenation of two objects. */
template<typename T1, typename T2>
inline uint256 Hash(const T1 p1begin, const T1 p1end,
const T2 p2begin, const T2 p2end) {
static const unsigned char pblank[1] = {};
uint256 result;
CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]))
.Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]))
.Finalize((unsigned char*)&result);
return result;
}
/** Compute the 256-bit hash of the concatenation of three objects. */
template<typename T1, typename T2, typename T3>
inline uint256 Hash(const T1 p1begin, const T1 p1end,
const T2 p2begin, const T2 p2end,
const T3 p3begin, const T3 p3end) {
static const unsigned char pblank[1] = {};
uint256 result;
CHash256().Write(p1begin == p1end ? pblank : (const unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]))
.Write(p2begin == p2end ? pblank : (const unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]))
.Write(p3begin == p3end ? pblank : (const unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0]))
.Finalize((unsigned char*)&result);
return result;
}
/** Compute the 160-bit hash an object. */
template<typename T1>
inline uint160 Hash160(const T1 pbegin, const T1 pend)
{
static unsigned char pblank[1] = {};
uint160 result;
CHash160().Write(pbegin == pend ? pblank : (const unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]))
.Finalize((unsigned char*)&result);
return result;
}
/** Compute the 160-bit hash of a vector. */
inline uint160 Hash160(const std::vector<unsigned char>& vch)
{
return Hash160(vch.begin(), vch.end());
}
/** A writer stream (for serialization) that computes a 256-bit hash. */
class CHashWriter class CHashWriter
{ {
private: private:
SHA256_CTX ctx; CHash256 ctx;
public: public:
int nType; int nType;
int nVersion; int nVersion;
void Init() { CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {}
SHA256_Init(&ctx);
}
CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {
Init();
}
CHashWriter& write(const char *pch, size_t size) { CHashWriter& write(const char *pch, size_t size) {
SHA256_Update(&ctx, pch, size); ctx.Write((const unsigned char*)pch, size);
return (*this); return (*this);
} }
// invalidates the object // invalidates the object
uint256 GetHash() { uint256 GetHash() {
uint256 hash1; uint256 result;
SHA256_Final((unsigned char*)&hash1, &ctx); ctx.Finalize((unsigned char*)&result);
uint256 hash2; return result;
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
return hash2;
} }
template<typename T> template<typename T>
@ -65,41 +148,7 @@ public:
} }
}; };
/** Compute the 256-bit hash of an object's serialization. */
template<typename T1, typename T2>
inline uint256 Hash(const T1 p1begin, const T1 p1end,
const T2 p2begin, const T2 p2end)
{
static unsigned char pblank[1];
uint256 hash1;
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
SHA256_Final((unsigned char*)&hash1, &ctx);
uint256 hash2;
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
return hash2;
}
template<typename T1, typename T2, typename T3>
inline uint256 Hash(const T1 p1begin, const T1 p1end,
const T2 p2begin, const T2 p2end,
const T3 p3begin, const T3 p3end)
{
static unsigned char pblank[1];
uint256 hash1;
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
SHA256_Update(&ctx, (p3begin == p3end ? pblank : (unsigned char*)&p3begin[0]), (p3end - p3begin) * sizeof(p3begin[0]));
SHA256_Final((unsigned char*)&hash1, &ctx);
uint256 hash2;
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
return hash2;
}
template<typename T> template<typename T>
uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION) uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
{ {
@ -108,32 +157,6 @@ uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL
return ss.GetHash(); return ss.GetHash();
} }
template<typename T1>
inline uint160 Hash160(const T1 pbegin, const T1 pend)
{
static unsigned char pblank[1];
uint256 hash1;
SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
uint160 hash2;
RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
return hash2;
}
inline uint160 Hash160(const std::vector<unsigned char>& vch)
{
return Hash160(vch.begin(), vch.end());
}
unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash); unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash);
typedef struct
{
SHA512_CTX ctxInner;
SHA512_CTX ctxOuter;
} HMAC_SHA512_CTX;
int HMAC_SHA512_Init(HMAC_SHA512_CTX *pctx, const void *pkey, size_t len);
int HMAC_SHA512_Update(HMAC_SHA512_CTX *pctx, const void *pdata, size_t len);
int HMAC_SHA512_Final(unsigned char *pmd, HMAC_SHA512_CTX *pctx);
#endif #endif

View file

@ -4,13 +4,14 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H) #if defined(HAVE_CONFIG_H)
#include "bitcoin-config.h" #include "config/bitcoin-config.h"
#endif #endif
#include "init.h" #include "init.h"
#include "addrman.h" #include "addrman.h"
#include "checkpoints.h" #include "checkpoints.h"
#include "key.h"
#include "main.h" #include "main.h"
#include "miner.h" #include "miner.h"
#include "net.h" #include "net.h"
@ -25,10 +26,12 @@
#endif #endif
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#ifndef WIN32 #ifndef WIN32
#include <signal.h> #include <signal.h>
#endif #endif
#include "compat/sanity.h"
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
@ -39,7 +42,6 @@ using namespace std;
using namespace boost; using namespace boost;
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
std::string strWalletFile;
CWallet* pwalletMain; CWallet* pwalletMain;
#endif #endif
@ -59,6 +61,8 @@ enum BindFlags {
BF_REPORT_ERROR = (1U << 1) BF_REPORT_ERROR = (1U << 1)
}; };
static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat";
CClientUIInterface uiInterface;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
@ -113,7 +117,6 @@ void Shutdown()
RenameThread("bitcoin-shutoff"); RenameThread("bitcoin-shutoff");
mempool.AddTransactionsUpdated(1); mempool.AddTransactionsUpdated(1);
StopRPCThreads(); StopRPCThreads();
ShutdownRPCMining();
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
if (pwalletMain) if (pwalletMain)
bitdb.Flush(false); bitdb.Flush(false);
@ -121,6 +124,14 @@ void Shutdown()
#endif #endif
StopNode(); StopNode();
UnregisterNodeSignals(GetNodeSignals()); UnregisterNodeSignals(GetNodeSignals());
boost::filesystem::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
CAutoFile est_fileout = CAutoFile(fopen(est_path.string().c_str(), "wb"), SER_DISK, CLIENT_VERSION);
if (est_fileout)
mempool.WriteFeeEstimates(est_fileout);
else
LogPrintf("failed to write fee estimates");
{ {
LOCK(cs_main); LOCK(cs_main);
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
@ -185,9 +196,9 @@ bool static Bind(const CService &addr, unsigned int flags) {
return true; return true;
} }
// Core-specific options shared between UI, daemon and RPC client std::string HelpMessage(HelpMessageMode mode)
std::string HelpMessage(HelpMessageMode hmm)
{ {
// When adding new options to the categories, please keep and ensure alphabetical ordering.
string strUsage = _("Options:") + "\n"; string strUsage = _("Options:") + "\n";
strUsage += " -? " + _("This help message") + "\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 += " -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";
@ -195,7 +206,7 @@ std::string HelpMessage(HelpMessageMode hmm)
strUsage += " -checkblocks=<n> " + _("How many blocks to check at startup (default: 288, 0 = all)") + "\n"; strUsage += " -checkblocks=<n> " + _("How many blocks to check at startup (default: 288, 0 = all)") + "\n";
strUsage += " -checklevel=<n> " + _("How thorough the block verification of -checkblocks is (0-4, default: 3)") + "\n"; strUsage += " -checklevel=<n> " + _("How thorough the block verification of -checkblocks is (0-4, default: 3)") + "\n";
strUsage += " -conf=<file> " + _("Specify configuration file (default: bitcoin.conf)") + "\n"; strUsage += " -conf=<file> " + _("Specify configuration file (default: bitcoin.conf)") + "\n";
if (hmm == HMM_BITCOIND) if (mode == HMM_BITCOIND)
{ {
#if !defined(WIN32) #if !defined(WIN32)
strUsage += " -daemon " + _("Run in the background as a daemon and accept commands") + "\n"; strUsage += " -daemon " + _("Run in the background as a daemon and accept commands") + "\n";
@ -205,6 +216,7 @@ std::string HelpMessage(HelpMessageMode hmm)
strUsage += " -dbcache=<n> " + strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache) + "\n"; strUsage += " -dbcache=<n> " + strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache) + "\n";
strUsage += " -keypool=<n> " + _("Set key pool size to <n> (default: 100)") + "\n"; strUsage += " -keypool=<n> " + _("Set key pool size to <n> (default: 100)") + "\n";
strUsage += " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + " " + _("on startup") + "\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 += " -par=<n> " + strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS) + "\n"; strUsage += " -par=<n> " + strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS) + "\n";
strUsage += " -pid=<file> " + _("Specify pid file (default: bitcoind.pid)") + "\n"; strUsage += " -pid=<file> " + _("Specify pid file (default: bitcoind.pid)") + "\n";
strUsage += " -reindex " + _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup") + "\n"; strUsage += " -reindex " + _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup") + "\n";
@ -227,9 +239,8 @@ std::string HelpMessage(HelpMessageMode hmm)
strUsage += " -onion=<ip:port> " + _("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)") + "\n"; strUsage += " -onion=<ip:port> " + _("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)") + "\n";
strUsage += " -onlynet=<net> " + _("Only connect to nodes in network <net> (IPv4, IPv6 or Tor)") + "\n"; strUsage += " -onlynet=<net> " + _("Only connect to nodes in network <net> (IPv4, IPv6 or Tor)") + "\n";
strUsage += " -port=<port> " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n"; strUsage += " -port=<port> " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n";
strUsage += " -proxy=<ip:port> " + _("Connect through SOCKS proxy") + "\n"; strUsage += " -proxy=<ip:port> " + _("Connect through SOCKS5 proxy") + "\n";
strUsage += " -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n"; strUsage += " -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n";
strUsage += " -socks=<n> " + _("Select SOCKS version for -proxy (4 or 5, default: 5)") + "\n";
strUsage += " -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000)") + "\n"; strUsage += " -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000)") + "\n";
#ifdef USE_UPNP #ifdef USE_UPNP
#if USE_UPNP #if USE_UPNP
@ -242,14 +253,18 @@ std::string HelpMessage(HelpMessageMode hmm)
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
strUsage += "\n" + _("Wallet options:") + "\n"; strUsage += "\n" + _("Wallet options:") + "\n";
strUsage += " -disablewallet " + _("Do not load the wallet and disable wallet RPC calls") + "\n"; strUsage += " -disablewallet " + _("Do not load the wallet and disable wallet RPC calls") + "\n";
strUsage += " -paytxfee=<amt> " + _("Fee per kB to add to transactions you send") + "\n"; strUsage += " -mintxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"), FormatMoney(CWallet::minTxFee.GetFeePerK())) + "\n";
strUsage += " -paytxfee=<amt> " + strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())) + "\n";
strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + " " + _("on startup") + "\n"; strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + " " + _("on startup") + "\n";
strUsage += " -respendnotify=<cmd> " + _("Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)") + "\n";
strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n"; strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n";
strUsage += " -spendzeroconfchange " + _("Spend unconfirmed change when sending transactions (default: 1)") + "\n"; strUsage += " -spendzeroconfchange " + _("Spend unconfirmed change when sending transactions (default: 1)") + "\n";
strUsage += " -txconfirmtarget=<n> " + _("If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: 1)") + "\n";
strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n"; strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n";
strUsage += " -wallet=<file> " + _("Specify wallet file (within data directory)") + " " + _("(default: wallet.dat)") + "\n"; strUsage += " -wallet=<file> " + _("Specify wallet file (within data directory)") + " " + _("(default: wallet.dat)") + "\n";
strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n"; strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n";
strUsage += " -zapwallettxes " + _("Clear list of wallet transactions (diagnostic tool; implies -rescan)") + "\n"; strUsage += " -zapwallettxes=<mode> " + _("Delete all wallet transactions and only recover those part of the blockchain through -rescan on startup") + "\n";
strUsage += " " + _("(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)") + "\n";
#endif #endif
strUsage += "\n" + _("Debugging/Testing options:") + "\n"; strUsage += "\n" + _("Debugging/Testing options:") + "\n";
@ -263,25 +278,26 @@ std::string HelpMessage(HelpMessageMode hmm)
strUsage += " -dropmessagestest=<n> " + _("Randomly drop 1 of every <n> network messages") + "\n"; strUsage += " -dropmessagestest=<n> " + _("Randomly drop 1 of every <n> network messages") + "\n";
strUsage += " -fuzzmessagestest=<n> " + _("Randomly fuzz 1 of every <n> network messages") + "\n"; strUsage += " -fuzzmessagestest=<n> " + _("Randomly fuzz 1 of every <n> network messages") + "\n";
strUsage += " -flushwallet " + _("Run a thread to flush wallet periodically (default: 1)") + "\n"; strUsage += " -flushwallet " + _("Run a thread to flush wallet periodically (default: 1)") + "\n";
strUsage += " -stopafterblockimport " + _("Stop running after importing blocks from disk (default: 0)") + "\n";
} }
strUsage += " -debug=<category> " + _("Output debugging information (default: 0, supplying <category> is optional)") + "\n"; strUsage += " -debug=<category> " + _("Output debugging information (default: 0, supplying <category> is optional)") + "\n";
strUsage += " " + _("If <category> is not supplied, output all debugging information.") + "\n"; strUsage += " " + _("If <category> is not supplied, output all debugging information.") + "\n";
strUsage += " " + _("<category> can be:"); strUsage += " " + _("<category> can be:");
strUsage += " addrman, alert, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below strUsage += " addrman, alert, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below
if (hmm == HMM_BITCOIN_QT) if (mode == HMM_BITCOIN_QT)
strUsage += ", qt"; strUsage += ", qt";
strUsage += ".\n"; strUsage += ".\n";
strUsage += " -gen " + _("Generate coins (default: 0)") + "\n"; strUsage += " -gen " + _("Generate coins (default: 0)") + "\n";
strUsage += " -genproclimit=<n> " + _("Set the processor limit for when generation is on (-1 = unlimited, default: -1)") + "\n"; strUsage += " -genproclimit=<n> " + _("Set the processor limit for when generation is on (-1 = unlimited, default: -1)") + "\n";
strUsage += " -help-debug " + _("Show all debugging options (usage: --help -help-debug)") + "\n"; strUsage += " -help-debug " + _("Show all debugging options (usage: --help -help-debug)") + "\n";
strUsage += " -logips " + _("Include IP addresses in debug output (default: 0)") + "\n";
strUsage += " -logtimestamps " + _("Prepend debug output with timestamp (default: 1)") + "\n"; strUsage += " -logtimestamps " + _("Prepend debug output with timestamp (default: 1)") + "\n";
if (GetBoolArg("-help-debug", false)) if (GetBoolArg("-help-debug", false))
{ {
strUsage += " -limitfreerelay=<n> " + _("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)") + "\n"; strUsage += " -limitfreerelay=<n> " + _("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:15)") + "\n";
strUsage += " -maxsigcachesize=<n> " + _("Limit size of signature cache to <n> entries (default: 50000)") + "\n"; strUsage += " -maxsigcachesize=<n> " + _("Limit size of signature cache to <n> entries (default: 50000)") + "\n";
} }
strUsage += " -mintxfee=<amt> " + _("Fees smaller than this are considered zero fee (for transaction creation) (default:") + " " + FormatMoney(CTransaction::nMinTxFee) + ")" + "\n"; strUsage += " -minrelaytxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())) + "\n";
strUsage += " -minrelaytxfee=<amt> " + _("Fees smaller than this are considered zero fee (for relaying) (default:") + " " + FormatMoney(CTransaction::nMinRelayTxFee) + ")" + "\n";
strUsage += " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n"; strUsage += " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n";
if (GetBoolArg("-help-debug", false)) if (GetBoolArg("-help-debug", false))
{ {
@ -296,6 +312,8 @@ std::string HelpMessage(HelpMessageMode hmm)
strUsage += " -shrinkdebugfile " + _("Shrink debug.log file on client startup (default: 1 when no -debug)") + "\n"; strUsage += " -shrinkdebugfile " + _("Shrink debug.log file on client startup (default: 1 when no -debug)") + "\n";
strUsage += " -testnet " + _("Use the test network") + "\n"; strUsage += " -testnet " + _("Use the test network") + "\n";
strUsage += "\n" + _("Node relay options:") + "\n";
strUsage += " -datacarrier " + _("Relay and mine data carrier transactions (default: 1)") + "\n";
strUsage += "\n" + _("Block creation options:") + "\n"; strUsage += "\n" + _("Block creation options:") + "\n";
strUsage += " -blockminsize=<n> " + _("Set minimum block size in bytes (default: 0)") + "\n"; strUsage += " -blockminsize=<n> " + _("Set minimum block size in bytes (default: 0)") + "\n";
strUsage += " -blockmaxsize=<n> " + strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE) + "\n"; strUsage += " -blockmaxsize=<n> " + strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE) + "\n";
@ -303,10 +321,11 @@ std::string HelpMessage(HelpMessageMode hmm)
strUsage += "\n" + _("RPC server options:") + "\n"; strUsage += "\n" + _("RPC server options:") + "\n";
strUsage += " -server " + _("Accept command line and JSON-RPC commands") + "\n"; strUsage += " -server " + _("Accept command line and JSON-RPC commands") + "\n";
strUsage += " -rpcbind=<addr> " + _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)") + "\n";
strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n"; strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n"; strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
strUsage += " -rpcport=<port> " + _("Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)") + "\n"; strUsage += " -rpcport=<port> " + _("Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)") + "\n";
strUsage += " -rpcallowip=<ip> " + _("Allow JSON-RPC connections from specified IP address") + "\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> " + _("Set the number of threads to service RPC calls (default: 4)") + "\n"; strUsage += " -rpcthreads=<n> " + _("Set the number of threads to service RPC calls (default: 4)") + "\n";
strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n"; strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
@ -318,6 +337,18 @@ std::string HelpMessage(HelpMessageMode hmm)
return strUsage; return strUsage;
} }
std::string LicenseInfo()
{
return FormatParagraph(strprintf(_("Copyright (C) 2009-%i The Bitcoin Core Developers"), COPYRIGHT_YEAR)) + "\n" +
"\n" +
FormatParagraph(_("This is experimental software.")) + "\n" +
"\n" +
FormatParagraph(_("Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.")) + "\n" +
"\n" +
FormatParagraph(_("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.")) +
"\n";
}
struct CImportingNow struct CImportingNow
{ {
CImportingNow() { CImportingNow() {
@ -381,6 +412,28 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
LogPrintf("Warning: Could not open blocks file %s\n", path.string()); LogPrintf("Warning: Could not open blocks file %s\n", path.string());
} }
} }
if (GetBoolArg("-stopafterblockimport", false)) {
LogPrintf("Stopping after block import\n");
StartShutdown();
}
}
/** Sanity checks
* Ensure that Bitcoin is running in a usable environment with all
* necessary library support.
*/
bool InitSanityCheck(void)
{
if(!ECC_InitSanityCheck()) {
InitError("OpenSSL appears to lack support for elliptic curve cryptography. For more "
"information, visit https://en.bitcoin.it/wiki/OpenSSL_and_EC_Libraries");
return false;
}
if (!glibc_sanity_test() || !glibcxx_sanity_test())
return false;
return true;
} }
/** Initialize bitcoin. /** Initialize bitcoin.
@ -489,7 +542,7 @@ bool AppInit2(boost::thread_group& threadGroup)
// -zapwallettx implies a rescan // -zapwallettx implies a rescan
if (GetBoolArg("-zapwallettxes", false)) { if (GetBoolArg("-zapwallettxes", false)) {
if (SoftSetBoolArg("-rescan", true)) if (SoftSetBoolArg("-rescan", true))
LogPrintf("AppInit2 : parameter interaction: -zapwallettxes=1 -> setting -rescan=1\n"); LogPrintf("AppInit2 : parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n");
} }
// Make sure enough file descriptors are available // Make sure enough file descriptors are available
@ -513,9 +566,16 @@ bool AppInit2(boost::thread_group& threadGroup)
// Check for -debugnet (deprecated) // Check for -debugnet (deprecated)
if (GetBoolArg("-debugnet", false)) if (GetBoolArg("-debugnet", false))
InitWarning(_("Warning: Deprecated argument -debugnet ignored, use -debug=net")); InitWarning(_("Warning: Deprecated argument -debugnet ignored, use -debug=net"));
// Check for -socks - as this is a privacy risk to continue, exit here
if (mapArgs.count("-socks"))
return InitError(_("Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported."));
// Check for -tor - as this is a privacy risk to continue, exit here
if (GetBoolArg("-tor", false))
return InitError(_("Error: Unsupported argument -tor found, use -onion."));
fBenchmark = GetBoolArg("-benchmark", false); fBenchmark = GetBoolArg("-benchmark", false);
mempool.setSanityCheck(GetBoolArg("-checkmempool", RegTest())); // Checkmempool defaults to true in regtest mode
mempool.setSanityCheck(GetBoolArg("-checkmempool", Params().DefaultCheckMemPool()));
Checkpoints::fEnabled = GetBoolArg("-checkpoints", true); Checkpoints::fEnabled = GetBoolArg("-checkpoints", true);
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
@ -530,6 +590,8 @@ bool AppInit2(boost::thread_group& threadGroup)
fServer = GetBoolArg("-server", false); fServer = GetBoolArg("-server", false);
fPrintToConsole = GetBoolArg("-printtoconsole", false); fPrintToConsole = GetBoolArg("-printtoconsole", false);
fLogTimestamps = GetBoolArg("-logtimestamps", true); fLogTimestamps = GetBoolArg("-logtimestamps", true);
fLogIPs = GetBoolArg("-logips", false);
setvbuf(stdout, NULL, _IOLBF, 0);
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
bool fDisableWallet = GetBoolArg("-disablewallet", false); bool fDisableWallet = GetBoolArg("-disablewallet", false);
#endif #endif
@ -553,36 +615,47 @@ bool AppInit2(boost::thread_group& threadGroup)
// a transaction spammer can cheaply fill blocks using // a transaction spammer can cheaply fill blocks using
// 1-satoshi-fee transactions. It should be set above the real // 1-satoshi-fee transactions. It should be set above the real
// cost to you of processing a transaction. // cost to you of processing a transaction.
if (mapArgs.count("-mintxfee"))
{
int64_t n = 0;
if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0)
CTransaction::nMinTxFee = n;
else
return InitError(strprintf(_("Invalid amount for -mintxfee=<amount>: '%s'"), mapArgs["-mintxfee"]));
}
if (mapArgs.count("-minrelaytxfee")) if (mapArgs.count("-minrelaytxfee"))
{ {
int64_t n = 0; int64_t n = 0;
if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0) if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0)
CTransaction::nMinRelayTxFee = n; ::minRelayTxFee = CFeeRate(n);
else else
return InitError(strprintf(_("Invalid amount for -minrelaytxfee=<amount>: '%s'"), mapArgs["-minrelaytxfee"])); return InitError(strprintf(_("Invalid amount for -minrelaytxfee=<amount>: '%s'"), mapArgs["-minrelaytxfee"]));
} }
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
if (mapArgs.count("-mintxfee"))
{
int64_t n = 0;
if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0)
CWallet::minTxFee = CFeeRate(n);
else
return InitError(strprintf(_("Invalid amount for -mintxfee=<amount>: '%s'"), mapArgs["-mintxfee"]));
}
if (mapArgs.count("-paytxfee")) if (mapArgs.count("-paytxfee"))
{ {
if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee)) int64_t nFeePerK = 0;
if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK))
return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"])); return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"]));
if (nTransactionFee > nHighTransactionFeeWarning) if (nFeePerK > nHighTransactionFeeWarning)
InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
payTxFee = CFeeRate(nFeePerK, 1000);
if (payTxFee < ::minRelayTxFee)
{
return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
mapArgs["-paytxfee"], ::minRelayTxFee.ToString()));
} }
}
nTxConfirmTarget = GetArg("-txconfirmtarget", 1);
bSpendZeroConfChange = GetArg("-spendzeroconfchange", true); bSpendZeroConfChange = GetArg("-spendzeroconfchange", true);
strWalletFile = GetArg("-wallet", "wallet.dat"); std::string strWalletFile = GetArg("-wallet", "wallet.dat");
#endif #endif
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
// Sanity check
if (!InitSanityCheck())
return InitError(_("Initialization sanity check failed. Bitcoin Core is shutting down."));
std::string strDataDir = GetDataDir().string(); std::string strDataDir = GetDataDir().string();
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
@ -610,6 +683,7 @@ bool AppInit2(boost::thread_group& threadGroup)
LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime())); LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()));
LogPrintf("Default data directory %s\n", GetDefaultDataDir().string()); LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
LogPrintf("Using data directory %s\n", strDataDir); LogPrintf("Using data directory %s\n", strDataDir);
LogPrintf("Using config file %s\n", GetConfigFile().string());
LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD); LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
std::ostringstream strErrors; std::ostringstream strErrors;
@ -674,10 +748,6 @@ bool AppInit2(boost::thread_group& threadGroup)
RegisterNodeSignals(GetNodeSignals()); RegisterNodeSignals(GetNodeSignals());
int nSocksVersion = GetArg("-socks", 5);
if (nSocksVersion != 4 && nSocksVersion != 5)
return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion));
if (mapArgs.count("-onlynet")) { if (mapArgs.count("-onlynet")) {
std::set<enum Network> nets; std::set<enum Network> nets;
BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) { BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) {
@ -701,40 +771,34 @@ bool AppInit2(boost::thread_group& threadGroup)
return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"])); return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"]));
if (!IsLimited(NET_IPV4)) if (!IsLimited(NET_IPV4))
SetProxy(NET_IPV4, addrProxy, nSocksVersion); SetProxy(NET_IPV4, addrProxy);
if (nSocksVersion > 4) {
if (!IsLimited(NET_IPV6)) if (!IsLimited(NET_IPV6))
SetProxy(NET_IPV6, addrProxy, nSocksVersion); SetProxy(NET_IPV6, addrProxy);
SetNameProxy(addrProxy, nSocksVersion); SetNameProxy(addrProxy);
}
fProxy = true; fProxy = true;
} }
// -onion can override normal proxy, -noonion disables tor entirely // -onion can override normal proxy, -noonion disables tor entirely
// -tor here is a temporary backwards compatibility measure
if (mapArgs.count("-tor"))
printf("Notice: option -tor has been replaced with -onion and will be removed in a later version.\n");
if (!(mapArgs.count("-onion") && mapArgs["-onion"] == "0") && if (!(mapArgs.count("-onion") && mapArgs["-onion"] == "0") &&
!(mapArgs.count("-tor") && mapArgs["-tor"] == "0") && (fProxy || mapArgs.count("-onion"))) {
(fProxy || mapArgs.count("-onion") || mapArgs.count("-tor"))) {
CService addrOnion; CService addrOnion;
if (!mapArgs.count("-onion") && !mapArgs.count("-tor")) if (!mapArgs.count("-onion"))
addrOnion = addrProxy; addrOnion = addrProxy;
else else
addrOnion = mapArgs.count("-onion")?CService(mapArgs["-onion"], 9050):CService(mapArgs["-tor"], 9050); addrOnion = CService(mapArgs["-onion"], 9050);
if (!addrOnion.IsValid()) if (!addrOnion.IsValid())
return InitError(strprintf(_("Invalid -onion address: '%s'"), mapArgs.count("-onion")?mapArgs["-onion"]:mapArgs["-tor"])); return InitError(strprintf(_("Invalid -onion address: '%s'"), mapArgs["-onion"]));
SetProxy(NET_TOR, addrOnion, 5); SetProxy(NET_TOR, addrOnion);
SetReachable(NET_TOR); SetReachable(NET_TOR);
} }
// see Step 2: parameter interactions for more information about these // see Step 2: parameter interactions for more information about these
fNoListen = !GetBoolArg("-listen", true); fListen = GetBoolArg("-listen", DEFAULT_LISTEN);
fDiscover = GetBoolArg("-discover", true); fDiscover = GetBoolArg("-discover", true);
fNameLookup = GetBoolArg("-dns", true); fNameLookup = GetBoolArg("-dns", true);
bool fBound = false; bool fBound = false;
if (!fNoListen) { if (fListen) {
if (mapArgs.count("-bind")) { if (mapArgs.count("-bind")) {
BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) { BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) {
CService addrBind; CService addrBind;
@ -855,7 +919,7 @@ bool AppInit2(boost::thread_group& threadGroup)
} }
uiInterface.InitMessage(_("Verifying blocks...")); uiInterface.InitMessage(_("Verifying blocks..."));
if (!VerifyDB(GetArg("-checklevel", 3), if (!CVerifyDB().VerifyDB(GetArg("-checklevel", 3),
GetArg("-checkblocks", 288))) { GetArg("-checkblocks", 288))) {
strLoadError = _("Corrupted block database detected"); strLoadError = _("Corrupted block database detected");
break; break;
@ -911,7 +975,7 @@ bool AppInit2(boost::thread_group& threadGroup)
for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
{ {
uint256 hash = (*mi).first; uint256 hash = (*mi).first;
if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0) if (boost::algorithm::starts_with(hash.ToString(), strMatch))
{ {
CBlockIndex* pindex = (*mi).second; CBlockIndex* pindex = (*mi).second;
CBlock block; CBlock block;
@ -927,17 +991,26 @@ bool AppInit2(boost::thread_group& threadGroup)
return false; return false;
} }
boost::filesystem::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
CAutoFile est_filein = CAutoFile(fopen(est_path.string().c_str(), "rb"), SER_DISK, CLIENT_VERSION);
if (est_filein)
mempool.ReadFeeEstimates(est_filein);
// ********************************************************* Step 8: load wallet // ********************************************************* Step 8: load wallet
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
if (fDisableWallet) { if (fDisableWallet) {
pwalletMain = NULL; pwalletMain = NULL;
LogPrintf("Wallet disabled!\n"); LogPrintf("Wallet disabled!\n");
} else { } else {
// needed to restore wallet transaction meta data after -zapwallettxes
std::vector<CWalletTx> vWtx;
if (GetBoolArg("-zapwallettxes", false)) { if (GetBoolArg("-zapwallettxes", false)) {
uiInterface.InitMessage(_("Zapping all transactions from wallet...")); uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
pwalletMain = new CWallet(strWalletFile); pwalletMain = new CWallet(strWalletFile);
DBErrors nZapWalletRet = pwalletMain->ZapWalletTx(); DBErrors nZapWalletRet = pwalletMain->ZapWalletTx(vWtx);
if (nZapWalletRet != DB_LOAD_OK) { if (nZapWalletRet != DB_LOAD_OK) {
uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted")); uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted"));
return false; return false;
@ -1032,6 +1105,29 @@ bool AppInit2(boost::thread_group& threadGroup)
LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart); LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart);
pwalletMain->SetBestChain(chainActive.GetLocator()); pwalletMain->SetBestChain(chainActive.GetLocator());
nWalletDBUpdated++; nWalletDBUpdated++;
// Restore wallet transaction metadata after -zapwallettxes=1
if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2")
{
BOOST_FOREACH(const CWalletTx& wtxOld, vWtx)
{
uint256 hash = wtxOld.GetHash();
std::map<uint256, CWalletTx>::iterator mi = pwalletMain->mapWallet.find(hash);
if (mi != pwalletMain->mapWallet.end())
{
const CWalletTx* copyFrom = &wtxOld;
CWalletTx* copyTo = &mi->second;
copyTo->mapValue = copyFrom->mapValue;
copyTo->vOrderForm = copyFrom->vOrderForm;
copyTo->nTimeReceived = copyFrom->nTimeReceived;
copyTo->nTimeSmart = copyFrom->nTimeSmart;
copyTo->fFromMe = copyFrom->fFromMe;
copyTo->strFromAccount = copyFrom->strFromAccount;
copyTo->nOrderPos = copyFrom->nOrderPos;
copyTo->WriteToDisk();
}
}
}
} }
} // (!fDisableWallet) } // (!fDisableWallet)
#else // ENABLE_WALLET #else // ENABLE_WALLET
@ -1078,17 +1174,16 @@ bool AppInit2(boost::thread_group& threadGroup)
RandAddSeedPerfmon(); RandAddSeedPerfmon();
//// debug print //// debug print
LogPrintf("mapBlockIndex.size() = %"PRIszu"\n", mapBlockIndex.size()); LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
LogPrintf("nBestHeight = %d\n", chainActive.Height()); LogPrintf("nBestHeight = %d\n", chainActive.Height());
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
LogPrintf("setKeyPool.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0); LogPrintf("setKeyPool.size() = %u\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0);
LogPrintf("mapWallet.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->mapWallet.size() : 0); LogPrintf("mapWallet.size() = %u\n", pwalletMain ? pwalletMain->mapWallet.size() : 0);
LogPrintf("mapAddressBook.size() = %"PRIszu"\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0); LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0);
#endif #endif
InitRespendFilter();
StartNode(threadGroup); StartNode(threadGroup);
// InitRPCMining is needed here so getwork/getblocktemplate in the GUI debug console works properly.
InitRPCMining();
if (fServer) if (fServer)
StartRPCThreads(); StartRPCThreads();

View file

@ -12,9 +12,8 @@ class CWallet;
namespace boost { namespace boost {
class thread_group; class thread_group;
}; } // namespace boost
extern std::string strWalletFile;
extern CWallet* pwalletMain; extern CWallet* pwalletMain;
void StartShutdown(); void StartShutdown();
@ -29,6 +28,9 @@ enum HelpMessageMode
HMM_BITCOIN_QT HMM_BITCOIN_QT
}; };
/** Help for options shared between UI and daemon (for -help) */
std::string HelpMessage(HelpMessageMode mode); std::string HelpMessage(HelpMessageMode mode);
/** Returns licensing information (for -version) */
std::string LicenseInfo();
#endif #endif

View file

@ -33,8 +33,8 @@
namespace json_spirit namespace json_spirit
{ {
const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >(); const spirit_namespace::int_parser < int64_t > int64_p = spirit_namespace::int_parser < int64_t >();
const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >(); const spirit_namespace::uint_parser< uint64_t > uint64_p = spirit_namespace::uint_parser< uint64_t >();
template< class Iter_type > template< class Iter_type >
bool is_eq( Iter_type first, Iter_type last, const char* c_str ) bool is_eq( Iter_type first, Iter_type last, const char* c_str )
@ -270,12 +270,12 @@ namespace json_spirit
add_to_current( Value_type() ); add_to_current( Value_type() );
} }
void new_int( boost::int64_t i ) void new_int( int64_t i )
{ {
add_to_current( i ); add_to_current( i );
} }
void new_uint64( boost::uint64_t ui ) void new_uint64( uint64_t ui )
{ {
add_to_current( ui ); add_to_current( ui );
} }
@ -425,8 +425,8 @@ namespace json_spirit
typedef boost::function< void( Char_type ) > Char_action; typedef boost::function< void( Char_type ) > Char_action;
typedef boost::function< void( Iter_type, Iter_type ) > Str_action; typedef boost::function< void( Iter_type, Iter_type ) > Str_action;
typedef boost::function< void( double ) > Real_action; typedef boost::function< void( double ) > Real_action;
typedef boost::function< void( boost::int64_t ) > Int_action; typedef boost::function< void( int64_t ) > Int_action;
typedef boost::function< void( boost::uint64_t ) > Uint64_action; typedef boost::function< void( uint64_t ) > Uint64_action;
Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) ); Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) );
Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) ); Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) );

View file

@ -16,8 +16,8 @@
#include <cassert> #include <cassert>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <stdint.h>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/variant.hpp> #include <boost/variant.hpp>
@ -45,8 +45,8 @@ namespace json_spirit
Value_impl( const Array& value ); Value_impl( const Array& value );
Value_impl( bool value ); Value_impl( bool value );
Value_impl( int value ); Value_impl( int value );
Value_impl( boost::int64_t value ); Value_impl( int64_t value );
Value_impl( boost::uint64_t value ); Value_impl( uint64_t value );
Value_impl( double value ); Value_impl( double value );
Value_impl( const Value_impl& other ); Value_impl( const Value_impl& other );
@ -65,8 +65,8 @@ namespace json_spirit
const Array& get_array() const; const Array& get_array() const;
bool get_bool() const; bool get_bool() const;
int get_int() const; int get_int() const;
boost::int64_t get_int64() const; int64_t get_int64() const;
boost::uint64_t get_uint64() const; uint64_t get_uint64() const;
double get_real() const; double get_real() const;
Object& get_obj(); Object& get_obj();
@ -83,7 +83,7 @@ namespace json_spirit
typedef boost::variant< String_type, typedef boost::variant< String_type,
boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
bool, boost::int64_t, double > Variant; bool, int64_t, double > Variant;
Value_type type_; Value_type type_;
Variant v_; Variant v_;
@ -258,13 +258,13 @@ namespace json_spirit
template< class Config > template< class Config >
Value_impl< Config >::Value_impl( int value ) Value_impl< Config >::Value_impl( int value )
: type_( int_type ) : type_( int_type )
, v_( static_cast< boost::int64_t >( value ) ) , v_( static_cast< int64_t >( value ) )
, is_uint64_( false ) , is_uint64_( false )
{ {
} }
template< class Config > template< class Config >
Value_impl< Config >::Value_impl( boost::int64_t value ) Value_impl< Config >::Value_impl( int64_t value )
: type_( int_type ) : type_( int_type )
, v_( value ) , v_( value )
, is_uint64_( false ) , is_uint64_( false )
@ -272,9 +272,9 @@ namespace json_spirit
} }
template< class Config > template< class Config >
Value_impl< Config >::Value_impl( boost::uint64_t value ) Value_impl< Config >::Value_impl( uint64_t value )
: type_( int_type ) : type_( int_type )
, v_( static_cast< boost::int64_t >( value ) ) , v_( static_cast< int64_t >( value ) )
, is_uint64_( true ) , is_uint64_( true )
{ {
} }
@ -390,19 +390,19 @@ namespace json_spirit
} }
template< class Config > template< class Config >
boost::int64_t Value_impl< Config >::get_int64() const int64_t Value_impl< Config >::get_int64() const
{ {
check_type( int_type ); check_type( int_type );
return boost::get< boost::int64_t >( v_ ); return boost::get< int64_t >( v_ );
} }
template< class Config > template< class Config >
boost::uint64_t Value_impl< Config >::get_uint64() const uint64_t Value_impl< Config >::get_uint64() const
{ {
check_type( int_type ); check_type( int_type );
return static_cast< boost::uint64_t >( get_int64() ); return static_cast< uint64_t >( get_int64() );
} }
template< class Config > template< class Config >
@ -481,13 +481,13 @@ namespace json_spirit
} }
template< class Value > template< class Value >
boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > ) int64_t get_value( const Value& value, Type_to_type< int64_t > )
{ {
return value.get_int64(); return value.get_int64();
} }
template< class Value > template< class Value >
boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > ) uint64_t get_value( const Value& value, Type_to_type< uint64_t > )
{ {
return value.get_uint64(); return value.get_uint64();
} }

View file

@ -4,14 +4,35 @@
#include "key.h" #include "key.h"
#include "crypto/sha2.h"
#include <openssl/rand.h>
#ifdef USE_SECP256K1
#include <secp256k1.h>
#else
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/ecdsa.h> #include <openssl/ecdsa.h>
#include <openssl/obj_mac.h> #include <openssl/obj_mac.h>
#include <openssl/rand.h> #endif
// anonymous namespace with local implementation code (OpenSSL interaction) // anonymous namespace with local implementation code (OpenSSL interaction)
namespace { namespace {
#ifdef USE_SECP256K1
#include <secp256k1.h>
class CSecp256k1Init {
public:
CSecp256k1Init() {
secp256k1_start();
}
~CSecp256k1Init() {
secp256k1_stop();
}
};
static CSecp256k1Init instance_of_csecp256k1;
#else
// Generate a private key from just the secret parameter // Generate a private key from just the secret parameter
int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key) int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
{ {
@ -332,30 +353,61 @@ public:
} }
}; };
}; // end of anonymous namespace #endif
bool CKey::Check(const unsigned char *vch) { int CompareBigEndian(const unsigned char *c1, size_t c1len, const unsigned char *c2, size_t c2len) {
// Do not convert to OpenSSL's data structures for range-checking keys, while (c1len > c2len) {
// it's easy enough to do directly. if (*c1)
static const unsigned char vchMax[32] = { return 1;
c1++;
c1len--;
}
while (c2len > c1len) {
if (*c2)
return -1;
c2++;
c2len--;
}
while (c1len > 0) {
if (*c1 > *c2)
return 1;
if (*c2 > *c1)
return -1;
c1++;
c2++;
c1len--;
}
return 0;
}
// Order of secp256k1's generator minus 1.
const unsigned char vchMaxModOrder[32] = {
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40
}; };
bool fIsZero = true;
for (int i=0; i<32 && fIsZero; i++) // Half of the order of secp256k1's generator minus 1.
if (vch[i] != 0) const unsigned char vchMaxModHalfOrder[32] = {
fIsZero = false; 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
if (fIsZero) 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
return false; 0x5D,0x57,0x6E,0x73,0x57,0xA4,0x50,0x1D,
for (int i=0; i<32; i++) { 0xDF,0xE9,0x2F,0x46,0x68,0x1B,0x20,0xA0
if (vch[i] < vchMax[i]) };
return true;
if (vch[i] > vchMax[i]) const unsigned char vchZero[0] = {};
return false;
} } // anon namespace
return true;
bool CKey::Check(const unsigned char *vch) {
return CompareBigEndian(vch, 32, vchZero, 0) > 0 &&
CompareBigEndian(vch, 32, vchMaxModOrder, 32) <= 0;
}
bool CKey::CheckSignatureElement(const unsigned char *vch, int len, bool half) {
return CompareBigEndian(vch, len, vchZero, 0) > 0 &&
CompareBigEndian(vch, len, half ? vchMaxModHalfOrder : vchMaxModOrder, 32) <= 0;
} }
void CKey::MakeNewKey(bool fCompressedIn) { void CKey::MakeNewKey(bool fCompressedIn) {
@ -367,10 +419,15 @@ void CKey::MakeNewKey(bool fCompressedIn) {
} }
bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) { bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) {
#ifdef USE_SECP256K1
if (!secp256k1_ecdsa_privkey_import((unsigned char*)begin(), &privkey[0], privkey.size()))
return false;
#else
CECKey key; CECKey key;
if (!key.SetPrivKey(privkey)) if (!key.SetPrivKey(privkey))
return false; return false;
key.GetSecretBytes(vch); key.GetSecretBytes(vch);
#endif
fCompressed = fCompressedIn; fCompressed = fCompressedIn;
fValid = true; fValid = true;
return true; return true;
@ -378,50 +435,92 @@ bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) {
CPrivKey CKey::GetPrivKey() const { CPrivKey CKey::GetPrivKey() const {
assert(fValid); assert(fValid);
CPrivKey privkey;
#ifdef USE_SECP256K1
privkey.resize(279);
int privkeylen = 279;
int ret = secp256k1_ecdsa_privkey_export(begin(), (unsigned char*)&privkey[0], &privkeylen, fCompressed);
assert(ret);
privkey.resize(privkeylen);
#else
CECKey key; CECKey key;
key.SetSecretBytes(vch); key.SetSecretBytes(vch);
CPrivKey privkey;
key.GetPrivKey(privkey, fCompressed); key.GetPrivKey(privkey, fCompressed);
#endif
return privkey; return privkey;
} }
CPubKey CKey::GetPubKey() const { CPubKey CKey::GetPubKey() const {
assert(fValid); assert(fValid);
CPubKey pubkey;
#ifdef USE_SECP256K1
int clen = 65;
int ret = secp256k1_ecdsa_pubkey_create((unsigned char*)pubkey.begin(), &clen, begin(), fCompressed);
assert(ret);
assert(pubkey.IsValid());
assert((int)pubkey.size() == clen);
#else
CECKey key; CECKey key;
key.SetSecretBytes(vch); key.SetSecretBytes(vch);
CPubKey pubkey;
key.GetPubKey(pubkey, fCompressed); key.GetPubKey(pubkey, fCompressed);
#endif
return pubkey; return pubkey;
} }
bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const { bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const {
if (!fValid) if (!fValid)
return false; return false;
#ifdef USE_SECP256K1
vchSig.resize(72);
int nSigLen = 72;
CKey nonce;
do {
nonce.MakeNewKey(true);
if (secp256k1_ecdsa_sign((const unsigned char*)&hash, 32, (unsigned char*)&vchSig[0], &nSigLen, begin(), nonce.begin()))
break;
} while(true);
vchSig.resize(nSigLen);
return true;
#else
CECKey key; CECKey key;
key.SetSecretBytes(vch); key.SetSecretBytes(vch);
return key.Sign(hash, vchSig); return key.Sign(hash, vchSig);
#endif
} }
bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const { bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const {
if (!fValid) if (!fValid)
return false; return false;
CECKey key;
key.SetSecretBytes(vch);
vchSig.resize(65); vchSig.resize(65);
int rec = -1; int rec = -1;
#ifdef USE_SECP256K1
CKey nonce;
do {
nonce.MakeNewKey(true);
if (secp256k1_ecdsa_sign_compact((const unsigned char*)&hash, 32, &vchSig[1], begin(), nonce.begin(), &rec))
break;
} while(true);
#else
CECKey key;
key.SetSecretBytes(vch);
if (!key.SignCompact(hash, &vchSig[1], rec)) if (!key.SignCompact(hash, &vchSig[1], rec))
return false; return false;
#endif
assert(rec != -1); assert(rec != -1);
vchSig[0] = 27 + rec + (fCompressed ? 4 : 0); vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
return true; return true;
} }
bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) { bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) {
#ifdef USE_SECP256K1
if (!secp256k1_ecdsa_privkey_import((unsigned char*)begin(), &privkey[0], privkey.size()))
return false;
#else
CECKey key; CECKey key;
if (!key.SetPrivKey(privkey, fSkipCheck)) if (!key.SetPrivKey(privkey, fSkipCheck))
return false; return false;
key.GetSecretBytes(vch); key.GetSecretBytes(vch);
#endif
fCompressed = vchPubKey.IsCompressed(); fCompressed = vchPubKey.IsCompressed();
fValid = true; fValid = true;
@ -437,55 +536,66 @@ bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) {
bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const { bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
if (!IsValid()) if (!IsValid())
return false; return false;
#ifdef USE_SECP256K1
if (secp256k1_ecdsa_verify((const unsigned char*)&hash, 32, &vchSig[0], vchSig.size(), begin(), size()) != 1)
return false;
#else
CECKey key; CECKey key;
if (!key.SetPubKey(*this)) if (!key.SetPubKey(*this))
return false; return false;
if (!key.Verify(hash, vchSig)) if (!key.Verify(hash, vchSig))
return false; return false;
#endif
return true; return true;
} }
bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) { bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
if (vchSig.size() != 65) if (vchSig.size() != 65)
return false; return false;
int recid = (vchSig[0] - 27) & 3;
bool fComp = (vchSig[0] - 27) & 4;
#ifdef USE_SECP256K1
int pubkeylen = 65;
if (!secp256k1_ecdsa_recover_compact((const unsigned char*)&hash, 32, &vchSig[1], (unsigned char*)begin(), &pubkeylen, fComp, recid))
return false;
assert((int)size() == pubkeylen);
#else
CECKey key; CECKey key;
if (!key.Recover(hash, &vchSig[1], (vchSig[0] - 27) & ~4)) if (!key.Recover(hash, &vchSig[1], recid))
return false;
key.GetPubKey(*this, (vchSig[0] - 27) & 4);
return true;
}
bool CPubKey::VerifyCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
if (!IsValid())
return false;
if (vchSig.size() != 65)
return false;
CECKey key;
if (!key.Recover(hash, &vchSig[1], (vchSig[0] - 27) & ~4))
return false;
CPubKey pubkeyRec;
key.GetPubKey(pubkeyRec, IsCompressed());
if (*this != pubkeyRec)
return false; return false;
key.GetPubKey(*this, fComp);
#endif
return true; return true;
} }
bool CPubKey::IsFullyValid() const { bool CPubKey::IsFullyValid() const {
if (!IsValid()) if (!IsValid())
return false; return false;
#ifdef USE_SECP256K1
if (!secp256k1_ecdsa_pubkey_verify(begin(), size()))
return false;
#else
CECKey key; CECKey key;
if (!key.SetPubKey(*this)) if (!key.SetPubKey(*this))
return false; return false;
#endif
return true; return true;
} }
bool CPubKey::Decompress() { bool CPubKey::Decompress() {
if (!IsValid()) if (!IsValid())
return false; return false;
#ifdef USE_SECP256K1
int clen = size();
int ret = secp256k1_ecdsa_pubkey_decompress((unsigned char*)begin(), &clen);
assert(ret);
assert(clen == (int)size());
#else
CECKey key; CECKey key;
if (!key.SetPubKey(*this)) if (!key.SetPubKey(*this))
return false; return false;
key.GetPubKey(*this, false); key.GetPubKey(*this, false);
#endif
return true; return true;
} }
@ -495,12 +605,10 @@ void static BIP32Hash(const unsigned char chainCode[32], unsigned int nChild, un
num[1] = (nChild >> 16) & 0xFF; num[1] = (nChild >> 16) & 0xFF;
num[2] = (nChild >> 8) & 0xFF; num[2] = (nChild >> 8) & 0xFF;
num[3] = (nChild >> 0) & 0xFF; num[3] = (nChild >> 0) & 0xFF;
HMAC_SHA512_CTX ctx; CHMAC_SHA512(chainCode, 32).Write(&header, 1)
HMAC_SHA512_Init(&ctx, chainCode, 32); .Write(data, 32)
HMAC_SHA512_Update(&ctx, &header, 1); .Write(num, 4)
HMAC_SHA512_Update(&ctx, data, 32); .Finalize(output);
HMAC_SHA512_Update(&ctx, num, 4);
HMAC_SHA512_Final(output, &ctx);
} }
bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const { bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const {
@ -517,7 +625,12 @@ bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild
BIP32Hash(cc, nChild, 0, begin(), out); BIP32Hash(cc, nChild, 0, begin(), out);
} }
memcpy(ccChild, out+32, 32); memcpy(ccChild, out+32, 32);
#ifdef USE_SECP256K1
memcpy((unsigned char*)keyChild.begin(), begin(), 32);
bool ret = secp256k1_ecdsa_privkey_tweak_add((unsigned char*)keyChild.begin(), out);
#else
bool ret = CECKey::TweakSecret((unsigned char*)keyChild.begin(), begin(), out); bool ret = CECKey::TweakSecret((unsigned char*)keyChild.begin(), begin(), out);
#endif
UnlockObject(out); UnlockObject(out);
keyChild.fCompressed = true; keyChild.fCompressed = true;
keyChild.fValid = ret; keyChild.fValid = ret;
@ -531,10 +644,15 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned i
unsigned char out[64]; unsigned char out[64];
BIP32Hash(cc, nChild, *begin(), begin()+1, out); BIP32Hash(cc, nChild, *begin(), begin()+1, out);
memcpy(ccChild, out+32, 32); memcpy(ccChild, out+32, 32);
#ifdef USE_SECP256K1
pubkeyChild = *this;
bool ret = secp256k1_ecdsa_pubkey_tweak_add((unsigned char*)pubkeyChild.begin(), pubkeyChild.size(), out);
#else
CECKey key; CECKey key;
bool ret = key.SetPubKey(*this); bool ret = key.SetPubKey(*this);
ret &= key.TweakPublic(out); ret &= key.TweakPublic(out);
key.GetPubKey(pubkeyChild, true); key.GetPubKey(pubkeyChild, true);
#endif
return ret; return ret;
} }
@ -547,13 +665,10 @@ bool CExtKey::Derive(CExtKey &out, unsigned int nChild) const {
} }
void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) { void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) {
static const char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'}; static const unsigned char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'};
HMAC_SHA512_CTX ctx;
HMAC_SHA512_Init(&ctx, hashkey, sizeof(hashkey));
HMAC_SHA512_Update(&ctx, seed, nSeedLen);
unsigned char out[64]; unsigned char out[64];
LockObject(out); LockObject(out);
HMAC_SHA512_Final(out, &ctx); CHMAC_SHA512(hashkey, sizeof(hashkey)).Write(seed, nSeedLen).Finalize(out);
key.Set(&out[0], &out[32], true); key.Set(&out[0], &out[32], true);
memcpy(vchChainCode, &out[32], 32); memcpy(vchChainCode, &out[32], 32);
UnlockObject(out); UnlockObject(out);
@ -616,3 +731,19 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const {
out.nChild = nChild; out.nChild = nChild;
return pubkey.Derive(out.pubkey, out.vchChainCode, nChild, vchChainCode); return pubkey.Derive(out.pubkey, out.vchChainCode, nChild, vchChainCode);
} }
bool ECC_InitSanityCheck() {
#ifdef USE_SECP256K1
return true;
#else
EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
if(pkey == NULL)
return false;
EC_KEY_free(pkey);
// TODO Is there more EC functionality that could be missing?
return true;
#endif
}

View file

@ -156,10 +156,6 @@ public:
// If this public key is not fully valid, the return value will be false. // If this public key is not fully valid, the return value will be false.
bool Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const; bool Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const;
// Verify a compact signature (~65 bytes).
// See CKey::SignCompact.
bool VerifyCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) const;
// Recover a public key from a compact signature. // Recover a public key from a compact signature.
bool RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig); bool RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig);
@ -269,6 +265,9 @@ public:
// Load private key and check that public key matches. // Load private key and check that public key matches.
bool Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck); bool Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck);
// Check whether an element of a signature (r or s) is valid.
static bool CheckSignatureElement(const unsigned char *vch, int len, bool half);
}; };
struct CExtPubKey { struct CExtPubKey {
@ -307,4 +306,7 @@ struct CExtKey {
void SetMaster(const unsigned char *seed, unsigned int nSeedLen); void SetMaster(const unsigned char *seed, unsigned int nSeedLen);
}; };
/** Check that required EC support is available at runtime */
bool ECC_InitSanityCheck(void);
#endif #endif

View file

@ -33,6 +33,9 @@ bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
bool CBasicKeyStore::AddCScript(const CScript& redeemScript) bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
{ {
if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
return error("CBasicKeyStore::AddCScript() : redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
LOCK(cs_KeyStore); LOCK(cs_KeyStore);
mapScripts[redeemScript.GetID()] = redeemScript; mapScripts[redeemScript.GetID()] = redeemScript;
return true; return true;
@ -56,3 +59,15 @@ bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut)
return false; return false;
} }
bool CBasicKeyStore::AddWatchOnly(const CScript &dest)
{
LOCK(cs_KeyStore);
setWatchOnly.insert(dest);
return true;
}
bool CBasicKeyStore::HaveWatchOnly(const CScript &dest) const
{
LOCK(cs_KeyStore);
return setWatchOnly.count(dest) > 0;
}

View file

@ -8,11 +8,21 @@
#include "key.h" #include "key.h"
#include "sync.h" #include "sync.h"
#include "script.h" // for CNoDestination
#include <boost/signals2/signal.hpp> #include <boost/signals2/signal.hpp>
#include <boost/variant.hpp>
class CScript; class CScript;
/** A txout script template with a specific destination. It is either:
* * CNoDestination: no destination set
* * CKeyID: TX_PUBKEYHASH destination
* * CScriptID: TX_SCRIPTHASH destination
* A CTxDestination is the internal data type encoded in a CBitcoinAddress
*/
typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
/** A virtual base class for key stores */ /** A virtual base class for key stores */
class CKeyStore class CKeyStore
{ {
@ -36,10 +46,15 @@ public:
virtual bool AddCScript(const CScript& redeemScript) =0; virtual bool AddCScript(const CScript& redeemScript) =0;
virtual bool HaveCScript(const CScriptID &hash) const =0; virtual bool HaveCScript(const CScriptID &hash) const =0;
virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0; virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0;
// Support for Watch-only addresses
virtual bool AddWatchOnly(const CScript &dest) =0;
virtual bool HaveWatchOnly(const CScript &dest) const =0;
}; };
typedef std::map<CKeyID, CKey> KeyMap; typedef std::map<CKeyID, CKey> KeyMap;
typedef std::map<CScriptID, CScript > ScriptMap; typedef std::map<CScriptID, CScript > ScriptMap;
typedef std::set<CScript> WatchOnlySet;
/** Basic key store, that keeps keys in an address->secret map */ /** Basic key store, that keeps keys in an address->secret map */
class CBasicKeyStore : public CKeyStore class CBasicKeyStore : public CKeyStore
@ -47,6 +62,7 @@ class CBasicKeyStore : public CKeyStore
protected: protected:
KeyMap mapKeys; KeyMap mapKeys;
ScriptMap mapScripts; ScriptMap mapScripts;
WatchOnlySet setWatchOnly;
public: public:
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
@ -88,6 +104,9 @@ public:
virtual bool AddCScript(const CScript& redeemScript); virtual bool AddCScript(const CScript& redeemScript);
virtual bool HaveCScript(const CScriptID &hash) const; virtual bool HaveCScript(const CScriptID &hash) const;
virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const; virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const;
virtual bool AddWatchOnly(const CScript &dest);
virtual bool HaveWatchOnly(const CScript &dest) const;
}; };
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial; typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;

View file

@ -72,7 +72,7 @@ SHARED = $(SHARED1)
else else
# Update db.h if you change these. # Update db.h if you change these.
SHARED_MAJOR = 1 SHARED_MAJOR = 1
SHARED_MINOR = 15 SHARED_MINOR = 17
SHARED1 = libleveldb.$(PLATFORM_SHARED_EXT) SHARED1 = libleveldb.$(PLATFORM_SHARED_EXT)
SHARED2 = $(SHARED1).$(SHARED_MAJOR) SHARED2 = $(SHARED1).$(SHARED_MAJOR)
SHARED3 = $(SHARED1).$(SHARED_MAJOR).$(SHARED_MINOR) SHARED3 = $(SHARED1).$(SHARED_MAJOR).$(SHARED_MINOR)
@ -190,19 +190,20 @@ PLATFORMSROOT=/Applications/Xcode.app/Contents/Developer/Platforms
SIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer SIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer
DEVICEROOT=$(PLATFORMSROOT)/iPhoneOS.platform/Developer DEVICEROOT=$(PLATFORMSROOT)/iPhoneOS.platform/Developer
IOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/version CFBundleShortVersionString) IOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/version CFBundleShortVersionString)
IOSARCH=-arch armv6 -arch armv7 -arch armv7s -arch arm64
.cc.o: .cc.o:
mkdir -p ios-x86/$(dir $@) mkdir -p ios-x86/$(dir $@)
$(CXX) $(CXXFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -c $< -o ios-x86/$@ $(CXX) $(CXXFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -arch x86_64 -c $< -o ios-x86/$@
mkdir -p ios-arm/$(dir $@) mkdir -p ios-arm/$(dir $@)
xcrun -sdk iphoneos $(CXX) $(CXXFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@ xcrun -sdk iphoneos $(CXX) $(CXXFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk $(IOSARCH) -c $< -o ios-arm/$@
lipo ios-x86/$@ ios-arm/$@ -create -output $@ lipo ios-x86/$@ ios-arm/$@ -create -output $@
.c.o: .c.o:
mkdir -p ios-x86/$(dir $@) mkdir -p ios-x86/$(dir $@)
$(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -c $< -o ios-x86/$@ $(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -arch x86_64 -c $< -o ios-x86/$@
mkdir -p ios-arm/$(dir $@) mkdir -p ios-arm/$(dir $@)
xcrun -sdk iphoneos $(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@ xcrun -sdk iphoneos $(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk $(IOSARCH) -c $< -o ios-arm/$@
lipo ios-x86/$@ ios-arm/$@ -create -output $@ lipo ios-x86/$@ ios-arm/$@ -create -output $@
else else

View file

@ -29,19 +29,14 @@ std::string LogFileName(const std::string& name, uint64_t number) {
return MakeFileName(name, number, "log"); return MakeFileName(name, number, "log");
} }
// TableFileName returns the filenames we usually write to, while
// SSTTableFileName returns the alternative filenames we also try to read from
// for backward compatibility. For now, swap them around.
// TODO: when compatibility is no longer necessary, swap them back
// (TableFileName to use "ldb" and SSTTableFileName to use "sst").
std::string TableFileName(const std::string& name, uint64_t number) { std::string TableFileName(const std::string& name, uint64_t number) {
assert(number > 0); assert(number > 0);
return MakeFileName(name, number, "sst"); return MakeFileName(name, number, "ldb");
} }
std::string SSTTableFileName(const std::string& name, uint64_t number) { std::string SSTTableFileName(const std::string& name, uint64_t number) {
assert(number > 0); assert(number > 0);
return MakeFileName(name, number, "ldb"); return MakeFileName(name, number, "sst");
} }
std::string DescriptorFileName(const std::string& dbname, uint64_t number) { std::string DescriptorFileName(const std::string& dbname, uint64_t number) {

Some files were not shown because too many files have changed in this diff Show more