Merge remote-tracking branch 'upstream/master'
Conflicts: src/qt/overviewpage.cpp src/qt/transactiondesc.cpp
This commit is contained in:
commit
96df327834
331 changed files with 19565 additions and 8435 deletions
13
.gitignore
vendored
13
.gitignore
vendored
|
@ -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
|
||||||
|
|
2
COPYING
2
COPYING
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
49
README.md
49
README.md
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
20
configure.ac
20
configure.ac
|
@ -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
|
||||||
|
|
|
@ -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: ")
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
61
contrib/gitian-descriptors/gitian-osx-bitcoin.yml
Normal file
61
contrib/gitian-descriptors/gitian-osx-bitcoin.yml
Normal 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
|
159
contrib/gitian-descriptors/gitian-osx-depends.yml
Normal file
159
contrib/gitian-descriptors/gitian-osx-depends.yml
Normal 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
|
178
contrib/gitian-descriptors/gitian-osx-native.yml
Normal file
178
contrib/gitian-descriptors/gitian-osx-native.yml
Normal 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
|
186
contrib/gitian-descriptors/gitian-osx-qt.yml
Normal file
186
contrib/gitian-descriptors/gitian-osx-qt.yml
Normal 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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
#
|
#
|
||||||
|
|
52
contrib/gitian-downloader/cfields-key.pgp
Normal file
52
contrib/gitian-downloader/cfields-key.pgp
Normal 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-----
|
|
@ -37,3 +37,6 @@ signers:
|
||||||
E944AE667CF960B1004BC32FCA662BE18B877A60:
|
E944AE667CF960B1004BC32FCA662BE18B877A60:
|
||||||
name: "Andreas Schildbach"
|
name: "Andreas Schildbach"
|
||||||
key: aschildbach
|
key: aschildbach
|
||||||
|
C060A6635913D98A3587D7DB1C2491FFEB0EF770:
|
||||||
|
name: "Cory Fields"
|
||||||
|
key: "cfields"
|
||||||
|
|
|
@ -37,3 +37,6 @@ signers:
|
||||||
E944AE667CF960B1004BC32FCA662BE18B877A60:
|
E944AE667CF960B1004BC32FCA662BE18B877A60:
|
||||||
name: "Andreas Schildbach"
|
name: "Andreas Schildbach"
|
||||||
key: aschildbach
|
key: aschildbach
|
||||||
|
C060A6635913D98A3587D7DB1C2491FFEB0EF770:
|
||||||
|
name: "Cory Fields"
|
||||||
|
key: "cfields"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
# ------------------------------------------------
|
# ------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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
75
doc/README_osx.txt
Normal 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.
|
|
@ -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.
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
53
doc/release-notes/release-notes-0.9.1.md
Normal file
53
doc/release-notes/release-notes-0.9.1.md
Normal 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.
|
207
doc/release-notes/release-notes-0.9.2.1.md
Normal file
207
doc/release-notes/release-notes-0.9.2.1.md
Normal 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
|
207
doc/release-notes/release-notes-0.9.2.md
Normal file
207
doc/release-notes/release-notes-0.9.2.md
Normal 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
|
|
@ -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:
|
||||||
|
|
|
@ -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
134
qa/rpc-tests/netutil.py
Normal 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
225
qa/rpc-tests/receivedby.py
Executable 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
154
qa/rpc-tests/rpcbind_test.py
Executable 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
142
qa/rpc-tests/smartfees.py
Executable 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()
|
|
@ -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:
|
||||||
|
|
|
@ -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
161
qa/rpc-tests/zapwallettxes.sh
Executable 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
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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')
|
||||||
|
|
172
src/Makefile.am
172
src/Makefile.am
|
@ -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
|
||||||
|
|
|
@ -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
417
src/Makefile.qt.include
Normal 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 $@
|
51
src/Makefile.qttest.include
Normal file
51
src/Makefile.qttest.include
Normal 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
109
src/Makefile.test.include
Normal 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 $@"
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
184
src/base58.cpp
184
src/base58.cpp
|
@ -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());
|
||||||
|
}
|
||||||
|
|
257
src/base58.h
257
src/base58.h
|
@ -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
|
||||||
|
|
595
src/bignum.h
595
src/bignum.h
|
@ -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
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 = ®TestParams;
|
pCurrentParams = ®TestParams;
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
93
src/chainparamsbase.cpp
Normal 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 = ®TestParams;
|
||||||
|
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
52
src/chainparamsbase.h
Normal 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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
11
src/coins.h
11
src/coins.h
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
67
src/compat/glibc_sanity.cpp
Normal file
67
src/compat/glibc_sanity.cpp
Normal 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>();
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
65
src/compat/glibcxx_sanity.cpp
Normal file
65
src/compat/glibcxx_sanity.cpp
Normal 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
11
src/compat/sanity.h
Normal 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
0
src/config/.empty
Normal file
79
src/core.cpp
79
src/core.cpp
|
@ -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(),
|
||||||
|
|
140
src/core.h
140
src/core.h
|
@ -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
93
src/crypto/common.h
Normal 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
204
src/crypto/ripemd160.cpp
Normal 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
27
src/crypto/ripemd160.h
Normal 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
192
src/crypto/sha1.cpp
Normal 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
27
src/crypto/sha1.h
Normal 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
398
src/crypto/sha2.cpp
Normal 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
60
src/crypto/sha2.h
Normal 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
|
41
src/hash.cpp
41
src/hash.cpp
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
189
src/hash.h
189
src/hash.h
|
@ -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
|
||||||
|
|
209
src/init.cpp
209
src/init.cpp
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ) );
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
237
src/key.cpp
237
src/key.cpp
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
10
src/key.h
10
src/key.h
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
Loading…
Reference in a new issue