Rename CClaimTrieCache to CClaimTrieUpdateBuffer #156
171 changed files with 2633 additions and 1514 deletions
25
.travis.yml
25
.travis.yml
|
@ -10,6 +10,7 @@ env:
|
||||||
global:
|
global:
|
||||||
- MAKEJOBS=-j3
|
- MAKEJOBS=-j3
|
||||||
- RUN_TESTS=false
|
- RUN_TESTS=false
|
||||||
|
- BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID
|
||||||
- CCACHE_SIZE=100M
|
- CCACHE_SIZE=100M
|
||||||
- CCACHE_TEMPDIR=/tmp/.ccache-temp
|
- CCACHE_TEMPDIR=/tmp/.ccache-temp
|
||||||
- CCACHE_COMPRESS=1
|
- CCACHE_COMPRESS=1
|
||||||
|
@ -25,19 +26,19 @@ matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
include:
|
include:
|
||||||
- compiler: ": ARM"
|
- compiler: ": ARM"
|
||||||
env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
|
env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
|
||||||
- compiler: ": bitcoind"
|
|
||||||
env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat CPPFLAGS=-DDEBUG_LOCKORDER"
|
|
||||||
- compiler: ": No wallet"
|
|
||||||
env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
|
|
||||||
- compiler: ": 32-bit + dash"
|
|
||||||
env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" USE_SHELL="/bin/dash"
|
|
||||||
- compiler: ": Cross-Mac"
|
|
||||||
env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" OSX_SDK=10.9 GOAL="deploy"
|
|
||||||
- compiler: ": Win64"
|
|
||||||
env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2"
|
|
||||||
- compiler: ": Win32"
|
- compiler: ": Win32"
|
||||||
env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2"
|
env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2"
|
||||||
|
- compiler: ": 32-bit + dash"
|
||||||
|
env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash"
|
||||||
|
- compiler: ": Win64"
|
||||||
|
env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2"
|
||||||
|
- compiler: ": bitcoind"
|
||||||
|
env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER"
|
||||||
|
- compiler: ": No wallet"
|
||||||
|
env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
|
||||||
|
- compiler: ": Cross-Mac"
|
||||||
|
env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy"
|
||||||
install:
|
install:
|
||||||
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi
|
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi
|
||||||
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi
|
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi
|
||||||
|
|
55
configure.ac
55
configure.ac
|
@ -115,9 +115,9 @@ AC_ARG_ENABLE([hardening],
|
||||||
|
|
||||||
AC_ARG_ENABLE([reduce-exports],
|
AC_ARG_ENABLE([reduce-exports],
|
||||||
[AS_HELP_STRING([--enable-reduce-exports],
|
[AS_HELP_STRING([--enable-reduce-exports],
|
||||||
[attempt to reduce exported symbols in the resulting executables (default is yes)])],
|
[attempt to reduce exported symbols in the resulting executables (default is no)])],
|
||||||
[use_reduce_exports=$enableval],
|
[use_reduce_exports=$enableval],
|
||||||
[use_reduce_exports=auto])
|
[use_reduce_exports=no])
|
||||||
|
|
||||||
AC_ARG_ENABLE([ccache],
|
AC_ARG_ENABLE([ccache],
|
||||||
[AS_HELP_STRING([--enable-ccache],
|
[AS_HELP_STRING([--enable-ccache],
|
||||||
|
@ -133,7 +133,7 @@ AC_ARG_ENABLE([lcov],
|
||||||
|
|
||||||
AC_ARG_ENABLE([glibc-back-compat],
|
AC_ARG_ENABLE([glibc-back-compat],
|
||||||
[AS_HELP_STRING([--enable-glibc-back-compat],
|
[AS_HELP_STRING([--enable-glibc-back-compat],
|
||||||
[enable backwards compatibility with glibc and libstdc++])],
|
[enable backwards compatibility with glibc])],
|
||||||
[use_glibc_compat=$enableval],
|
[use_glibc_compat=$enableval],
|
||||||
[use_glibc_compat=no])
|
[use_glibc_compat=no])
|
||||||
|
|
||||||
|
@ -350,8 +350,8 @@ if test x$use_lcov = xyes; then
|
||||||
[AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")])
|
[AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl Require little endian
|
dnl Check for endianness
|
||||||
AC_C_BIGENDIAN([AC_MSG_ERROR("Big Endian not supported")])
|
AC_C_BIGENDIAN
|
||||||
|
|
||||||
dnl Check for pthread compile/link requirements
|
dnl Check for pthread compile/link requirements
|
||||||
AX_PTHREAD
|
AX_PTHREAD
|
||||||
|
@ -438,17 +438,22 @@ 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([endian.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
|
AC_CHECK_HEADERS([endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
|
||||||
AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])])
|
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_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])])
|
||||||
|
|
||||||
AC_CHECK_DECLS([strnlen])
|
AC_CHECK_DECLS([strnlen])
|
||||||
|
|
||||||
AC_CHECK_DECLS([le32toh, le64toh, htole32, htole64, be32toh, be64toh, htobe32, htobe64],,,
|
AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,,
|
||||||
[#if HAVE_ENDIAN_H
|
[#if HAVE_ENDIAN_H
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#endif])
|
#endif])
|
||||||
|
|
||||||
|
AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,,
|
||||||
|
[#if HAVE_BYTESWAP_H
|
||||||
|
#include <byteswap.h>
|
||||||
|
#endif])
|
||||||
|
|
||||||
dnl Check for MSG_NOSIGNAL
|
dnl Check for MSG_NOSIGNAL
|
||||||
AC_MSG_CHECKING(for MSG_NOSIGNAL)
|
AC_MSG_CHECKING(for MSG_NOSIGNAL)
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]],
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]],
|
||||||
|
@ -471,22 +476,14 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([
|
||||||
[
|
[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
if test x$use_reduce_exports = xyes; then
|
if test x$use_reduce_exports = xyes; then
|
||||||
AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduced-exports.])
|
AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduce-exports.])
|
||||||
fi
|
fi
|
||||||
AC_MSG_WARN([Cannot find a working visibility attribute. Disabling reduced exports.])
|
|
||||||
use_reduce_exports=no
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
if test x$use_reduce_exports != xno; then
|
if test x$use_reduce_exports = xyes; then
|
||||||
AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"],
|
AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"],
|
||||||
[
|
[AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])])
|
||||||
if test x$use_reduce_exports = xyes; then
|
|
||||||
AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduced-exports.])
|
|
||||||
fi
|
|
||||||
AC_MSG_WARN([Cannot set default symbol visibility. Disabling reduced exports.])
|
|
||||||
use_reduce_exports=no
|
|
||||||
])
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
LEVELDB_CPPFLAGS=
|
LEVELDB_CPPFLAGS=
|
||||||
|
@ -533,7 +530,7 @@ AX_BOOST_THREAD
|
||||||
AX_BOOST_CHRONO
|
AX_BOOST_CHRONO
|
||||||
|
|
||||||
|
|
||||||
if test x$use_reduce_exports != xno; then
|
if test x$use_reduce_exports = xyes; then
|
||||||
AC_MSG_CHECKING([for working boost reduced exports])
|
AC_MSG_CHECKING([for working boost reduced exports])
|
||||||
TEMP_CPPFLAGS="$CPPFLAGS"
|
TEMP_CPPFLAGS="$CPPFLAGS"
|
||||||
CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS"
|
CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS"
|
||||||
|
@ -547,25 +544,14 @@ if test x$use_reduce_exports != xno; then
|
||||||
#endif
|
#endif
|
||||||
]])],[
|
]])],[
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
],[:
|
],[
|
||||||
if test x$use_reduce_exports = xauto; then
|
AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduce-exports.])
|
||||||
use_reduce_exports=no
|
|
||||||
else
|
|
||||||
if test x$use_reduce_exports = xyes; then
|
|
||||||
AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduced-exports.])
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
AC_MSG_WARN([boost versions < 1.49 are known to have symbol visibility issues. Disabling reduced exports.])
|
|
||||||
])
|
])
|
||||||
CPPFLAGS="$TEMP_CPPFLAGS"
|
CPPFLAGS="$TEMP_CPPFLAGS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
elif test x$use_reduce_exports = xauto; then
|
|
||||||
use_reduce_exports=yes
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test x$use_reduce_exports != xno; then
|
if test x$use_reduce_exports = xyes; then
|
||||||
CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS"
|
CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS"
|
||||||
AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"])
|
AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"])
|
||||||
fi
|
fi
|
||||||
|
@ -827,7 +813,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether to reduce exports])
|
AC_MSG_CHECKING([whether to reduce exports])
|
||||||
if test x$use_reduce_exports != xno; then
|
if test x$use_reduce_exports = xyes; then
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
|
@ -849,7 +835,6 @@ 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])
|
||||||
|
|
|
@ -16,6 +16,9 @@ Repository Tools
|
||||||
Specific tools for developers working on this repository.
|
Specific tools for developers working on this repository.
|
||||||
Contains the script `github-merge.sh` for merging github pull requests securely and signing them using GPG.
|
Contains the script `github-merge.sh` for merging github pull requests securely and signing them using GPG.
|
||||||
|
|
||||||
|
### [Verify-Commits](/contrib/verify-commits) ###
|
||||||
|
Tool to verify that every merge commit was signed by a developer using the above `github-merge.sh` script.
|
||||||
|
|
||||||
### [Linearize](/contrib/linearize) ###
|
### [Linearize](/contrib/linearize) ###
|
||||||
Construct a linear, no-fork, best version of the blockchain.
|
Construct a linear, no-fork, best version of the blockchain.
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ if cmd == "backupwallet":
|
||||||
try:
|
try:
|
||||||
path = raw_input("Enter destination path/filename: ")
|
path = raw_input("Enter destination path/filename: ")
|
||||||
print access.backupwallet(path)
|
print access.backupwallet(path)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "encryptwallet":
|
elif cmd == "encryptwallet":
|
||||||
try:
|
try:
|
||||||
|
@ -32,29 +32,29 @@ elif cmd == "encryptwallet":
|
||||||
print "\n---Wallet encrypted. Server stopping, restart to run with encrypted wallet---\n"
|
print "\n---Wallet encrypted. Server stopping, restart to run with encrypted wallet---\n"
|
||||||
else:
|
else:
|
||||||
print "\n---Passphrases do not match---\n"
|
print "\n---Passphrases do not match---\n"
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getaccount":
|
elif cmd == "getaccount":
|
||||||
try:
|
try:
|
||||||
addr = raw_input("Enter a Bitcoin address: ")
|
addr = raw_input("Enter a Bitcoin address: ")
|
||||||
print access.getaccount(addr)
|
print access.getaccount(addr)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getaccountaddress":
|
elif cmd == "getaccountaddress":
|
||||||
try:
|
try:
|
||||||
acct = raw_input("Enter an account name: ")
|
acct = raw_input("Enter an account name: ")
|
||||||
print access.getaccountaddress(acct)
|
print access.getaccountaddress(acct)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getaddressesbyaccount":
|
elif cmd == "getaddressesbyaccount":
|
||||||
try:
|
try:
|
||||||
acct = raw_input("Enter an account name: ")
|
acct = raw_input("Enter an account name: ")
|
||||||
print access.getaddressesbyaccount(acct)
|
print access.getaddressesbyaccount(acct)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getbalance":
|
elif cmd == "getbalance":
|
||||||
try:
|
try:
|
||||||
|
@ -64,57 +64,57 @@ elif cmd == "getbalance":
|
||||||
print access.getbalance(acct, mc)
|
print access.getbalance(acct, mc)
|
||||||
except:
|
except:
|
||||||
print access.getbalance()
|
print access.getbalance()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getblockbycount":
|
elif cmd == "getblockbycount":
|
||||||
try:
|
try:
|
||||||
height = raw_input("Height: ")
|
height = raw_input("Height: ")
|
||||||
print access.getblockbycount(height)
|
print access.getblockbycount(height)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getblockcount":
|
elif cmd == "getblockcount":
|
||||||
try:
|
try:
|
||||||
print access.getblockcount()
|
print access.getblockcount()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getblocknumber":
|
elif cmd == "getblocknumber":
|
||||||
try:
|
try:
|
||||||
print access.getblocknumber()
|
print access.getblocknumber()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getconnectioncount":
|
elif cmd == "getconnectioncount":
|
||||||
try:
|
try:
|
||||||
print access.getconnectioncount()
|
print access.getconnectioncount()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getdifficulty":
|
elif cmd == "getdifficulty":
|
||||||
try:
|
try:
|
||||||
print access.getdifficulty()
|
print access.getdifficulty()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getgenerate":
|
elif cmd == "getgenerate":
|
||||||
try:
|
try:
|
||||||
print access.getgenerate()
|
print access.getgenerate()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "gethashespersec":
|
elif cmd == "gethashespersec":
|
||||||
try:
|
try:
|
||||||
print access.gethashespersec()
|
print access.gethashespersec()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getinfo":
|
elif cmd == "getinfo":
|
||||||
try:
|
try:
|
||||||
print access.getinfo()
|
print access.getinfo()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getnewaddress":
|
elif cmd == "getnewaddress":
|
||||||
try:
|
try:
|
||||||
|
@ -123,8 +123,8 @@ elif cmd == "getnewaddress":
|
||||||
print access.getnewaddress(acct)
|
print access.getnewaddress(acct)
|
||||||
except:
|
except:
|
||||||
print access.getnewaddress()
|
print access.getnewaddress()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getreceivedbyaccount":
|
elif cmd == "getreceivedbyaccount":
|
||||||
try:
|
try:
|
||||||
|
@ -134,8 +134,8 @@ elif cmd == "getreceivedbyaccount":
|
||||||
print access.getreceivedbyaccount(acct, mc)
|
print access.getreceivedbyaccount(acct, mc)
|
||||||
except:
|
except:
|
||||||
print access.getreceivedbyaccount()
|
print access.getreceivedbyaccount()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getreceivedbyaddress":
|
elif cmd == "getreceivedbyaddress":
|
||||||
try:
|
try:
|
||||||
|
@ -145,15 +145,15 @@ elif cmd == "getreceivedbyaddress":
|
||||||
print access.getreceivedbyaddress(addr, mc)
|
print access.getreceivedbyaddress(addr, mc)
|
||||||
except:
|
except:
|
||||||
print access.getreceivedbyaddress()
|
print access.getreceivedbyaddress()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "gettransaction":
|
elif cmd == "gettransaction":
|
||||||
try:
|
try:
|
||||||
txid = raw_input("Enter a transaction ID: ")
|
txid = raw_input("Enter a transaction ID: ")
|
||||||
print access.gettransaction(txid)
|
print access.gettransaction(txid)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "getwork":
|
elif cmd == "getwork":
|
||||||
try:
|
try:
|
||||||
|
@ -162,8 +162,8 @@ elif cmd == "getwork":
|
||||||
print access.gettransaction(data)
|
print access.gettransaction(data)
|
||||||
except:
|
except:
|
||||||
print access.gettransaction()
|
print access.gettransaction()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "help":
|
elif cmd == "help":
|
||||||
try:
|
try:
|
||||||
|
@ -172,8 +172,8 @@ elif cmd == "help":
|
||||||
print access.help(cmd)
|
print access.help(cmd)
|
||||||
except:
|
except:
|
||||||
print access.help()
|
print access.help()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "listaccounts":
|
elif cmd == "listaccounts":
|
||||||
try:
|
try:
|
||||||
|
@ -182,8 +182,8 @@ elif cmd == "listaccounts":
|
||||||
print access.listaccounts(mc)
|
print access.listaccounts(mc)
|
||||||
except:
|
except:
|
||||||
print access.listaccounts()
|
print access.listaccounts()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "listreceivedbyaccount":
|
elif cmd == "listreceivedbyaccount":
|
||||||
try:
|
try:
|
||||||
|
@ -193,8 +193,8 @@ elif cmd == "listreceivedbyaccount":
|
||||||
print access.listreceivedbyaccount(mc, incemp)
|
print access.listreceivedbyaccount(mc, incemp)
|
||||||
except:
|
except:
|
||||||
print access.listreceivedbyaccount()
|
print access.listreceivedbyaccount()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "listreceivedbyaddress":
|
elif cmd == "listreceivedbyaddress":
|
||||||
try:
|
try:
|
||||||
|
@ -204,8 +204,8 @@ elif cmd == "listreceivedbyaddress":
|
||||||
print access.listreceivedbyaddress(mc, incemp)
|
print access.listreceivedbyaddress(mc, incemp)
|
||||||
except:
|
except:
|
||||||
print access.listreceivedbyaddress()
|
print access.listreceivedbyaddress()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "listtransactions":
|
elif cmd == "listtransactions":
|
||||||
try:
|
try:
|
||||||
|
@ -216,8 +216,8 @@ elif cmd == "listtransactions":
|
||||||
print access.listtransactions(acct, count, frm)
|
print access.listtransactions(acct, count, frm)
|
||||||
except:
|
except:
|
||||||
print access.listtransactions()
|
print access.listtransactions()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "move":
|
elif cmd == "move":
|
||||||
try:
|
try:
|
||||||
|
@ -230,8 +230,8 @@ elif cmd == "move":
|
||||||
print access.move(frm, to, amt, mc, comment)
|
print access.move(frm, to, amt, mc, comment)
|
||||||
except:
|
except:
|
||||||
print access.move(frm, to, amt)
|
print access.move(frm, to, amt)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "sendfrom":
|
elif cmd == "sendfrom":
|
||||||
try:
|
try:
|
||||||
|
@ -245,8 +245,8 @@ elif cmd == "sendfrom":
|
||||||
print access.sendfrom(frm, to, amt, mc, comment, commentto)
|
print access.sendfrom(frm, to, amt, mc, comment, commentto)
|
||||||
except:
|
except:
|
||||||
print access.sendfrom(frm, to, amt)
|
print access.sendfrom(frm, to, amt)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "sendmany":
|
elif cmd == "sendmany":
|
||||||
try:
|
try:
|
||||||
|
@ -258,8 +258,8 @@ elif cmd == "sendmany":
|
||||||
print access.sendmany(frm,to,mc,comment)
|
print access.sendmany(frm,to,mc,comment)
|
||||||
except:
|
except:
|
||||||
print access.sendmany(frm,to)
|
print access.sendmany(frm,to)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "sendtoaddress":
|
elif cmd == "sendtoaddress":
|
||||||
try:
|
try:
|
||||||
|
@ -271,16 +271,16 @@ elif cmd == "sendtoaddress":
|
||||||
print access.sendtoaddress(to,amt,comment,commentto)
|
print access.sendtoaddress(to,amt,comment,commentto)
|
||||||
except:
|
except:
|
||||||
print access.sendtoaddress(to,amt)
|
print access.sendtoaddress(to,amt)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "setaccount":
|
elif cmd == "setaccount":
|
||||||
try:
|
try:
|
||||||
addr = raw_input("Address: ")
|
addr = raw_input("Address: ")
|
||||||
acct = raw_input("Account:")
|
acct = raw_input("Account:")
|
||||||
print access.setaccount(addr,acct)
|
print access.setaccount(addr,acct)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "setgenerate":
|
elif cmd == "setgenerate":
|
||||||
try:
|
try:
|
||||||
|
@ -290,36 +290,36 @@ elif cmd == "setgenerate":
|
||||||
print access.setgenerate(gen, cpus)
|
print access.setgenerate(gen, cpus)
|
||||||
except:
|
except:
|
||||||
print access.setgenerate(gen)
|
print access.setgenerate(gen)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "settxfee":
|
elif cmd == "settxfee":
|
||||||
try:
|
try:
|
||||||
amt = raw_input("Amount:")
|
amt = raw_input("Amount:")
|
||||||
print access.settxfee(amt)
|
print access.settxfee(amt)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "stop":
|
elif cmd == "stop":
|
||||||
try:
|
try:
|
||||||
print access.stop()
|
print access.stop()
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "validateaddress":
|
elif cmd == "validateaddress":
|
||||||
try:
|
try:
|
||||||
addr = raw_input("Address: ")
|
addr = raw_input("Address: ")
|
||||||
print access.validateaddress(addr)
|
print access.validateaddress(addr)
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "walletpassphrase":
|
elif cmd == "walletpassphrase":
|
||||||
try:
|
try:
|
||||||
pwd = getpass.getpass(prompt="Enter wallet passphrase: ")
|
pwd = getpass.getpass(prompt="Enter wallet passphrase: ")
|
||||||
access.walletpassphrase(pwd, 60)
|
access.walletpassphrase(pwd, 60)
|
||||||
print "\n---Wallet unlocked---\n"
|
print "\n---Wallet unlocked---\n"
|
||||||
except:
|
except Exception as inst:
|
||||||
print "\n---An error occurred---\n"
|
print inst
|
||||||
|
|
||||||
elif cmd == "walletpassphrasechange":
|
elif cmd == "walletpassphrasechange":
|
||||||
try:
|
try:
|
||||||
|
@ -328,10 +328,8 @@ elif cmd == "walletpassphrasechange":
|
||||||
access.walletpassphrasechange(pwd, pwd2)
|
access.walletpassphrasechange(pwd, pwd2)
|
||||||
print
|
print
|
||||||
print "\n---Passphrase changed---\n"
|
print "\n---Passphrase changed---\n"
|
||||||
except:
|
except Exception as inst:
|
||||||
print
|
print inst
|
||||||
print "\n---An error occurred---\n"
|
|
||||||
print
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print "Command not found or not supported"
|
print "Command not found or not supported"
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
debian/manpages/bitcoind.1
|
debian/manpages/bitcoind.1
|
||||||
debian/manpages/bitcoin.conf.5
|
debian/manpages/bitcoin.conf.5
|
||||||
|
debian/manpages/bitcoin-cli.1
|
||||||
|
|
48
contrib/debian/manpages/bitcoin-cli.1
Normal file
48
contrib/debian/manpages/bitcoin-cli.1
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
.TH BITCOIN-CLI "1" "February 2015" "bitcoin-cli 0.10"
|
||||||
|
.SH NAME
|
||||||
|
bitcoin-cli \- a remote procedure call client for Bitcoin Core.
|
||||||
|
.SH SYNOPSIS
|
||||||
|
bitcoin-cli [options] <command> [params] \- Send command to Bitcoin Core.
|
||||||
|
.TP
|
||||||
|
bitcoin-cli [options] help \- Asks Bitcoin Core for a list of supported commands.
|
||||||
|
.SH DESCRIPTION
|
||||||
|
This manual page documents the bitcoin-cli program. bitcoin-cli is an RPC client used to send commands to Bitcoin Core.
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
\fB\-?\fR
|
||||||
|
Show the help message.
|
||||||
|
.TP
|
||||||
|
\fB\-conf=\fR<file>
|
||||||
|
Specify configuration file (default: bitcoin.conf).
|
||||||
|
.TP
|
||||||
|
\fB\-datadir=\fR<dir>
|
||||||
|
Specify data directory.
|
||||||
|
.TP
|
||||||
|
\fB\-testnet\fR
|
||||||
|
Connect to a Bitcoin Core instance running in testnet mode.
|
||||||
|
.TP
|
||||||
|
\fB\-regtest\fR
|
||||||
|
Connect to a Bitcoin Core instance running in regtest mode (see documentation for -regtest on bitcoind).
|
||||||
|
.TP
|
||||||
|
\fB\-rpcuser=\fR<user>
|
||||||
|
Username for JSON\-RPC connections.
|
||||||
|
.TP
|
||||||
|
\fB\-rpcpassword=\fR<pw>
|
||||||
|
Password for JSON\-RPC connections.
|
||||||
|
.TP
|
||||||
|
\fB\-rpcport=\fR<port>
|
||||||
|
Listen for JSON\-RPC connections on <port> (default: 8332 or testnet: 18332).
|
||||||
|
.TP
|
||||||
|
\fB\-rpcconnect=\fR<ip>
|
||||||
|
Send commands to node running on <ip> (default: 127.0.0.1).
|
||||||
|
.TP
|
||||||
|
\fB\-rpcssl\fR=\fI1\fR
|
||||||
|
Use OpenSSL (https) for JSON\-RPC connections (see the Bitcoin Wiki for SSL setup instructions).
|
||||||
|
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
\fBbitcoind\fP, \fBbitcoin.conf\fP
|
||||||
|
.SH AUTHOR
|
||||||
|
This manual page was written by Ciemon Dunville <ciemon@gmail.com>. Permission is granted to copy, distribute and/or modify this document under the terms of the MIT License.
|
||||||
|
|
||||||
|
The complete text of the MIT License can be found on the web at \fIhttp://opensource.org/licenses/MIT\fP.
|
|
@ -15,6 +15,7 @@ packages:
|
||||||
- "faketime"
|
- "faketime"
|
||||||
- "bsdmainutils"
|
- "bsdmainutils"
|
||||||
- "binutils-gold"
|
- "binutils-gold"
|
||||||
|
- "libstdc++6-4.6-pic"
|
||||||
reference_datetime: "2013-06-01 00:00:00"
|
reference_datetime: "2013-06-01 00:00:00"
|
||||||
remotes:
|
remotes:
|
||||||
- "url": "https://github.com/bitcoin/bitcoin.git"
|
- "url": "https://github.com/bitcoin/bitcoin.git"
|
||||||
|
@ -23,7 +24,7 @@ files: []
|
||||||
script: |
|
script: |
|
||||||
WRAP_DIR=$HOME/wrapped
|
WRAP_DIR=$HOME/wrapped
|
||||||
HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu"
|
HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu"
|
||||||
CONFIGFLAGS="--enable-upnp-default --enable-glibc-back-compat"
|
CONFIGFLAGS="--enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++"
|
||||||
FAKETIME_HOST_PROGS=""
|
FAKETIME_HOST_PROGS=""
|
||||||
FAKETIME_PROGS="date ar ranlib nm strip"
|
FAKETIME_PROGS="date ar ranlib nm strip"
|
||||||
|
|
||||||
|
@ -69,6 +70,14 @@ script: |
|
||||||
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
|
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Ubuntu precise hack: Not an issue in later versions.
|
||||||
|
# Precise's libstdc++.a is non-pic. There's an optional libstdc++6-4.6-pic
|
||||||
|
# package which provides libstdc++_pic.a, but the linker can't find it.
|
||||||
|
# Symlink it to a path that will be included in our link-line so that the
|
||||||
|
# linker picks it up before the default libstdc++.a.
|
||||||
|
# This is only necessary for 64bit.
|
||||||
|
ln -s /usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++_pic.a ${BASEPREFIX}/x86_64-unknown-linux-gnu/lib/libstdc++.a
|
||||||
|
|
||||||
# Create the release tarball using (arbitrarily) the first host
|
# Create the release tarball using (arbitrarily) the first host
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
|
./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
|
||||||
|
|
|
@ -27,7 +27,7 @@ files:
|
||||||
script: |
|
script: |
|
||||||
WRAP_DIR=$HOME/wrapped
|
WRAP_DIR=$HOME/wrapped
|
||||||
HOSTS="x86_64-apple-darwin11"
|
HOSTS="x86_64-apple-darwin11"
|
||||||
CONFIGFLAGS="--enable-upnp-default GENISOIMAGE=$WRAP_DIR/genisoimage"
|
CONFIGFLAGS="--enable-upnp-default --enable-reduce-exports GENISOIMAGE=$WRAP_DIR/genisoimage"
|
||||||
FAKETIME_HOST_PROGS=""
|
FAKETIME_HOST_PROGS=""
|
||||||
FAKETIME_PROGS="ar ranlib date dmg genisoimage"
|
FAKETIME_PROGS="ar ranlib date dmg genisoimage"
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ files: []
|
||||||
script: |
|
script: |
|
||||||
WRAP_DIR=$HOME/wrapped
|
WRAP_DIR=$HOME/wrapped
|
||||||
HOSTS="x86_64-w64-mingw32 i686-w64-mingw32"
|
HOSTS="x86_64-w64-mingw32 i686-w64-mingw32"
|
||||||
CONFIGFLAGS="--enable-upnp-default"
|
CONFIGFLAGS="--enable-upnp-default --enable-reduce-exports"
|
||||||
FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip"
|
FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip"
|
||||||
FAKETIME_PROGS="date makensis zip"
|
FAKETIME_PROGS="date makensis zip"
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ SystemD: bitcoind.service
|
||||||
Upstart: bitcoind.conf
|
Upstart: bitcoind.conf
|
||||||
OpenRC: bitcoind.openrc
|
OpenRC: bitcoind.openrc
|
||||||
bitcoind.openrcconf
|
bitcoind.openrcconf
|
||||||
|
CentOS: bitcoind.init
|
||||||
|
|
||||||
have been made available to assist packagers in creating node packages here.
|
have been made available to assist packagers in creating node packages here.
|
||||||
|
|
||||||
|
|
67
contrib/init/bitcoind.init
Normal file
67
contrib/init/bitcoind.init
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# bitcoind The bitcoin core server.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# chkconfig: 345 80 20
|
||||||
|
# description: bitcoind
|
||||||
|
# processname: bitcoind
|
||||||
|
#
|
||||||
|
|
||||||
|
# Source function library.
|
||||||
|
. /etc/init.d/functions
|
||||||
|
|
||||||
|
# you can override defaults in /etc/sysconfig/bitcoind, see below
|
||||||
|
if [ -f /etc/sysconfig/bitcoind ]; then
|
||||||
|
. /etc/sysconfig/bitcoind
|
||||||
|
fi
|
||||||
|
|
||||||
|
RETVAL=0
|
||||||
|
|
||||||
|
prog=bitcoind
|
||||||
|
# you can override the lockfile via BITCOIND_LOCKFILE in /etc/sysconfig/bitcoind
|
||||||
|
lockfile=${BITCOIND_LOCKFILE-/var/lock/subsys/bitcoind}
|
||||||
|
|
||||||
|
# bitcoind defaults to /usr/bin/bitcoind, override with BITCOIND_BIN
|
||||||
|
bitcoind=${BITCOIND_BIN-/usr/bin/bitcoind}
|
||||||
|
|
||||||
|
# bitcoind opts default to -disablewallet, override with BITCOIND_OPTS
|
||||||
|
bitcoind_opts=${BITCOIND_OPTS--disablewallet}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
echo -n $"Starting $prog: "
|
||||||
|
daemon $DAEMONOPTS $bitcoind $bitcoind_opts
|
||||||
|
RETVAL=$?
|
||||||
|
echo
|
||||||
|
[ $RETVAL -eq 0 ] && touch $lockfile
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
echo -n $"Stopping $prog: "
|
||||||
|
killproc $prog
|
||||||
|
RETVAL=$?
|
||||||
|
echo
|
||||||
|
[ $RETVAL -eq 0 ] && rm -f $lockfile
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stop
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
status $prog
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
stop
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: service $prog {start|stop|status|restart}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
|
@ -12,9 +12,11 @@ BITCOIND_CONFIGFILE=${BITCOIND_CONFIGFILE:-/etc/bitcoin/bitcoin.conf}
|
||||||
BITCOIND_PIDDIR=${BITCOIND_PIDDIR:-/var/run/bitcoind}
|
BITCOIND_PIDDIR=${BITCOIND_PIDDIR:-/var/run/bitcoind}
|
||||||
BITCOIND_PIDFILE=${BITCOIND_PIDFILE:-${BITCOIND_PIDDIR}/bitcoind.pid}
|
BITCOIND_PIDFILE=${BITCOIND_PIDFILE:-${BITCOIND_PIDDIR}/bitcoind.pid}
|
||||||
BITCOIND_DATADIR=${BITCOIND_DATADIR:-${BITCOIND_DEFAULT_DATADIR}}
|
BITCOIND_DATADIR=${BITCOIND_DATADIR:-${BITCOIND_DEFAULT_DATADIR}}
|
||||||
BITCOIND_USER=${BITCOIND_USER:-bitcoin}
|
BITCOIND_USER=${BITCOIND_USER:-${BITCOIN_USER:-bitcoin}}
|
||||||
BITCOIND_GROUP=${BITCOIND_GROUP:-bitcoin}
|
BITCOIND_GROUP=${BITCOIND_GROUP:-bitcoin}
|
||||||
BITCOIND_BIN=${BITCOIND_BIN:-/usr/bin/bitcoind}
|
BITCOIND_BIN=${BITCOIND_BIN:-/usr/bin/bitcoind}
|
||||||
|
BITCOIND_NICE=${BITCOIND_NICE:-${NICELEVEL:-0}}
|
||||||
|
BITCOIND_OPTS="${BITCOIND_OPTS:-${BITCOIN_OPTS}}"
|
||||||
|
|
||||||
name="Bitcoin Core Daemon"
|
name="Bitcoin Core Daemon"
|
||||||
description="Bitcoin crypto-currency p2p network daemon"
|
description="Bitcoin crypto-currency p2p network daemon"
|
||||||
|
@ -28,7 +30,7 @@ command_args="-pid=\"${BITCOIND_PIDFILE}\" \
|
||||||
|
|
||||||
required_files="${BITCOIND_CONFIGFILE}"
|
required_files="${BITCOIND_CONFIGFILE}"
|
||||||
start_stop_daemon_args="-u ${BITCOIND_USER} \
|
start_stop_daemon_args="-u ${BITCOIND_USER} \
|
||||||
-N ${BITCOIND_NICE:-0} -w 2000"
|
-N ${BITCOIND_NICE} -w 2000"
|
||||||
pidfile="${BITCOIND_PIDFILE}"
|
pidfile="${BITCOIND_PIDFILE}"
|
||||||
retry=60
|
retry=60
|
||||||
|
|
||||||
|
|
15
contrib/verify-commits/gpg.sh
Executable file
15
contrib/verify-commits/gpg.sh
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/sh
|
||||||
|
INPUT=$(</dev/stdin)
|
||||||
|
VALID=false
|
||||||
|
IFS=$'\n'
|
||||||
|
for LINE in $(echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null); do
|
||||||
|
case "$LINE" in "[GNUPG:] VALIDSIG"*)
|
||||||
|
while read KEY; do
|
||||||
|
case "$LINE" in "[GNUPG:] VALIDSIG $KEY "*) VALID=true;; esac
|
||||||
|
done < ./contrib/verify-commits/trusted-keys
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
if ! $VALID; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null
|
16
contrib/verify-commits/pre-push-hook.sh
Executable file
16
contrib/verify-commits/pre-push-hook.sh
Executable file
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/bash
|
||||||
|
if ! [[ "$2" =~ [git@]?[www.]?github.com[:|/]bitcoin/bitcoin[.git]? ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
while read LINE; do
|
||||||
|
set -- A $LINE
|
||||||
|
if [ "$4" != "refs/heads/master" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if ! ./contrib/verify-commits/verify-commits.sh $3 > /dev/null 2>&1; then
|
||||||
|
echo "ERROR: A commit is not signed, can't push"
|
||||||
|
./contrib/verify-commits/verify-commits.sh
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done < /dev/stdin
|
1
contrib/verify-commits/trusted-git-root
Normal file
1
contrib/verify-commits/trusted-git-root
Normal file
|
@ -0,0 +1 @@
|
||||||
|
053038e5ba116cb319fb85f3cb3e062cf1b3df15
|
5
contrib/verify-commits/trusted-keys
Normal file
5
contrib/verify-commits/trusted-keys
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
71A3B16735405025D447E8F274810B012346C9A6
|
||||||
|
1F4410F6A89268CE3197A84C57896D2FF8F0B657
|
||||||
|
01CDF4627A3B88AAE4A571C87588242FBE38D3A8
|
||||||
|
AF8BE07C7049F3A26B239D5325B3083201782B2F
|
||||||
|
81291FA67D2C379A006A053FEAB5AF94D9E9ABE7
|
51
contrib/verify-commits/verify-commits.sh
Executable file
51
contrib/verify-commits/verify-commits.sh
Executable file
|
@ -0,0 +1,51 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
DIR=$(dirname "$0")
|
||||||
|
|
||||||
|
echo "Please verify all commits in the following list are not evil:"
|
||||||
|
git log "$DIR"
|
||||||
|
|
||||||
|
VERIFIED_ROOT=$(cat "${DIR}/trusted-git-root")
|
||||||
|
|
||||||
|
HAVE_FAILED=false
|
||||||
|
IS_SIGNED () {
|
||||||
|
if [ $1 = $VERIFIED_ROOT ]; then
|
||||||
|
return 0;
|
||||||
|
fi
|
||||||
|
if ! git -c "gpg.program=${DIR}/gpg.sh" verify-commit $1 > /dev/null 2>&1; then
|
||||||
|
return 1;
|
||||||
|
fi
|
||||||
|
local PARENTS=$(git show -s --format=format:%P $1)
|
||||||
|
for PARENT in $PARENTS; do
|
||||||
|
if IS_SIGNED $PARENT > /dev/null; then
|
||||||
|
return 0;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if ! "$HAVE_FAILED"; then
|
||||||
|
echo "No parent of $1 was signed with a trusted key!" > /dev/stderr
|
||||||
|
echo "Parents are:" > /dev/stderr
|
||||||
|
for PARENT in $PARENTS; do
|
||||||
|
git show -s $PARENT > /dev/stderr
|
||||||
|
done
|
||||||
|
HAVE_FAILED=true
|
||||||
|
fi
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ x"$1" = "x" ]; then
|
||||||
|
TEST_COMMIT="HEAD"
|
||||||
|
else
|
||||||
|
TEST_COMMIT="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
IS_SIGNED "$TEST_COMMIT"
|
||||||
|
RES=$?
|
||||||
|
if [ "$RES" = 1 ]; then
|
||||||
|
if ! "$HAVE_FAILED"; then
|
||||||
|
echo "$TEST_COMMIT was not signed with a trusted key!"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "There is a valid path from $TEST_COMMIT to $VERIFIED_ROOT where all commits are signed!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $RES
|
|
@ -6,7 +6,6 @@ SDK_PATH ?= $(BASEDIR)/SDKs
|
||||||
NO_QT ?=
|
NO_QT ?=
|
||||||
NO_WALLET ?=
|
NO_WALLET ?=
|
||||||
NO_UPNP ?=
|
NO_UPNP ?=
|
||||||
USE_LINUX_STATIC_QT5 ?=
|
|
||||||
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
|
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
|
||||||
|
|
||||||
BUILD = $(shell ./config.guess)
|
BUILD = $(shell ./config.guess)
|
||||||
|
|
|
@ -23,7 +23,6 @@ NO_QT: Don't download/build/cache qt and its dependencies
|
||||||
NO_WALLET: Don't download/build/cache libs needed to enable the wallet
|
NO_WALLET: Don't download/build/cache libs needed to enable the wallet
|
||||||
NO_UPNP: Don't download/build/cache packages needed for enabling upnp
|
NO_UPNP: Don't download/build/cache packages needed for enabling upnp
|
||||||
DEBUG: disable some optimizations and enable more runtime checking
|
DEBUG: disable some optimizations and enable more runtime checking
|
||||||
USE_LINUX_STATIC_QT5: Build a static qt5 rather than shared qt4. Linux only.
|
|
||||||
|
|
||||||
If some packages are not built, for example 'make NO_WALLET=1', the appropriate
|
If some packages are not built, for example 'make NO_WALLET=1', the appropriate
|
||||||
options will be passed to bitcoin's configure. In this case, --disable-wallet.
|
options will be passed to bitcoin's configure. In this case, --disable-wallet.
|
||||||
|
|
|
@ -13,8 +13,13 @@ define $(package)_preprocess_cmds
|
||||||
sed "s/pthread-stubs//" -i configure
|
sed "s/pthread-stubs//" -i configure
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
# Don't install xcb headers to the default path in order to work around a qt
|
||||||
|
# build issue: https://bugreports.qt.io/browse/QTBUG-34748
|
||||||
|
# When using qt's internal libxcb, it may end up finding the real headers in
|
||||||
|
# depends staging. Use a non-default path to avoid that.
|
||||||
|
|
||||||
define $(package)_config_cmds
|
define $(package)_config_cmds
|
||||||
$($(package)_autoconf)
|
$($(package)_autoconf) --includedir=$(host_prefix)/include/xcb-shared
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define $(package)_build_cmds
|
define $(package)_build_cmds
|
||||||
|
|
|
@ -4,15 +4,10 @@ native_packages := native_ccache native_comparisontool
|
||||||
qt_native_packages = native_protobuf
|
qt_native_packages = native_protobuf
|
||||||
qt_packages = qrencode protobuf
|
qt_packages = qrencode protobuf
|
||||||
|
|
||||||
qt46_linux_packages = qt46 expat dbus libxcb xcb_proto libXau xproto freetype libX11 xextproto libXext xtrans libICE libSM
|
qt_linux_packages= qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans
|
||||||
qt5_linux_packages= qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans
|
|
||||||
|
|
||||||
qt_darwin_packages=qt
|
qt_darwin_packages=qt
|
||||||
qt_mingw32_packages=qt
|
qt_mingw32_packages=qt
|
||||||
|
|
||||||
qt_linux_$(USE_LINUX_STATIC_QT5):=$(qt5_linux_packages)
|
|
||||||
qt_linux_:=$(qt46_linux_packages)
|
|
||||||
qt_linux_packages:=$(qt_linux_$(USE_LINUX_STATIC_QT5))
|
|
||||||
|
|
||||||
wallet_packages=bdb
|
wallet_packages=bdb
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,31 @@
|
||||||
--- old/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2014-07-30 18:17:27.384458441 -0400
|
--- old/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-03-17 02:06:42.705930685 +0000
|
||||||
+++ new/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2014-07-30 18:18:28.620459303 -0400
|
+++ new/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2015-03-17 02:08:41.281926351 +0000
|
||||||
@@ -101,10 +101,6 @@
|
@@ -103,7 +103,6 @@
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-DEFINES += $$QMAKE_DEFINES_XCB
|
DEFINES += $$QMAKE_DEFINES_XCB
|
||||||
-LIBS += $$QMAKE_LIBS_XCB
|
LIBS += $$QMAKE_LIBS_XCB
|
||||||
-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
|
-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
|
||||||
-
|
|
||||||
CONFIG += qpa/genericunixfontdatabase
|
CONFIG += qpa/genericunixfontdatabase
|
||||||
|
|
||||||
contains(QT_CONFIG, dbus) {
|
@@ -118,7 +117,8 @@
|
||||||
@@ -141,3 +137,7 @@
|
contains(QT_CONFIG, xcb-qt) {
|
||||||
INCLUDEPATH += ../../../3rdparty/xkbcommon/xkbcommon/
|
DEFINES += XCB_USE_RENDER
|
||||||
}
|
XCB_DIR = ../../../3rdparty/xcb
|
||||||
}
|
- INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude
|
||||||
+
|
+ QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB
|
||||||
+DEFINES += $$QMAKE_DEFINES_XCB
|
+ QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB
|
||||||
+LIBS += $$QMAKE_LIBS_XCB
|
LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static
|
||||||
+INCLUDEPATH += $$QMAKE_CFLAGS_XCB
|
} else {
|
||||||
|
LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr
|
||||||
|
--- old/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:07:04.641929383 +0000
|
||||||
|
+++ new/qtbase/src/plugins/platforms/xcb/xcb-static/xcb-static.pro 2015-03-17 02:10:15.485922059 +0000
|
||||||
|
@@ -8,7 +8,7 @@
|
||||||
|
|
||||||
|
XCB_DIR = ../../../../3rdparty/xcb
|
||||||
|
|
||||||
|
-INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude
|
||||||
|
+QMAKE_CFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/include/xcb -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB
|
||||||
|
|
||||||
|
# ignore compiler warnings in 3rdparty code
|
||||||
|
QMAKE_CFLAGS_STATIC_LIB+=-w
|
||||||
|
|
12
doc/init.md
12
doc/init.md
|
@ -8,6 +8,7 @@ can be found in the contrib/init folder.
|
||||||
contrib/init/bitcoind.openrc: OpenRC compatible SysV style init script
|
contrib/init/bitcoind.openrc: OpenRC compatible SysV style init script
|
||||||
contrib/init/bitcoind.openrcconf: OpenRC conf.d file
|
contrib/init/bitcoind.openrcconf: OpenRC conf.d file
|
||||||
contrib/init/bitcoind.conf: Upstart service configuration file
|
contrib/init/bitcoind.conf: Upstart service configuration file
|
||||||
|
contrib/init/bitcoind.init: CentOS compatible SysV style init script
|
||||||
|
|
||||||
1. Service User
|
1. Service User
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
@ -49,6 +50,7 @@ Configuration file: /etc/bitcoin/bitcoin.conf
|
||||||
Data directory: /var/lib/bitcoind
|
Data directory: /var/lib/bitcoind
|
||||||
PID file: /var/run/bitcoind/bitcoind.pid (OpenRC and Upstart)
|
PID file: /var/run/bitcoind/bitcoind.pid (OpenRC and Upstart)
|
||||||
/var/lib/bitcoind/bitcoind.pid (systemd)
|
/var/lib/bitcoind/bitcoind.pid (systemd)
|
||||||
|
Lock file: /var/lock/subsys/bitcoind (CentOS)
|
||||||
|
|
||||||
The configuration file, PID directory (if applicable) and data directory
|
The configuration file, PID directory (if applicable) and data directory
|
||||||
should all be owned by the bitcoin user and group. It is advised for security
|
should all be owned by the bitcoin user and group. It is advised for security
|
||||||
|
@ -81,7 +83,15 @@ Drop bitcoind.conf in /etc/init. Test by running "service bitcoind start"
|
||||||
it will automatically start on reboot.
|
it will automatically start on reboot.
|
||||||
|
|
||||||
NOTE: This script is incompatible with CentOS 5 and Amazon Linux 2014 as they
|
NOTE: This script is incompatible with CentOS 5 and Amazon Linux 2014 as they
|
||||||
use old versions of Upstart and do not supply the start-stop-daemon uitility.
|
use old versions of Upstart and do not supply the start-stop-daemon utility.
|
||||||
|
|
||||||
|
4d) CentOS
|
||||||
|
|
||||||
|
Copy bitcoind.init to /etc/init.d/bitcoind. Test by running "service bitcoind start".
|
||||||
|
|
||||||
|
Using this script, you can adjust the path and flags to the bitcoind program by
|
||||||
|
setting the BITCOIND and FLAGS environment variables in the file
|
||||||
|
/etc/sysconfig/bitcoind. You can also use the DAEMONOPTS environment variable here.
|
||||||
|
|
||||||
5. Auto-respawn
|
5. Auto-respawn
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
76
qa/rpc-tests/invalidateblock.py
Executable file
76
qa/rpc-tests/invalidateblock.py
Executable file
|
@ -0,0 +1,76 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
# Copyright (c) 2014 The Bitcoin Core developers
|
||||||
|
# Distributed under the MIT software license, see the accompanying
|
||||||
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test InvalidateBlock code
|
||||||
|
#
|
||||||
|
|
||||||
|
from test_framework import BitcoinTestFramework
|
||||||
|
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
|
||||||
|
from util import *
|
||||||
|
|
||||||
|
class InvalidateTest(BitcoinTestFramework):
|
||||||
|
|
||||||
|
|
||||||
|
def setup_chain(self):
|
||||||
|
print("Initializing test directory "+self.options.tmpdir)
|
||||||
|
initialize_chain_clean(self.options.tmpdir, 3)
|
||||||
|
|
||||||
|
def setup_network(self):
|
||||||
|
self.nodes = []
|
||||||
|
self.is_network_split = False
|
||||||
|
self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"]))
|
||||||
|
self.nodes.append(start_node(1, self.options.tmpdir, ["-debug"]))
|
||||||
|
self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"]))
|
||||||
|
|
||||||
|
def run_test(self):
|
||||||
|
print "Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:"
|
||||||
|
print "Mine 4 blocks on Node 0"
|
||||||
|
self.nodes[0].setgenerate(True, 4)
|
||||||
|
assert(self.nodes[0].getblockcount() == 4)
|
||||||
|
besthash = self.nodes[0].getbestblockhash()
|
||||||
|
|
||||||
|
print "Mine competing 6 blocks on Node 1"
|
||||||
|
self.nodes[1].setgenerate(True, 6)
|
||||||
|
assert(self.nodes[1].getblockcount() == 6)
|
||||||
|
|
||||||
|
print "Connect nodes to force a reorg"
|
||||||
|
connect_nodes_bi(self.nodes,0,1)
|
||||||
|
sync_blocks(self.nodes[0:2])
|
||||||
|
assert(self.nodes[0].getblockcount() == 6)
|
||||||
|
badhash = self.nodes[1].getblockhash(2)
|
||||||
|
|
||||||
|
print "Invalidate block 2 on node 0 and verify we reorg to node 0's original chain"
|
||||||
|
self.nodes[0].invalidateblock(badhash)
|
||||||
|
newheight = self.nodes[0].getblockcount()
|
||||||
|
newhash = self.nodes[0].getbestblockhash()
|
||||||
|
if (newheight != 4 or newhash != besthash):
|
||||||
|
raise AssertionError("Wrong tip for node0, hash %s, height %d"%(newhash,newheight))
|
||||||
|
|
||||||
|
print "\nMake sure we won't reorg to a lower work chain:"
|
||||||
|
connect_nodes_bi(self.nodes,1,2)
|
||||||
|
print "Sync node 2 to node 1 so both have 6 blocks"
|
||||||
|
sync_blocks(self.nodes[1:3])
|
||||||
|
assert(self.nodes[2].getblockcount() == 6)
|
||||||
|
print "Invalidate block 5 on node 1 so its tip is now at 4"
|
||||||
|
self.nodes[1].invalidateblock(self.nodes[1].getblockhash(5))
|
||||||
|
assert(self.nodes[1].getblockcount() == 4)
|
||||||
|
print "Invalidate block 3 on node 2, so its tip is now 2"
|
||||||
|
self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3))
|
||||||
|
assert(self.nodes[2].getblockcount() == 2)
|
||||||
|
print "..and then mine a block"
|
||||||
|
self.nodes[2].setgenerate(True, 1)
|
||||||
|
print "Verify all nodes are at the right height"
|
||||||
|
time.sleep(5)
|
||||||
|
for i in xrange(3):
|
||||||
|
print i,self.nodes[i].getblockcount()
|
||||||
|
assert(self.nodes[2].getblockcount() == 3)
|
||||||
|
assert(self.nodes[0].getblockcount() == 4)
|
||||||
|
node1height = self.nodes[1].getblockcount()
|
||||||
|
if node1height < 4:
|
||||||
|
raise AssertionError("Node 1 reorged to a lower height: %d"%node1height)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
InvalidateTest().main()
|
|
@ -102,6 +102,35 @@ class WalletTest (BitcoinTestFramework):
|
||||||
assert_equal(self.nodes[2].getbalance(), 100)
|
assert_equal(self.nodes[2].getbalance(), 100)
|
||||||
assert_equal(self.nodes[2].getbalance("from1"), 100-21)
|
assert_equal(self.nodes[2].getbalance("from1"), 100-21)
|
||||||
|
|
||||||
|
# Send 10 BTC normal
|
||||||
|
address = self.nodes[0].getnewaddress("test")
|
||||||
|
self.nodes[2].settxfee(Decimal('0.001'))
|
||||||
|
txid = self.nodes[2].sendtoaddress(address, 10, "", "", False)
|
||||||
|
self.nodes[2].setgenerate(True, 1)
|
||||||
|
self.sync_all()
|
||||||
|
assert_equal(self.nodes[2].getbalance(), Decimal('89.99900000'))
|
||||||
|
assert_equal(self.nodes[0].getbalance(), Decimal('10.00000000'))
|
||||||
|
|
||||||
|
# Send 10 BTC with subtract fee from amount
|
||||||
|
txid = self.nodes[2].sendtoaddress(address, 10, "", "", True)
|
||||||
|
self.nodes[2].setgenerate(True, 1)
|
||||||
|
self.sync_all()
|
||||||
|
assert_equal(self.nodes[2].getbalance(), Decimal('79.99900000'))
|
||||||
|
assert_equal(self.nodes[0].getbalance(), Decimal('19.99900000'))
|
||||||
|
|
||||||
|
# Sendmany 10 BTC
|
||||||
|
txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [])
|
||||||
|
self.nodes[2].setgenerate(True, 1)
|
||||||
|
self.sync_all()
|
||||||
|
assert_equal(self.nodes[2].getbalance(), Decimal('69.99800000'))
|
||||||
|
assert_equal(self.nodes[0].getbalance(), Decimal('29.99900000'))
|
||||||
|
|
||||||
|
# Sendmany 10 BTC with subtract fee from amount
|
||||||
|
txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [address])
|
||||||
|
self.nodes[2].setgenerate(True, 1)
|
||||||
|
self.sync_all()
|
||||||
|
assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000'))
|
||||||
|
assert_equal(self.nodes[0].getbalance(), Decimal('39.99800000'))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
WalletTest ().main ()
|
WalletTest ().main ()
|
||||||
|
|
|
@ -72,7 +72,6 @@ endif
|
||||||
BITCOIN_CORE_H = \
|
BITCOIN_CORE_H = \
|
||||||
addrman.h \
|
addrman.h \
|
||||||
alert.h \
|
alert.h \
|
||||||
allocators.h \
|
|
||||||
amount.h \
|
amount.h \
|
||||||
arith_uint256.h \
|
arith_uint256.h \
|
||||||
base58.h \
|
base58.h \
|
||||||
|
@ -89,8 +88,7 @@ BITCOIN_CORE_H = \
|
||||||
compat.h \
|
compat.h \
|
||||||
compressor.h \
|
compressor.h \
|
||||||
core_io.h \
|
core_io.h \
|
||||||
crypter.h \
|
wallet/db.h \
|
||||||
db.h \
|
|
||||||
eccryptoverify.h \
|
eccryptoverify.h \
|
||||||
ecwrapper.h \
|
ecwrapper.h \
|
||||||
hash.h \
|
hash.h \
|
||||||
|
@ -125,7 +123,10 @@ BITCOIN_CORE_H = \
|
||||||
script/standard.h \
|
script/standard.h \
|
||||||
serialize.h \
|
serialize.h \
|
||||||
streams.h \
|
streams.h \
|
||||||
|
support/allocators/secure.h \
|
||||||
|
support/allocators/zeroafterfree.h \
|
||||||
support/cleanse.h \
|
support/cleanse.h \
|
||||||
|
support/pagelocker.h \
|
||||||
sync.h \
|
sync.h \
|
||||||
threadsafety.h \
|
threadsafety.h \
|
||||||
timedata.h \
|
timedata.h \
|
||||||
|
@ -139,10 +140,14 @@ BITCOIN_CORE_H = \
|
||||||
utilmoneystr.h \
|
utilmoneystr.h \
|
||||||
utilstrencodings.h \
|
utilstrencodings.h \
|
||||||
utiltime.h \
|
utiltime.h \
|
||||||
|
validationinterface.h \
|
||||||
version.h \
|
version.h \
|
||||||
walletdb.h \
|
wallet/crypter.h \
|
||||||
wallet.h \
|
wallet/walletdb.h \
|
||||||
wallet_ismine.h \
|
wallet/wallet.h \
|
||||||
|
wallet/wallet_ismine.h \
|
||||||
|
compat/byteswap.h \
|
||||||
|
compat/endian.h \
|
||||||
compat/sanity.h
|
compat/sanity.h
|
||||||
|
|
||||||
JSON_H = \
|
JSON_H = \
|
||||||
|
@ -191,6 +196,7 @@ libbitcoin_server_a_SOURCES = \
|
||||||
timedata.cpp \
|
timedata.cpp \
|
||||||
txdb.cpp \
|
txdb.cpp \
|
||||||
txmempool.cpp \
|
txmempool.cpp \
|
||||||
|
validationinterface.cpp \
|
||||||
$(JSON_H) \
|
$(JSON_H) \
|
||||||
$(BITCOIN_CORE_H)
|
$(BITCOIN_CORE_H)
|
||||||
|
|
||||||
|
@ -198,13 +204,13 @@ libbitcoin_server_a_SOURCES = \
|
||||||
# when wallet enabled
|
# when wallet enabled
|
||||||
libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
||||||
libbitcoin_wallet_a_SOURCES = \
|
libbitcoin_wallet_a_SOURCES = \
|
||||||
db.cpp \
|
wallet/crypter.cpp \
|
||||||
crypter.cpp \
|
wallet/db.cpp \
|
||||||
rpcdump.cpp \
|
wallet/rpcdump.cpp \
|
||||||
rpcwallet.cpp \
|
wallet/rpcwallet.cpp \
|
||||||
wallet.cpp \
|
wallet/wallet.cpp \
|
||||||
wallet_ismine.cpp \
|
wallet/wallet_ismine.cpp \
|
||||||
walletdb.cpp \
|
wallet/walletdb.cpp \
|
||||||
$(BITCOIN_CORE_H)
|
$(BITCOIN_CORE_H)
|
||||||
|
|
||||||
# crypto primitives library
|
# crypto primitives library
|
||||||
|
@ -235,7 +241,6 @@ univalue_libbitcoin_univalue_a_SOURCES = \
|
||||||
# common: shared between bitcoind, and bitcoin-qt and non-server tools
|
# common: shared between bitcoind, and bitcoin-qt and non-server tools
|
||||||
libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
||||||
libbitcoin_common_a_SOURCES = \
|
libbitcoin_common_a_SOURCES = \
|
||||||
allocators.cpp \
|
|
||||||
arith_uint256.cpp \
|
arith_uint256.cpp \
|
||||||
amount.cpp \
|
amount.cpp \
|
||||||
base58.cpp \
|
base58.cpp \
|
||||||
|
@ -267,6 +272,7 @@ libbitcoin_common_a_SOURCES = \
|
||||||
# backward-compatibility objects and their sanity checks are linked.
|
# backward-compatibility objects and their sanity checks are linked.
|
||||||
libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
||||||
libbitcoin_util_a_SOURCES = \
|
libbitcoin_util_a_SOURCES = \
|
||||||
|
support/pagelocker.cpp \
|
||||||
chainparamsbase.cpp \
|
chainparamsbase.cpp \
|
||||||
clientversion.cpp \
|
clientversion.cpp \
|
||||||
compat/glibc_sanity.cpp \
|
compat/glibc_sanity.cpp \
|
||||||
|
@ -285,7 +291,6 @@ libbitcoin_util_a_SOURCES = \
|
||||||
|
|
||||||
if GLIBC_BACK_COMPAT
|
if GLIBC_BACK_COMPAT
|
||||||
libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
|
libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
|
||||||
libbitcoin_util_a_SOURCES += compat/glibcxx_compat.cpp
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# cli: shared between bitcoin-cli and bitcoin-qt
|
# cli: shared between bitcoin-cli and bitcoin-qt
|
||||||
|
@ -377,16 +382,12 @@ libbitcoinconsensus_la_SOURCES = \
|
||||||
|
|
||||||
if GLIBC_BACK_COMPAT
|
if GLIBC_BACK_COMPAT
|
||||||
libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp
|
libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp
|
||||||
libbitcoinconsensus_la_SOURCES += compat/glibcxx_compat.cpp
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libbitcoinconsensus_la_LDFLAGS = -no-undefined $(RELDFLAGS)
|
libbitcoinconsensus_la_LDFLAGS = -no-undefined $(RELDFLAGS)
|
||||||
libbitcoinconsensus_la_LIBADD = $(CRYPTO_LIBS)
|
libbitcoinconsensus_la_LIBADD = $(CRYPTO_LIBS)
|
||||||
libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BITCOIN_INTERNAL
|
libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BITCOIN_INTERNAL
|
||||||
|
|
||||||
if USE_LIBSECP256K1
|
|
||||||
libbitcoinconsensus_la_LIBADD += secp256k1/libsecp256k1.la
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ BITCOIN_TESTS =\
|
||||||
test/ncctrie_tests.cpp \
|
test/ncctrie_tests.cpp \
|
||||||
test/netbase_tests.cpp \
|
test/netbase_tests.cpp \
|
||||||
test/pmt_tests.cpp \
|
test/pmt_tests.cpp \
|
||||||
|
test/pow_tests.cpp \
|
||||||
test/rpc_tests.cpp \
|
test/rpc_tests.cpp \
|
||||||
test/sanity_tests.cpp \
|
test/sanity_tests.cpp \
|
||||||
test/script_P2SH_tests.cpp \
|
test/script_P2SH_tests.cpp \
|
||||||
|
@ -66,6 +67,7 @@ BITCOIN_TESTS =\
|
||||||
test/sigopcount_tests.cpp \
|
test/sigopcount_tests.cpp \
|
||||||
test/skiplist_tests.cpp \
|
test/skiplist_tests.cpp \
|
||||||
test/test_bitcoin.cpp \
|
test/test_bitcoin.cpp \
|
||||||
|
test/test_bitcoin.h \
|
||||||
test/timedata_tests.cpp \
|
test/timedata_tests.cpp \
|
||||||
test/transaction_tests.cpp \
|
test/transaction_tests.cpp \
|
||||||
test/uint256_tests.cpp \
|
test/uint256_tests.cpp \
|
||||||
|
@ -75,7 +77,7 @@ BITCOIN_TESTS =\
|
||||||
if ENABLE_WALLET
|
if ENABLE_WALLET
|
||||||
BITCOIN_TESTS += \
|
BITCOIN_TESTS += \
|
||||||
test/accounting_tests.cpp \
|
test/accounting_tests.cpp \
|
||||||
test/wallet_tests.cpp \
|
wallet/test/wallet_tests.cpp \
|
||||||
test/rpc_wallet_tests.cpp
|
test/rpc_wallet_tests.cpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -272,8 +272,9 @@ void CAddrMan::Good_(const CService& addr, int64_t nTime)
|
||||||
// update info
|
// update info
|
||||||
info.nLastSuccess = nTime;
|
info.nLastSuccess = nTime;
|
||||||
info.nLastTry = nTime;
|
info.nLastTry = nTime;
|
||||||
info.nTime = nTime;
|
|
||||||
info.nAttempts = 0;
|
info.nAttempts = 0;
|
||||||
|
// nTime is not updated here, to avoid leaking information about
|
||||||
|
// currently-connected peers.
|
||||||
|
|
||||||
// if it is already in the tried set, don't do anything else
|
// if it is already in the tried set, don't do anything else
|
||||||
if (info.fInTried)
|
if (info.fInTried)
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#include "utilstrencodings.h"
|
#include "utilstrencodings.h"
|
||||||
|
#include "crypto/common.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -246,14 +247,14 @@ uint32_t arith_uint256::GetCompact(bool fNegative) const
|
||||||
uint256 ArithToUint256(const arith_uint256 &a)
|
uint256 ArithToUint256(const arith_uint256 &a)
|
||||||
{
|
{
|
||||||
uint256 b;
|
uint256 b;
|
||||||
// TODO: needs bswap32 on big-endian
|
for(int x=0; x<a.WIDTH; ++x)
|
||||||
memcpy(b.begin(), a.pn, a.size());
|
WriteLE32(b.begin() + x*4, a.pn[x]);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
arith_uint256 UintToArith256(const uint256 &a)
|
arith_uint256 UintToArith256(const uint256 &a)
|
||||||
{
|
{
|
||||||
arith_uint256 b;
|
arith_uint256 b;
|
||||||
// TODO: needs bswap32 on big-endian
|
for(int x=0; x<b.WIDTH; ++x)
|
||||||
memcpy(b.pn, a.begin(), a.size());
|
b.pn[x] = ReadLE32(a.begin() + x*4);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "pubkey.h"
|
#include "pubkey.h"
|
||||||
#include "script/script.h"
|
#include "script/script.h"
|
||||||
#include "script/standard.h"
|
#include "script/standard.h"
|
||||||
|
#include "support/allocators/zeroafterfree.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
@ -20,21 +20,21 @@ using namespace json_spirit;
|
||||||
std::string HelpMessageCli()
|
std::string HelpMessageCli()
|
||||||
{
|
{
|
||||||
string strUsage;
|
string strUsage;
|
||||||
strUsage += _("Options:") + "\n";
|
strUsage += HelpMessageGroup(_("Options:"));
|
||||||
strUsage += " -? " + _("This help message") + "\n";
|
strUsage += HelpMessageOpt("-?", _("This help message"));
|
||||||
strUsage += " -conf=<file> " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n";
|
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
|
||||||
strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
|
strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
|
||||||
strUsage += " -testnet " + _("Use the test network") + "\n";
|
strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
|
||||||
strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be "
|
strUsage += HelpMessageOpt("-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";
|
"solved instantly. This is intended for regression testing tools and app development."));
|
||||||
strUsage += " -rpcconnect=<ip> " + strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1") + "\n";
|
strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1"));
|
||||||
strUsage += " -rpcport=<port> " + strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n";
|
strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8332, 18332));
|
||||||
strUsage += " -rpcwait " + _("Wait for RPC server to start") + "\n";
|
strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start"));
|
||||||
strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
|
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
|
||||||
strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
|
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
|
||||||
|
|
||||||
strUsage += "\n" + _("SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
|
strUsage += HelpMessageGroup(_("SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
|
||||||
strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
|
strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
|
||||||
|
|
||||||
return strUsage;
|
return strUsage;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,38 +54,34 @@ static bool AppInitRawTx(int argc, char* argv[])
|
||||||
|
|
||||||
fprintf(stdout, "%s", strUsage.c_str());
|
fprintf(stdout, "%s", strUsage.c_str());
|
||||||
|
|
||||||
strUsage = _("Options:") + "\n";
|
strUsage = HelpMessageGroup(_("Options:"));
|
||||||
strUsage += " -? " + _("This help message") + "\n";
|
strUsage += HelpMessageOpt("-?", _("This help message"));
|
||||||
strUsage += " -create " + _("Create new, empty TX.") + "\n";
|
strUsage += HelpMessageOpt("-create", _("Create new, empty TX."));
|
||||||
strUsage += " -json " + _("Select JSON output") + "\n";
|
strUsage += HelpMessageOpt("-json", _("Select JSON output"));
|
||||||
strUsage += " -txid " + _("Output only the hex-encoded transaction id of the resultant transaction.") + "\n";
|
strUsage += HelpMessageOpt("-txid", _("Output only the hex-encoded transaction id of the resultant transaction."));
|
||||||
strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n";
|
strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly."));
|
||||||
strUsage += " -testnet " + _("Use the test network") + "\n";
|
strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
|
||||||
strUsage += "\n";
|
|
||||||
|
|
||||||
fprintf(stdout, "%s", strUsage.c_str());
|
fprintf(stdout, "%s", strUsage.c_str());
|
||||||
|
|
||||||
|
strUsage = HelpMessageGroup(_("Commands:"));
|
||||||
strUsage = _("Commands:") + "\n";
|
strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX"));
|
||||||
strUsage += " delin=N " + _("Delete input N from TX") + "\n";
|
strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX"));
|
||||||
strUsage += " delout=N " + _("Delete output N from TX") + "\n";
|
strUsage += HelpMessageOpt("in=TXID:VOUT", _("Add input to TX"));
|
||||||
strUsage += " in=TXID:VOUT " + _("Add input to TX") + "\n";
|
strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
|
||||||
strUsage += " locktime=N " + _("Set TX lock time to N") + "\n";
|
strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
|
||||||
strUsage += " nversion=N " + _("Set TX version to N") + "\n";
|
strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX"));
|
||||||
strUsage += " outaddr=VALUE:ADDRESS " + _("Add address-based output to TX") + "\n";
|
strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX"));
|
||||||
strUsage += " outscript=VALUE:SCRIPT " + _("Add raw script output to TX") + "\n";
|
strUsage += HelpMessageOpt("sign=SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " +
|
||||||
strUsage += " sign=SIGHASH-FLAGS " + _("Add zero or more signatures to transaction") + "\n";
|
_("This command requires JSON registers:") +
|
||||||
strUsage += " This command requires JSON registers:\n";
|
_("prevtxs=JSON object") + ", " +
|
||||||
strUsage += " prevtxs=JSON object\n";
|
_("privatekeys=JSON object") + ". " +
|
||||||
strUsage += " privatekeys=JSON object\n";
|
_("See signrawtransaction docs for format of sighash flags, JSON objects."));
|
||||||
strUsage += " See signrawtransaction docs for format of sighash flags, JSON objects.\n";
|
|
||||||
strUsage += "\n";
|
|
||||||
fprintf(stdout, "%s", strUsage.c_str());
|
fprintf(stdout, "%s", strUsage.c_str());
|
||||||
|
|
||||||
strUsage = _("Register Commands:") + "\n";
|
strUsage = HelpMessageGroup(_("Register Commands:"));
|
||||||
strUsage += " load=NAME:FILENAME " + _("Load JSON file FILENAME into register NAME") + "\n";
|
strUsage += HelpMessageOpt("load=NAME:FILENAME", _("Load JSON file FILENAME into register NAME"));
|
||||||
strUsage += " set=NAME:JSON-STRING " + _("Set register NAME to given JSON-STRING") + "\n";
|
strUsage += HelpMessageOpt("set=NAME:JSON-STRING", _("Set register NAME to given JSON-STRING"));
|
||||||
strUsage += "\n";
|
|
||||||
fprintf(stdout, "%s", strUsage.c_str());
|
fprintf(stdout, "%s", strUsage.c_str());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -200,7 +200,6 @@ public:
|
||||||
fAllowMinDifficultyBlocks = false;
|
fAllowMinDifficultyBlocks = false;
|
||||||
fRequireStandard = true;
|
fRequireStandard = true;
|
||||||
fMineBlocksOnDemand = false;
|
fMineBlocksOnDemand = false;
|
||||||
fSkipProofOfWorkCheck = false;
|
|
||||||
fTestnetToBeDeprecatedFieldRPC = false;
|
fTestnetToBeDeprecatedFieldRPC = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,51 +310,8 @@ public:
|
||||||
};
|
};
|
||||||
static CRegTestParams regTestParams;
|
static CRegTestParams regTestParams;
|
||||||
|
|
||||||
/**
|
|
||||||
* Unit test
|
|
||||||
*/
|
|
||||||
class CUnitTestParams : public CMainParams, public CModifiableParams {
|
|
||||||
public:
|
|
||||||
CUnitTestParams() {
|
|
||||||
strNetworkID = "unittest";
|
|
||||||
nDefaultPort = 18445;
|
|
||||||
vFixedSeeds.clear(); //! Unit test mode doesn't have any fixed seeds.
|
|
||||||
vSeeds.clear(); //! Unit test mode doesn't have any DNS seeds.
|
|
||||||
|
|
||||||
fRequireRPCPassword = false;
|
|
||||||
fMiningRequiresPeers = false;
|
|
||||||
fDefaultCheckMemPool = true;
|
|
||||||
fAllowMinDifficultyBlocks = false;
|
|
||||||
fMineBlocksOnDemand = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Checkpoints::CCheckpointData& Checkpoints() const
|
|
||||||
{
|
|
||||||
// UnitTest share the same checkpoints as MAIN
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Published setters to allow changing values in unit test cases
|
|
||||||
virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) { nSubsidyHalvingInterval=anSubsidyHalvingInterval; }
|
|
||||||
virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) { nEnforceBlockUpgradeMajority=anEnforceBlockUpgradeMajority; }
|
|
||||||
virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) { nRejectBlockOutdatedMajority=anRejectBlockOutdatedMajority; }
|
|
||||||
virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) { nToCheckBlockUpgradeMajority=anToCheckBlockUpgradeMajority; }
|
|
||||||
virtual void setDefaultCheckMemPool(bool afDefaultCheckMemPool) { fDefaultCheckMemPool=afDefaultCheckMemPool; }
|
|
||||||
virtual void setAllowMinDifficultyBlocks(bool afAllowMinDifficultyBlocks) { fAllowMinDifficultyBlocks=afAllowMinDifficultyBlocks; }
|
|
||||||
virtual void setSkipProofOfWorkCheck(bool afSkipProofOfWorkCheck) { fSkipProofOfWorkCheck = afSkipProofOfWorkCheck; }
|
|
||||||
};
|
|
||||||
static CUnitTestParams unitTestParams;
|
|
||||||
|
|
||||||
|
|
||||||
static CChainParams *pCurrentParams = 0;
|
static CChainParams *pCurrentParams = 0;
|
||||||
|
|
||||||
CModifiableParams *ModifiableParams()
|
|
||||||
{
|
|
||||||
assert(pCurrentParams);
|
|
||||||
assert(pCurrentParams==&unitTestParams);
|
|
||||||
return (CModifiableParams*)&unitTestParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CChainParams &Params() {
|
const CChainParams &Params() {
|
||||||
assert(pCurrentParams);
|
assert(pCurrentParams);
|
||||||
return *pCurrentParams;
|
return *pCurrentParams;
|
||||||
|
@ -369,8 +325,6 @@ CChainParams &Params(CBaseChainParams::Network network) {
|
||||||
return testNetParams;
|
return testNetParams;
|
||||||
case CBaseChainParams::REGTEST:
|
case CBaseChainParams::REGTEST:
|
||||||
return regTestParams;
|
return regTestParams;
|
||||||
case CBaseChainParams::UNITTEST:
|
|
||||||
return unitTestParams;
|
|
||||||
default:
|
default:
|
||||||
assert(false && "Unimplemented network");
|
assert(false && "Unimplemented network");
|
||||||
return mainParams;
|
return mainParams;
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
|
|
||||||
|
|
||||||
struct CDNSSeedData {
|
struct CDNSSeedData {
|
||||||
std::string name, host;
|
std::string name, host;
|
||||||
CDNSSeedData(const std::string &strName, const std::string &strHost) : name(strName), host(strHost) {}
|
CDNSSeedData(const std::string &strName, const std::string &strHost) : name(strName), host(strHost) {}
|
||||||
|
@ -42,7 +40,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint256& HashGenesisBlock() const { return hashGenesisBlock; }
|
const uint256& HashGenesisBlock() const { return hashGenesisBlock; }
|
||||||
const MessageStartChars& MessageStart() const { return pchMessageStart; }
|
const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; }
|
||||||
const std::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 arith_uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
|
const arith_uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
|
||||||
|
@ -62,8 +60,6 @@ public:
|
||||||
bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; }
|
bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; }
|
||||||
/** Allow mining of a min-difficulty block */
|
/** Allow mining of a min-difficulty block */
|
||||||
bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; }
|
bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; }
|
||||||
/** Skip proof-of-work check: allow mining of any difficulty block */
|
|
||||||
bool SkipProofOfWorkCheck() const { return fSkipProofOfWorkCheck; }
|
|
||||||
/** Make standard checks */
|
/** Make standard checks */
|
||||||
bool RequireStandard() const { return fRequireStandard; }
|
bool RequireStandard() const { return fRequireStandard; }
|
||||||
int64_t TargetTimespan() const { return nTargetTimespan; }
|
int64_t TargetTimespan() const { return nTargetTimespan; }
|
||||||
|
@ -83,7 +79,7 @@ protected:
|
||||||
CChainParams() {}
|
CChainParams() {}
|
||||||
|
|
||||||
uint256 hashGenesisBlock;
|
uint256 hashGenesisBlock;
|
||||||
MessageStartChars pchMessageStart;
|
CMessageHeader::MessageStartChars pchMessageStart;
|
||||||
//! Raw pub key bytes for the broadcast alert signing key.
|
//! Raw pub key bytes for the broadcast alert signing key.
|
||||||
std::vector<unsigned char> vAlertPubKey;
|
std::vector<unsigned char> vAlertPubKey;
|
||||||
int nDefaultPort;
|
int nDefaultPort;
|
||||||
|
@ -106,29 +102,9 @@ protected:
|
||||||
bool fAllowMinDifficultyBlocks;
|
bool fAllowMinDifficultyBlocks;
|
||||||
bool fRequireStandard;
|
bool fRequireStandard;
|
||||||
bool fMineBlocksOnDemand;
|
bool fMineBlocksOnDemand;
|
||||||
bool fSkipProofOfWorkCheck;
|
|
||||||
bool fTestnetToBeDeprecatedFieldRPC;
|
bool fTestnetToBeDeprecatedFieldRPC;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Modifiable parameters interface is used by test cases to adapt the parameters in order
|
|
||||||
* to test specific features more easily. Test cases should always restore the previous
|
|
||||||
* values after finalization.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class CModifiableParams {
|
|
||||||
public:
|
|
||||||
//! Published setters to allow changing values in unit test cases
|
|
||||||
virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) =0;
|
|
||||||
virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority)=0;
|
|
||||||
virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority)=0;
|
|
||||||
virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority)=0;
|
|
||||||
virtual void setDefaultCheckMemPool(bool aDefaultCheckMemPool)=0;
|
|
||||||
virtual void setAllowMinDifficultyBlocks(bool aAllowMinDifficultyBlocks)=0;
|
|
||||||
virtual void setSkipProofOfWorkCheck(bool aSkipProofOfWorkCheck)=0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the currently selected parameters. This won't change after app startup
|
* Return the currently selected parameters. This won't change after app startup
|
||||||
* outside of the unit tests.
|
* outside of the unit tests.
|
||||||
|
@ -138,9 +114,6 @@ const CChainParams &Params();
|
||||||
/** Return parameters for the given network. */
|
/** Return parameters for the given network. */
|
||||||
CChainParams &Params(CBaseChainParams::Network network);
|
CChainParams &Params(CBaseChainParams::Network network);
|
||||||
|
|
||||||
/** Get modifiable network parameters (UNITTEST only) */
|
|
||||||
CModifiableParams *ModifiableParams();
|
|
||||||
|
|
||||||
/** 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(CBaseChainParams::Network network);
|
void SelectParams(CBaseChainParams::Network network);
|
||||||
|
|
||||||
|
|
|
@ -82,9 +82,6 @@ void SelectBaseParams(CBaseChainParams::Network network)
|
||||||
case CBaseChainParams::REGTEST:
|
case CBaseChainParams::REGTEST:
|
||||||
pCurrentBaseParams = ®TestParams;
|
pCurrentBaseParams = ®TestParams;
|
||||||
break;
|
break;
|
||||||
case CBaseChainParams::UNITTEST:
|
|
||||||
pCurrentBaseParams = &unitTestParams;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
assert(false && "Unimplemented network");
|
assert(false && "Unimplemented network");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -19,7 +19,6 @@ public:
|
||||||
MAIN,
|
MAIN,
|
||||||
TESTNET,
|
TESTNET,
|
||||||
REGTEST,
|
REGTEST,
|
||||||
UNITTEST,
|
|
||||||
|
|
||||||
MAX_NETWORK_TYPES
|
MAX_NETWORK_TYPES
|
||||||
};
|
};
|
||||||
|
|
47
src/compat/byteswap.h
Normal file
47
src/compat/byteswap.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright (c) 2014 The Bitcoin developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_COMPAT_BYTESWAP_H
|
||||||
|
#define BITCOIN_COMPAT_BYTESWAP_H
|
||||||
|
|
||||||
|
#if defined(HAVE_CONFIG_H)
|
||||||
|
#include "config/bitcoin-config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_BYTESWAP_H)
|
||||||
|
#include <byteswap.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_DECL_BSWAP_16 == 0
|
||||||
|
inline uint16_t bswap_16(uint16_t x)
|
||||||
|
{
|
||||||
|
return (x >> 8) | ((x & 0x00ff) << 8);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BSWAP16
|
||||||
|
|
||||||
|
#if HAVE_DECL_BSWAP_32 == 0
|
||||||
|
inline uint32_t bswap_32(uint32_t x)
|
||||||
|
{
|
||||||
|
return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >> 8) |
|
||||||
|
((x & 0x0000ff00U) << 8) | ((x & 0x000000ffU) << 24));
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BSWAP32
|
||||||
|
|
||||||
|
#if HAVE_DECL_BSWAP_64 == 0
|
||||||
|
inline uint64_t bswap_64(uint64_t x)
|
||||||
|
{
|
||||||
|
return (((x & 0xff00000000000000ull) >> 56)
|
||||||
|
| ((x & 0x00ff000000000000ull) >> 40)
|
||||||
|
| ((x & 0x0000ff0000000000ull) >> 24)
|
||||||
|
| ((x & 0x000000ff00000000ull) >> 8)
|
||||||
|
| ((x & 0x00000000ff000000ull) << 8)
|
||||||
|
| ((x & 0x0000000000ff0000ull) << 24)
|
||||||
|
| ((x & 0x000000000000ff00ull) << 40)
|
||||||
|
| ((x & 0x00000000000000ffull) << 56));
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BSWAP64
|
||||||
|
|
||||||
|
#endif // BITCOIN_COMPAT_BYTESWAP_H
|
194
src/compat/endian.h
Normal file
194
src/compat/endian.h
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
// Copyright (c) 2014 The Bitcoin developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_COMPAT_ENDIAN_H
|
||||||
|
#define BITCOIN_COMPAT_ENDIAN_H
|
||||||
|
|
||||||
|
#if defined(HAVE_CONFIG_H)
|
||||||
|
#include "config/bitcoin-config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "compat/byteswap.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_ENDIAN_H)
|
||||||
|
#include <endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WORDS_BIGENDIAN)
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOBE16 == 0
|
||||||
|
inline uint16_t htobe16(uint16_t host_16bits)
|
||||||
|
{
|
||||||
|
return host_16bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOBE16
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOLE16 == 0
|
||||||
|
inline uint16_t htole16(uint16_t host_16bits)
|
||||||
|
{
|
||||||
|
return bswap_16(host_16bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOLE16
|
||||||
|
|
||||||
|
#if HAVE_DECL_BE16TOH == 0
|
||||||
|
inline uint16_t be16toh(uint16_t big_endian_16bits)
|
||||||
|
{
|
||||||
|
return big_endian_16bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BE16TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_LE16TOH == 0
|
||||||
|
inline uint16_t le16toh(uint16_t little_endian_16bits)
|
||||||
|
{
|
||||||
|
return bswap_16(little_endian_16bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_LE16TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOBE32 == 0
|
||||||
|
inline uint32_t htobe32(uint32_t host_32bits)
|
||||||
|
{
|
||||||
|
return host_32bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOBE32
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOLE32 == 0
|
||||||
|
inline uint32_t htole32(uint32_t host_32bits)
|
||||||
|
{
|
||||||
|
return bswap_32(host_32bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOLE32
|
||||||
|
|
||||||
|
#if HAVE_DECL_BE32TOH == 0
|
||||||
|
inline uint32_t be32toh(uint32_t big_endian_32bits)
|
||||||
|
{
|
||||||
|
return big_endian_32bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BE32TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_LE32TOH == 0
|
||||||
|
inline uint32_t le32toh(uint32_t little_endian_32bits)
|
||||||
|
{
|
||||||
|
return bswap_32(little_endian_32bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_LE32TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOBE64 == 0
|
||||||
|
inline uint64_t htobe64(uint64_t host_64bits)
|
||||||
|
{
|
||||||
|
return host_64bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOBE64
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOLE64 == 0
|
||||||
|
inline uint64_t htole64(uint64_t host_64bits)
|
||||||
|
{
|
||||||
|
return bswap_64(host_64bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOLE64
|
||||||
|
|
||||||
|
#if HAVE_DECL_BE64TOH == 0
|
||||||
|
inline uint64_t be64toh(uint64_t big_endian_64bits)
|
||||||
|
{
|
||||||
|
return big_endian_64bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BE64TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_LE64TOH == 0
|
||||||
|
inline uint64_t le64toh(uint64_t little_endian_64bits)
|
||||||
|
{
|
||||||
|
return bswap_64(little_endian_64bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_LE64TOH
|
||||||
|
|
||||||
|
#else // WORDS_BIGENDIAN
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOBE16 == 0
|
||||||
|
inline uint16_t htobe16(uint16_t host_16bits)
|
||||||
|
{
|
||||||
|
return bswap_16(host_16bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOBE16
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOLE16 == 0
|
||||||
|
inline uint16_t htole16(uint16_t host_16bits)
|
||||||
|
{
|
||||||
|
return host_16bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOLE16
|
||||||
|
|
||||||
|
#if HAVE_DECL_BE16TOH == 0
|
||||||
|
inline uint16_t be16toh(uint16_t big_endian_16bits)
|
||||||
|
{
|
||||||
|
return bswap_16(big_endian_16bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BE16TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_LE16TOH == 0
|
||||||
|
inline uint16_t le16toh(uint16_t little_endian_16bits)
|
||||||
|
{
|
||||||
|
return little_endian_16bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_LE16TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOBE32 == 0
|
||||||
|
inline uint32_t htobe32(uint32_t host_32bits)
|
||||||
|
{
|
||||||
|
return bswap_32(host_32bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOBE32
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOLE32 == 0
|
||||||
|
inline uint32_t htole32(uint32_t host_32bits)
|
||||||
|
{
|
||||||
|
return host_32bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOLE32
|
||||||
|
|
||||||
|
#if HAVE_DECL_BE32TOH == 0
|
||||||
|
inline uint32_t be32toh(uint32_t big_endian_32bits)
|
||||||
|
{
|
||||||
|
return bswap_32(big_endian_32bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BE32TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_LE32TOH == 0
|
||||||
|
inline uint32_t le32toh(uint32_t little_endian_32bits)
|
||||||
|
{
|
||||||
|
return little_endian_32bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_LE32TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOBE64 == 0
|
||||||
|
inline uint64_t htobe64(uint64_t host_64bits)
|
||||||
|
{
|
||||||
|
return bswap_64(host_64bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOBE64
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOLE64 == 0
|
||||||
|
inline uint64_t htole64(uint64_t host_64bits)
|
||||||
|
{
|
||||||
|
return host_64bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOLE64
|
||||||
|
|
||||||
|
#if HAVE_DECL_BE64TOH == 0
|
||||||
|
inline uint64_t be64toh(uint64_t big_endian_64bits)
|
||||||
|
{
|
||||||
|
return bswap_64(big_endian_64bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BE64TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_LE64TOH == 0
|
||||||
|
inline uint64_t le64toh(uint64_t little_endian_64bits)
|
||||||
|
{
|
||||||
|
return little_endian_64bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_LE64TOH
|
||||||
|
|
||||||
|
#endif // WORDS_BIGENDIAN
|
||||||
|
|
||||||
|
#endif // BITCOIN_COMPAT_ENDIAN_H
|
|
@ -1,94 +0,0 @@
|
||||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
|
||||||
// Distributed under the MIT software license, see the accompanying
|
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <istream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <typeinfo>
|
|
||||||
|
|
||||||
#ifndef _GLIBCXX_USE_NOEXCEPT
|
|
||||||
#define _GLIBCXX_USE_NOEXCEPT throw()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace std
|
|
||||||
{
|
|
||||||
const char* bad_exception::what() const throw()
|
|
||||||
{
|
|
||||||
return "std::bad_exception";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* bad_cast::what() const throw()
|
|
||||||
{
|
|
||||||
return "std::bad_cast";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* bad_alloc::what() const throw()
|
|
||||||
{
|
|
||||||
return "std::bad_alloc";
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace __detail
|
|
||||||
{
|
|
||||||
struct _List_node_base {
|
|
||||||
void _M_hook(std::__detail::_List_node_base* const __position) throw() __attribute__((used))
|
|
||||||
{
|
|
||||||
_M_next = __position;
|
|
||||||
_M_prev = __position->_M_prev;
|
|
||||||
__position->_M_prev->_M_next = this;
|
|
||||||
__position->_M_prev = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _M_unhook() __attribute__((used))
|
|
||||||
{
|
|
||||||
_List_node_base* const __next_node = _M_next;
|
|
||||||
_List_node_base* const __prev_node = _M_prev;
|
|
||||||
__prev_node->_M_next = __next_node;
|
|
||||||
__next_node->_M_prev = __prev_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
_List_node_base* _M_next;
|
|
||||||
_List_node_base* _M_prev;
|
|
||||||
};
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template ostream& ostream::_M_insert(bool);
|
|
||||||
template ostream& ostream::_M_insert(long);
|
|
||||||
template ostream& ostream::_M_insert(double);
|
|
||||||
template ostream& ostream::_M_insert(unsigned long);
|
|
||||||
template ostream& ostream::_M_insert(const void*);
|
|
||||||
template ostream& __ostream_insert(ostream&, const char*, streamsize);
|
|
||||||
template istream& istream::_M_extract(long&);
|
|
||||||
template istream& istream::_M_extract(unsigned short&);
|
|
||||||
|
|
||||||
out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT {}
|
|
||||||
|
|
||||||
length_error::~length_error() _GLIBCXX_USE_NOEXCEPT {}
|
|
||||||
|
|
||||||
// Used with permission.
|
|
||||||
// See: https://github.com/madlib/madlib/commit/c3db418c0d34d6813608f2137fef1012ce03043d
|
|
||||||
|
|
||||||
void ctype<char>::_M_widen_init() const
|
|
||||||
{
|
|
||||||
char __tmp[sizeof(_M_widen)];
|
|
||||||
for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i)
|
|
||||||
__tmp[__i] = __i;
|
|
||||||
do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen);
|
|
||||||
|
|
||||||
_M_widen_ok = 1;
|
|
||||||
// Set _M_widen_ok to 2 if memcpy can't be used.
|
|
||||||
for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i)
|
|
||||||
if (__tmp[__i] != _M_widen[__i]) {
|
|
||||||
_M_widen_ok = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void __throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__));
|
|
||||||
void __throw_out_of_range_fmt(const char* err, ...)
|
|
||||||
{
|
|
||||||
// Safe and over-simplified version. Ignore the format and print it as-is.
|
|
||||||
__throw_out_of_range(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace std
|
|
|
@ -11,110 +11,56 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#if defined(HAVE_ENDIAN_H)
|
#include "compat/endian.h"
|
||||||
#include <endian.h>
|
|
||||||
#endif
|
uint16_t static inline ReadLE16(const unsigned char* ptr)
|
||||||
|
{
|
||||||
|
return le16toh(*((uint16_t*)ptr));
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t static inline ReadLE32(const unsigned char* ptr)
|
uint32_t static inline ReadLE32(const unsigned char* ptr)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_LE32TOH == 1
|
|
||||||
return le32toh(*((uint32_t*)ptr));
|
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)
|
uint64_t static inline ReadLE64(const unsigned char* ptr)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_LE64TOH == 1
|
|
||||||
return le64toh(*((uint64_t*)ptr));
|
return le64toh(*((uint64_t*)ptr));
|
||||||
#elif !defined(WORDS_BIGENDIAN)
|
}
|
||||||
return *((uint64_t*)ptr);
|
|
||||||
#else
|
void static inline WriteLE16(unsigned char* ptr, uint16_t x)
|
||||||
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]);
|
*((uint16_t*)ptr) = htole16(x);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
|
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_HTOLE32 == 1
|
|
||||||
*((uint32_t*)ptr) = htole32(x);
|
*((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)
|
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_HTOLE64 == 1
|
|
||||||
*((uint64_t*)ptr) = htole64(x);
|
*((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)
|
uint32_t static inline ReadBE32(const unsigned char* ptr)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_BE32TOH == 1
|
|
||||||
return be32toh(*((uint32_t*)ptr));
|
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)
|
uint64_t static inline ReadBE64(const unsigned char* ptr)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_BE64TOH == 1
|
|
||||||
return be64toh(*((uint64_t*)ptr));
|
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)
|
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_HTOBE32 == 1
|
|
||||||
*((uint32_t*)ptr) = htobe32(x);
|
*((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)
|
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_HTOBE64 == 1
|
|
||||||
*((uint64_t*)ptr) = htobe64(x);
|
*((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 // BITCOIN_CRYPTO_COMMON_H
|
#endif // BITCOIN_CRYPTO_COMMON_H
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
#include "crypto/common.h"
|
||||||
#include "crypto/hmac_sha512.h"
|
#include "crypto/hmac_sha512.h"
|
||||||
|
|
||||||
|
|
||||||
inline uint32_t ROTL32(uint32_t x, int8_t r)
|
inline uint32_t ROTL32(uint32_t x, int8_t r)
|
||||||
{
|
{
|
||||||
return (x << r) | (x >> (32 - r));
|
return (x << r) | (x >> (32 - r));
|
||||||
|
@ -23,10 +25,10 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
|
||||||
|
|
||||||
//----------
|
//----------
|
||||||
// body
|
// body
|
||||||
const uint32_t* blocks = (const uint32_t*)(&vDataToHash[0] + nblocks * 4);
|
const uint8_t* blocks = &vDataToHash[0] + nblocks * 4;
|
||||||
|
|
||||||
for (int i = -nblocks; i; i++) {
|
for (int i = -nblocks; i; i++) {
|
||||||
uint32_t k1 = blocks[i];
|
uint32_t k1 = ReadLE32(blocks + i*4);
|
||||||
|
|
||||||
k1 *= c1;
|
k1 *= c1;
|
||||||
k1 = ROTL32(k1, 15);
|
k1 = ROTL32(k1, 15);
|
||||||
|
|
301
src/init.cpp
301
src/init.cpp
|
@ -23,10 +23,10 @@
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "utilmoneystr.h"
|
#include "utilmoneystr.h"
|
||||||
|
#include "validationinterface.h"
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
#include "db.h"
|
#include "wallet/wallet.h"
|
||||||
#include "wallet.h"
|
#include "wallet/walletdb.h"
|
||||||
#include "walletdb.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -151,7 +151,7 @@ void Shutdown()
|
||||||
StopRPCThreads();
|
StopRPCThreads();
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
if (pwalletMain)
|
if (pwalletMain)
|
||||||
bitdb.Flush(false);
|
pwalletMain->Flush(false);
|
||||||
GenerateBitcoins(false, NULL, 0);
|
GenerateBitcoins(false, NULL, 0);
|
||||||
#endif
|
#endif
|
||||||
StopNode();
|
StopNode();
|
||||||
|
@ -186,7 +186,7 @@ void Shutdown()
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
if (pwalletMain)
|
if (pwalletMain)
|
||||||
bitdb.Flush(true);
|
pwalletMain->Flush(true);
|
||||||
#endif
|
#endif
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
boost::filesystem::remove(GetPidFile());
|
boost::filesystem::remove(GetPidFile());
|
||||||
|
@ -258,157 +258,174 @@ void OnRPCPreCommand(const CRPCCommand& cmd)
|
||||||
|
|
||||||
std::string HelpMessage(HelpMessageMode mode)
|
std::string HelpMessage(HelpMessageMode mode)
|
||||||
{
|
{
|
||||||
|
|
||||||
// When adding new options to the categories, please keep and ensure alphabetical ordering.
|
// When adding new options to the categories, please keep and ensure alphabetical ordering.
|
||||||
string strUsage = _("Options:") + "\n";
|
string strUsage = HelpMessageGroup(_("Options:"));
|
||||||
strUsage += " -? " + _("This help message") + "\n";
|
strUsage += HelpMessageOpt("-?", _("This help message"));
|
||||||
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 += HelpMessageOpt("-alertnotify=<cmd>", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)"));
|
||||||
strUsage += " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n";
|
strUsage += HelpMessageOpt("-blocknotify=<cmd>", _("Execute command when the best block changes (%s in cmd is replaced by block hash)"));
|
||||||
strUsage += " -checkblocks=<n> " + strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288) + "\n";
|
strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288));
|
||||||
strUsage += " -checklevel=<n> " + strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3) + "\n";
|
strUsage += HelpMessageOpt("-checklevel=<n>", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3));
|
||||||
strUsage += " -conf=<file> " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n";
|
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
|
||||||
if (mode == 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 += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
|
strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
|
||||||
strUsage += " -dbcache=<n> " + strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache) + "\n";
|
strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache));
|
||||||
strUsage += " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + " " + _("on startup") + "\n";
|
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup"));
|
||||||
strUsage += " -maxorphantx=<n> " + strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "\n";
|
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
|
||||||
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 += HelpMessageOpt("-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));
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
strUsage += " -pid=<file> " + strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid") + "\n";
|
strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid"));
|
||||||
#endif
|
#endif
|
||||||
strUsage += " -reindex " + _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup") + "\n";
|
strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup"));
|
||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
strUsage += " -sysperms " + _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)") + "\n";
|
strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)"));
|
||||||
#endif
|
#endif
|
||||||
strUsage += " -txindex " + strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0) + "\n";
|
strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0));
|
||||||
|
|
||||||
strUsage += "\n" + _("Connection options:") + "\n";
|
strUsage += HelpMessageGroup(_("Connection options:"));
|
||||||
strUsage += " -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n";
|
strUsage += HelpMessageOpt("-addnode=<ip>", _("Add a node to connect to and attempt to keep the connection open"));
|
||||||
strUsage += " -banscore=<n> " + strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100) + "\n";
|
strUsage += HelpMessageOpt("-banscore=<n>", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100));
|
||||||
strUsage += " -bantime=<n> " + strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400) + "\n";
|
strUsage += HelpMessageOpt("-bantime=<n>", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400));
|
||||||
strUsage += " -bind=<addr> " + _("Bind to given address and always listen on it. Use [host]:port notation for IPv6") + "\n";
|
strUsage += HelpMessageOpt("-bind=<addr>", _("Bind to given address and always listen on it. Use [host]:port notation for IPv6"));
|
||||||
strUsage += " -connect=<ip> " + _("Connect only to the specified node(s)") + "\n";
|
strUsage += HelpMessageOpt("-connect=<ip>", _("Connect only to the specified node(s)"));
|
||||||
strUsage += " -discover " + _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)") + "\n";
|
strUsage += HelpMessageOpt("-discover", _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)"));
|
||||||
strUsage += " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)") + "\n";
|
strUsage += HelpMessageOpt("-dns", _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)"));
|
||||||
strUsage += " -dnsseed " + _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)") + "\n";
|
strUsage += HelpMessageOpt("-dnsseed", _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)"));
|
||||||
strUsage += " -externalip=<ip> " + _("Specify your own public address") + "\n";
|
strUsage += HelpMessageOpt("-externalip=<ip>", _("Specify your own public address"));
|
||||||
strUsage += " -forcednsseed " + strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0) + "\n";
|
strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0));
|
||||||
strUsage += " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n";
|
strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)"));
|
||||||
strUsage += " -maxconnections=<n> " + strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125) + "\n";
|
strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125));
|
||||||
strUsage += " -maxreceivebuffer=<n> " + strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000) + "\n";
|
strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000));
|
||||||
strUsage += " -maxsendbuffer=<n> " + strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000) + "\n";
|
strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000));
|
||||||
strUsage += " -onion=<ip:port> " + strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy") + "\n";
|
strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy"));
|
||||||
strUsage += " -onlynet=<net> " + _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)") + "\n";
|
strUsage += HelpMessageOpt("-onlynet=<net>", _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)"));
|
||||||
strUsage += " -permitbaremultisig " + strprintf(_("Relay non-P2SH multisig (default: %u)"), 1) + "\n";
|
strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), 1));
|
||||||
strUsage += " -port=<port> " + strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 8333, 18333) + "\n";
|
strUsage += HelpMessageOpt("-port=<port>", strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 8333, 18333));
|
||||||
strUsage += " -proxy=<ip:port> " + _("Connect through SOCKS5 proxy") + "\n";
|
strUsage += HelpMessageOpt("-proxy=<ip:port>", _("Connect through SOCKS5 proxy"));
|
||||||
strUsage += " -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n";
|
strUsage += HelpMessageOpt("-seednode=<ip>", _("Connect to a node to retrieve peer addresses, and disconnect"));
|
||||||
strUsage += " -timeout=<n> " + strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT) + "\n";
|
strUsage += HelpMessageOpt("-timeout=<n>", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT));
|
||||||
#ifdef USE_UPNP
|
#ifdef USE_UPNP
|
||||||
#if USE_UPNP
|
#if USE_UPNP
|
||||||
strUsage += " -upnp " + _("Use UPnP to map the listening port (default: 1 when listening)") + "\n";
|
strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening)"));
|
||||||
#else
|
#else
|
||||||
strUsage += " -upnp " + strprintf(_("Use UPnP to map the listening port (default: %u)"), 0) + "\n";
|
strUsage += HelpMessageOpt("-upnp", strprintf(_("Use UPnP to map the listening port (default: %u)"), 0));
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
strUsage += " -whitebind=<addr> " + _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6") + "\n";
|
strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6"));
|
||||||
strUsage += " -whitelist=<netmask> " + _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + "\n";
|
strUsage += HelpMessageOpt("-whitelist=<netmask>", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") +
|
||||||
strUsage += " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway") + "\n";
|
" " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway"));
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
strUsage += "\n" + _("Wallet options:") + "\n";
|
strUsage += HelpMessageGroup(_("Wallet options:"));
|
||||||
strUsage += " -disablewallet " + _("Do not load the wallet and disable wallet RPC calls") + "\n";
|
strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
|
||||||
strUsage += " -keypool=<n> " + strprintf(_("Set key pool size to <n> (default: %u)"), 100) + "\n";
|
strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100));
|
||||||
if (GetBoolArg("-help-debug", false))
|
if (GetBoolArg("-help-debug", false))
|
||||||
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 += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"),
|
||||||
strUsage += " -paytxfee=<amt> " + strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())) + "\n";
|
FormatMoney(CWallet::minTxFee.GetFeePerK())));
|
||||||
strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + " " + _("on startup") + "\n";
|
strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())));
|
||||||
strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n";
|
strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup"));
|
||||||
strUsage += " -sendfreetransactions " + strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0) + "\n";
|
strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup"));
|
||||||
strUsage += " -spendzeroconfchange " + strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1) + "\n";
|
strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0));
|
||||||
strUsage += " -txconfirmtarget=<n> " + strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1) + "\n";
|
strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1));
|
||||||
strUsage += " -maxtxfee=<amt> " + strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), FormatMoney(maxTxFee)) + "\n";
|
strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1));
|
||||||
strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n";
|
strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"),
|
||||||
strUsage += " -wallet=<file> " + _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat") + "\n";
|
FormatMoney(maxTxFee)));
|
||||||
strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n";
|
strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup"));
|
||||||
strUsage += " -zapwallettxes=<mode> " + _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + "\n";
|
strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat"));
|
||||||
strUsage += " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)") + "\n";
|
strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
|
||||||
|
strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
|
||||||
|
" " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
strUsage += "\n" + _("Debugging/Testing options:") + "\n";
|
strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
|
||||||
if (GetBoolArg("-help-debug", false))
|
if (GetBoolArg("-help-debug", false))
|
||||||
{
|
{
|
||||||
strUsage += " -checkpoints " + strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1) + "\n";
|
strUsage += HelpMessageOpt("-checkpoints", strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1));
|
||||||
strUsage += " -dblogsize=<n> " + strprintf(_("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)"), 100) + "\n";
|
strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf(_("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)"), 100));
|
||||||
strUsage += " -disablesafemode " + strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0) + "\n";
|
strUsage += HelpMessageOpt("-disablesafemode", strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0));
|
||||||
strUsage += " -testsafemode " + strprintf(_("Force safe mode (default: %u)"), 0) + "\n";
|
strUsage += HelpMessageOpt("-testsafemode", strprintf(_("Force safe mode (default: %u)"), 0));
|
||||||
strUsage += " -dropmessagestest=<n> " + _("Randomly drop 1 of every <n> network messages") + "\n";
|
strUsage += HelpMessageOpt("-dropmessagestest=<n>", _("Randomly drop 1 of every <n> network messages"));
|
||||||
strUsage += " -fuzzmessagestest=<n> " + _("Randomly fuzz 1 of every <n> network messages") + "\n";
|
strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", _("Randomly fuzz 1 of every <n> network messages"));
|
||||||
strUsage += " -flushwallet " + strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1) + "\n";
|
strUsage += HelpMessageOpt("-flushwallet", strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1));
|
||||||
strUsage += " -stopafterblockimport " + strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0) + "\n";
|
strUsage += HelpMessageOpt("-stopafterblockimport", strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0));
|
||||||
}
|
}
|
||||||
strUsage += " -debug=<category> " + strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + "\n";
|
string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below
|
||||||
strUsage += " " + _("If <category> is not supplied, output all debugging information.") + "\n";
|
|
||||||
strUsage += " " + _("<category> can be:");
|
|
||||||
strUsage += " addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below
|
|
||||||
if (mode == HMM_BITCOIN_QT)
|
if (mode == HMM_BITCOIN_QT)
|
||||||
strUsage += ", qt";
|
debugCategories += ", qt";
|
||||||
strUsage += ".\n";
|
strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
|
||||||
|
_("If <category> is not supplied, output all debugging information.") + _("<category> can be:") + " " + debugCategories + ".");
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
strUsage += " -gen " + strprintf(_("Generate coins (default: %u)"), 0) + "\n";
|
strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0));
|
||||||
strUsage += " -genproclimit=<n> " + strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1) + "\n";
|
strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1));
|
||||||
#endif
|
#endif
|
||||||
strUsage += " -help-debug " + _("Show all debugging options (usage: --help -help-debug)") + "\n";
|
strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)"));
|
||||||
strUsage += " -logips " + strprintf(_("Include IP addresses in debug output (default: %u)"), 0) + "\n";
|
strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0));
|
||||||
strUsage += " -logtimestamps " + strprintf(_("Prepend debug output with timestamp (default: %u)"), 1) + "\n";
|
strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1));
|
||||||
if (GetBoolArg("-help-debug", false))
|
if (GetBoolArg("-help-debug", false))
|
||||||
{
|
{
|
||||||
strUsage += " -limitfreerelay=<n> " + strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15) + "\n";
|
strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15));
|
||||||
strUsage += " -relaypriority " + strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1) + "\n";
|
strUsage += HelpMessageOpt("-relaypriority", strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1));
|
||||||
strUsage += " -maxsigcachesize=<n> " + strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000) + "\n";
|
strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000));
|
||||||
}
|
}
|
||||||
strUsage += " -minrelaytxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())) + "\n";
|
strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK())));
|
||||||
strUsage += " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n";
|
strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file"));
|
||||||
if (GetBoolArg("-help-debug", false))
|
if (GetBoolArg("-help-debug", false))
|
||||||
{
|
{
|
||||||
strUsage += " -printpriority " + strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0) + "\n";
|
strUsage += HelpMessageOpt("-printpriority", strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0));
|
||||||
strUsage += " -privdb " + strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1) + "\n";
|
strUsage += HelpMessageOpt("-privdb", strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1));
|
||||||
strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n";
|
strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + " " +
|
||||||
strUsage += " " + _("This is intended for regression testing tools and app development.") + "\n";
|
_("This is intended for regression testing tools and app development.") + " " +
|
||||||
strUsage += " " + _("In this mode -genproclimit controls how many blocks are generated immediately.") + "\n";
|
_("In this mode -genproclimit controls how many blocks are generated immediately."));
|
||||||
}
|
}
|
||||||
strUsage += " -shrinkdebugfile " + _("Shrink debug.log file on client startup (default: 1 when no -debug)") + "\n";
|
strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)"));
|
||||||
strUsage += " -testnet " + _("Use the test network") + "\n";
|
strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
|
||||||
|
|
||||||
strUsage += "\n" + _("Node relay options:") + "\n";
|
strUsage += HelpMessageGroup(_("Node relay options:"));
|
||||||
strUsage += " -datacarrier " + strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1) + "\n";
|
strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1));
|
||||||
strUsage += " -datacarriersize " + strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY) + "\n";
|
strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY));
|
||||||
|
|
||||||
strUsage += "\n" + _("Block creation options:") + "\n";
|
strUsage += HelpMessageGroup(_("Block creation options:"));
|
||||||
strUsage += " -blockminsize=<n> " + strprintf(_("Set minimum block size in bytes (default: %u)"), 0) + "\n";
|
strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), 0));
|
||||||
strUsage += " -blockmaxsize=<n> " + strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE) + "\n";
|
strUsage += HelpMessageOpt("-blockmaxsize=<n>", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE));
|
||||||
strUsage += " -blockprioritysize=<n> " + strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE) + "\n";
|
strUsage += HelpMessageOpt("-blockprioritysize=<n>", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE));
|
||||||
|
|
||||||
strUsage += "\n" + _("RPC server options:") + "\n";
|
strUsage += HelpMessageGroup(_("RPC server options:"));
|
||||||
strUsage += " -server " + _("Accept command line and JSON-RPC commands") + "\n";
|
strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands"));
|
||||||
strUsage += " -rest " + strprintf(_("Accept public REST requests (default: %u)"), 0) + "\n";
|
strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), 0));
|
||||||
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 += HelpMessageOpt("-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)"));
|
||||||
strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
|
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
|
||||||
strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
|
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
|
||||||
strUsage += " -rpcport=<port> " + strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n";
|
strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332));
|
||||||
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 += HelpMessageOpt("-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"));
|
||||||
strUsage += " -rpcthreads=<n> " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n";
|
strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4));
|
||||||
strUsage += " -rpckeepalive " + strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1) + "\n";
|
strUsage += HelpMessageOpt("-rpckeepalive", strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1));
|
||||||
|
|
||||||
strUsage += "\n" + _("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
|
strUsage += HelpMessageGroup(_("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
|
||||||
strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
|
strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
|
||||||
strUsage += " -rpcsslcertificatechainfile=<file.cert> " + strprintf(_("Server certificate file (default: %s)"), "server.cert") + "\n";
|
strUsage += HelpMessageOpt("-rpcsslcertificatechainfile=<file.cert>", strprintf(_("Server certificate file (default: %s)"), "server.cert"));
|
||||||
strUsage += " -rpcsslprivatekeyfile=<file.pem> " + strprintf(_("Server private key (default: %s)"), "server.pem") + "\n";
|
strUsage += HelpMessageOpt("-rpcsslprivatekeyfile=<file.pem>", strprintf(_("Server private key (default: %s)"), "server.pem"));
|
||||||
strUsage += " -rpcsslciphers=<ciphers> " + strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH") + "\n";
|
strUsage += HelpMessageOpt("-rpcsslciphers=<ciphers>", strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"));
|
||||||
|
|
||||||
|
if (mode == HMM_BITCOIN_QT)
|
||||||
|
{
|
||||||
|
strUsage += HelpMessageGroup(_("UI Options:"));
|
||||||
|
if (GetBoolArg("-help-debug", false)) {
|
||||||
|
strUsage += HelpMessageOpt("-allowselfsignedrootcertificates", _("Allow self signed root certificates (default: 0)"));
|
||||||
|
}
|
||||||
|
strUsage += HelpMessageOpt("-choosedatadir", _("Choose data directory on startup (default: 0)"));
|
||||||
|
strUsage += HelpMessageOpt("-lang=<lang>", _("Set language, for example \"de_DE\" (default: system locale)"));
|
||||||
|
strUsage += HelpMessageOpt("-min", _("Start minimized"));
|
||||||
|
strUsage += HelpMessageOpt("-rootcertificates=<file>", _("Set SSL root certificates for payment request (default: -system-)"));
|
||||||
|
strUsage += HelpMessageOpt("-splash", _("Show splash screen on startup (default: 1)"));
|
||||||
|
}
|
||||||
|
|
||||||
return strUsage;
|
return strUsage;
|
||||||
}
|
}
|
||||||
|
@ -837,47 +854,17 @@ bool AppInit2(boost::thread_group& threadGroup)
|
||||||
LogPrintf("Using wallet %s\n", strWalletFile);
|
LogPrintf("Using wallet %s\n", strWalletFile);
|
||||||
uiInterface.InitMessage(_("Verifying wallet..."));
|
uiInterface.InitMessage(_("Verifying wallet..."));
|
||||||
|
|
||||||
if (!bitdb.Open(GetDataDir()))
|
std::string warningString;
|
||||||
{
|
std::string errorString;
|
||||||
// try moving the database env out of the way
|
|
||||||
boost::filesystem::path pathDatabase = GetDataDir() / "database";
|
|
||||||
boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime());
|
|
||||||
try {
|
|
||||||
boost::filesystem::rename(pathDatabase, pathDatabaseBak);
|
|
||||||
LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string());
|
|
||||||
} catch (const boost::filesystem::filesystem_error&) {
|
|
||||||
// failure is ok (well, not really, but it's not worse than what we started with)
|
|
||||||
}
|
|
||||||
|
|
||||||
// try again
|
if (!CWallet::Verify(strWalletFile, warningString, errorString))
|
||||||
if (!bitdb.Open(GetDataDir())) {
|
return false;
|
||||||
// if it still fails, it probably means we can't even create the database env
|
|
||||||
string msg = strprintf(_("Error initializing wallet database environment %s!"), strDataDir);
|
|
||||||
return InitError(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetBoolArg("-salvagewallet", false))
|
if (!warningString.empty())
|
||||||
{
|
InitWarning(warningString);
|
||||||
// Recover readable keypairs:
|
if (!errorString.empty())
|
||||||
if (!CWalletDB::Recover(bitdb, strWalletFile, true))
|
return InitError(warningString);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (boost::filesystem::exists(GetDataDir() / strWalletFile))
|
|
||||||
{
|
|
||||||
CDBEnv::VerifyResult r = bitdb.Verify(strWalletFile, CWalletDB::Recover);
|
|
||||||
if (r == CDBEnv::RECOVER_OK)
|
|
||||||
{
|
|
||||||
string msg = strprintf(_("Warning: wallet.dat corrupt, data salvaged!"
|
|
||||||
" Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
|
|
||||||
" your balance or transactions are incorrect you should"
|
|
||||||
" restore from a backup."), strDataDir);
|
|
||||||
InitWarning(msg);
|
|
||||||
}
|
|
||||||
if (r == CDBEnv::RECOVER_FAIL)
|
|
||||||
return InitError(_("wallet.dat corrupt, salvage failed"));
|
|
||||||
}
|
|
||||||
} // (!fDisableWallet)
|
} // (!fDisableWallet)
|
||||||
#endif // ENABLE_WALLET
|
#endif // ENABLE_WALLET
|
||||||
// ********************************************************* Step 6: network initialization
|
// ********************************************************* Step 6: network initialization
|
||||||
|
|
|
@ -208,11 +208,9 @@ void CExtKey::Decode(const unsigned char code[74]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ECC_InitSanityCheck() {
|
bool ECC_InitSanityCheck() {
|
||||||
#if !defined(USE_SECP256K1)
|
|
||||||
if (!CECKey::SanityCheck()) {
|
if (!CECKey::SanityCheck()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
CKey key;
|
CKey key;
|
||||||
key.MakeNewKey(true);
|
key.MakeNewKey(true);
|
||||||
CPubKey pubkey = key.GetPubKey();
|
CPubKey pubkey = key.GetPubKey();
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
#ifndef BITCOIN_KEY_H
|
#ifndef BITCOIN_KEY_H
|
||||||
#define BITCOIN_KEY_H
|
#define BITCOIN_KEY_H
|
||||||
|
|
||||||
#include "allocators.h"
|
|
||||||
#include "serialize.h"
|
#include "serialize.h"
|
||||||
|
#include "support/allocators/secure.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include "keystore.h"
|
#include "keystore.h"
|
||||||
|
|
||||||
#include "crypter.h"
|
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
|
168
src/main.cpp
168
src/main.cpp
|
@ -5,9 +5,9 @@
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#include "arith_uint256.h"
|
|
||||||
#include "addrman.h"
|
#include "addrman.h"
|
||||||
#include "alert.h"
|
#include "alert.h"
|
||||||
|
#include "arith_uint256.h"
|
||||||
#include "chainparams.h"
|
#include "chainparams.h"
|
||||||
#include "checkpoints.h"
|
#include "checkpoints.h"
|
||||||
#include "checkqueue.h"
|
#include "checkqueue.h"
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "utilmoneystr.h"
|
#include "utilmoneystr.h"
|
||||||
#include "ncc.h"
|
#include "ncc.h"
|
||||||
|
#include "validationinterface.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
@ -56,7 +57,6 @@ bool fTxIndex = false;
|
||||||
bool fIsBareMultisigStd = true;
|
bool fIsBareMultisigStd = true;
|
||||||
unsigned int nCoinCacheSize = 5000;
|
unsigned int nCoinCacheSize = 5000;
|
||||||
|
|
||||||
|
|
||||||
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
|
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
|
||||||
CFeeRate minRelayTxFee = CFeeRate(1000);
|
CFeeRate minRelayTxFee = CFeeRate(1000);
|
||||||
|
|
||||||
|
@ -159,68 +159,6 @@ namespace {
|
||||||
set<int> setDirtyFileInfo;
|
set<int> setDirtyFileInfo;
|
||||||
} // anon namespace
|
} // anon namespace
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// dispatching functions
|
|
||||||
//
|
|
||||||
|
|
||||||
// These functions dispatch to one or all registered wallets
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
struct CMainSignals {
|
|
||||||
/** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */
|
|
||||||
boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction;
|
|
||||||
/** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */
|
|
||||||
boost::signals2::signal<void (const uint256 &)> EraseTransaction;
|
|
||||||
/** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
|
|
||||||
boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
|
|
||||||
/** Notifies listeners of a new active block chain. */
|
|
||||||
boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
|
|
||||||
/** Notifies listeners about an inventory item being seen on the network. */
|
|
||||||
boost::signals2::signal<void (const uint256 &)> Inventory;
|
|
||||||
/** Tells listeners to broadcast their data. */
|
|
||||||
boost::signals2::signal<void ()> Broadcast;
|
|
||||||
/** Notifies listeners of a block validation result */
|
|
||||||
boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
|
|
||||||
} g_signals;
|
|
||||||
|
|
||||||
} // anon namespace
|
|
||||||
|
|
||||||
void RegisterValidationInterface(CValidationInterface* pwalletIn) {
|
|
||||||
g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
|
|
||||||
g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));
|
|
||||||
g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
|
|
||||||
g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
|
|
||||||
g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
|
|
||||||
g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn));
|
|
||||||
g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
|
|
||||||
g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
|
|
||||||
g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn));
|
|
||||||
g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
|
|
||||||
g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
|
|
||||||
g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
|
|
||||||
g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));
|
|
||||||
g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnregisterAllValidationInterfaces() {
|
|
||||||
g_signals.BlockChecked.disconnect_all_slots();
|
|
||||||
g_signals.Broadcast.disconnect_all_slots();
|
|
||||||
g_signals.Inventory.disconnect_all_slots();
|
|
||||||
g_signals.SetBestChain.disconnect_all_slots();
|
|
||||||
g_signals.UpdatedTransaction.disconnect_all_slots();
|
|
||||||
g_signals.EraseTransaction.disconnect_all_slots();
|
|
||||||
g_signals.SyncTransaction.disconnect_all_slots();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) {
|
|
||||||
g_signals.SyncTransaction(tx, pblock);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Registration of network node signals.
|
// Registration of network node signals.
|
||||||
|
@ -241,6 +179,10 @@ struct CBlockReject {
|
||||||
* and we're no longer holding the node's locks.
|
* and we're no longer holding the node's locks.
|
||||||
*/
|
*/
|
||||||
struct CNodeState {
|
struct CNodeState {
|
||||||
|
//! The peer's address
|
||||||
|
CService address;
|
||||||
|
//! Whether we have a fully established connection.
|
||||||
|
bool fCurrentlyConnected;
|
||||||
//! Accumulated misbehaviour score for this peer.
|
//! Accumulated misbehaviour score for this peer.
|
||||||
int nMisbehavior;
|
int nMisbehavior;
|
||||||
//! Whether this peer should be disconnected and banned (unless whitelisted).
|
//! Whether this peer should be disconnected and banned (unless whitelisted).
|
||||||
|
@ -265,6 +207,7 @@ struct CNodeState {
|
||||||
bool fPreferredDownload;
|
bool fPreferredDownload;
|
||||||
|
|
||||||
CNodeState() {
|
CNodeState() {
|
||||||
|
fCurrentlyConnected = false;
|
||||||
nMisbehavior = 0;
|
nMisbehavior = 0;
|
||||||
fShouldBan = false;
|
fShouldBan = false;
|
||||||
pindexBestKnownBlock = NULL;
|
pindexBestKnownBlock = NULL;
|
||||||
|
@ -308,6 +251,7 @@ void InitializeNode(NodeId nodeid, const CNode *pnode) {
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
|
CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
|
||||||
state.name = pnode->addrName;
|
state.name = pnode->addrName;
|
||||||
|
state.address = pnode->addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FinalizeNode(NodeId nodeid) {
|
void FinalizeNode(NodeId nodeid) {
|
||||||
|
@ -317,6 +261,10 @@ void FinalizeNode(NodeId nodeid) {
|
||||||
if (state->fSyncStarted)
|
if (state->fSyncStarted)
|
||||||
nSyncStarted--;
|
nSyncStarted--;
|
||||||
|
|
||||||
|
if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
|
||||||
|
AddressCurrentlyConnected(state->address);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
|
BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
|
||||||
mapBlocksInFlight.erase(entry.hash);
|
mapBlocksInFlight.erase(entry.hash);
|
||||||
EraseOrphansFor(nodeid);
|
EraseOrphansFor(nodeid);
|
||||||
|
@ -2026,7 +1974,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
|
|
||||||
// Watch for changes to the previous coinbase transaction.
|
// Watch for changes to the previous coinbase transaction.
|
||||||
static uint256 hashPrevBestCoinBase;
|
static uint256 hashPrevBestCoinBase;
|
||||||
g_signals.UpdatedTransaction(hashPrevBestCoinBase);
|
GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
|
||||||
hashPrevBestCoinBase = block.vtx[0].GetHash();
|
hashPrevBestCoinBase = block.vtx[0].GetHash();
|
||||||
|
|
||||||
int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3;
|
int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3;
|
||||||
|
@ -2087,7 +2035,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
|
||||||
return state.Abort("Failed to write to coin database");
|
return state.Abort("Failed to write to coin database");
|
||||||
// Update best block in wallet (so we can detect restored wallets).
|
// Update best block in wallet (so we can detect restored wallets).
|
||||||
if (mode != FLUSH_STATE_IF_NEEDED) {
|
if (mode != FLUSH_STATE_IF_NEEDED) {
|
||||||
g_signals.SetBestChain(chainActive.GetLocator());
|
GetMainSignals().SetBestChain(chainActive.GetLocator());
|
||||||
}
|
}
|
||||||
nLastWrite = GetTimeMicros();
|
nLastWrite = GetTimeMicros();
|
||||||
}
|
}
|
||||||
|
@ -2215,7 +2163,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
|
||||||
CNCCTrieCache trieCache(pnccTrie);
|
CNCCTrieCache trieCache(pnccTrie);
|
||||||
CInv inv(MSG_BLOCK, pindexNew->GetBlockHash());
|
CInv inv(MSG_BLOCK, pindexNew->GetBlockHash());
|
||||||
bool rv = ConnectBlock(*pblock, state, pindexNew, view, trieCache);
|
bool rv = ConnectBlock(*pblock, state, pindexNew, view, trieCache);
|
||||||
g_signals.BlockChecked(*pblock, state);
|
GetMainSignals().BlockChecked(*pblock, state);
|
||||||
if (!rv) {
|
if (!rv) {
|
||||||
if (state.IsInvalid())
|
if (state.IsInvalid())
|
||||||
InvalidBlockFound(pindexNew, state);
|
InvalidBlockFound(pindexNew, state);
|
||||||
|
@ -2456,8 +2404,8 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
|
||||||
// add them again.
|
// add them again.
|
||||||
BlockMap::iterator it = mapBlockIndex.begin();
|
BlockMap::iterator it = mapBlockIndex.begin();
|
||||||
while (it != mapBlockIndex.end()) {
|
while (it != mapBlockIndex.end()) {
|
||||||
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
|
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
|
||||||
setBlockIndexCandidates.insert(pindex);
|
setBlockIndexCandidates.insert(it->second);
|
||||||
}
|
}
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
|
@ -2600,8 +2548,11 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd
|
||||||
}
|
}
|
||||||
|
|
||||||
nLastBlockFile = nFile;
|
nLastBlockFile = nFile;
|
||||||
vinfoBlockFile[nFile].nSize += nAddSize;
|
|
||||||
vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
|
vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
|
||||||
|
if (fKnown)
|
||||||
|
vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
|
||||||
|
else
|
||||||
|
vinfoBlockFile[nFile].nSize += nAddSize;
|
||||||
|
|
||||||
if (!fKnown) {
|
if (!fKnown) {
|
||||||
unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
|
unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
|
||||||
|
@ -2739,8 +2690,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
|
||||||
int nHeight = pindexPrev->nHeight+1;
|
int nHeight = pindexPrev->nHeight+1;
|
||||||
|
|
||||||
// Check proof of work
|
// Check proof of work
|
||||||
if ((!Params().SkipProofOfWorkCheck()) &&
|
if ((block.nBits != GetNextWorkRequired(pindexPrev, &block)))
|
||||||
(block.nBits != GetNextWorkRequired(pindexPrev, &block)))
|
|
||||||
return state.DoS(100, error("%s: incorrect proof of work", __func__),
|
return state.DoS(100, error("%s: incorrect proof of work", __func__),
|
||||||
REJECT_INVALID, "bad-diffbits");
|
REJECT_INVALID, "bad-diffbits");
|
||||||
|
|
||||||
|
@ -3232,10 +3182,31 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
|
||||||
|
|
||||||
void UnloadBlockIndex()
|
void UnloadBlockIndex()
|
||||||
{
|
{
|
||||||
mapBlockIndex.clear();
|
LOCK(cs_main);
|
||||||
setBlockIndexCandidates.clear();
|
setBlockIndexCandidates.clear();
|
||||||
chainActive.SetTip(NULL);
|
chainActive.SetTip(NULL);
|
||||||
pindexBestInvalid = NULL;
|
pindexBestInvalid = NULL;
|
||||||
|
pindexBestHeader = NULL;
|
||||||
|
mempool.clear();
|
||||||
|
mapOrphanTransactions.clear();
|
||||||
|
mapOrphanTransactionsByPrev.clear();
|
||||||
|
nSyncStarted = 0;
|
||||||
|
mapBlocksUnlinked.clear();
|
||||||
|
vinfoBlockFile.clear();
|
||||||
|
nLastBlockFile = 0;
|
||||||
|
nBlockSequenceId = 1;
|
||||||
|
mapBlockSource.clear();
|
||||||
|
mapBlocksInFlight.clear();
|
||||||
|
nQueuedValidatedHeaders = 0;
|
||||||
|
nPreferredDownload = 0;
|
||||||
|
setDirtyBlockIndex.clear();
|
||||||
|
setDirtyFileInfo.clear();
|
||||||
|
mapNodeState.clear();
|
||||||
|
|
||||||
|
BOOST_FOREACH(BlockMap::value_type& entry, mapBlockIndex) {
|
||||||
|
delete entry.second;
|
||||||
|
}
|
||||||
|
mapBlockIndex.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadBlockIndex()
|
bool LoadBlockIndex()
|
||||||
|
@ -3502,19 +3473,17 @@ void static ProcessGetData(CNode* pfrom)
|
||||||
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
|
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
|
||||||
if (mi != mapBlockIndex.end())
|
if (mi != mapBlockIndex.end())
|
||||||
{
|
{
|
||||||
// If the requested block is at a height below our last
|
if (chainActive.Contains(mi->second)) {
|
||||||
// checkpoint, only serve it if it's in the checkpointed chain
|
|
||||||
int nHeight = mi->second->nHeight;
|
|
||||||
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
|
|
||||||
if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
|
|
||||||
if (!chainActive.Contains(mi->second))
|
|
||||||
{
|
|
||||||
LogPrintf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n");
|
|
||||||
} else {
|
|
||||||
send = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
send = true;
|
send = true;
|
||||||
|
} else {
|
||||||
|
// To prevent fingerprinting attacks, only send blocks outside of the active
|
||||||
|
// chain if they are valid, and no more than a month older than the best header
|
||||||
|
// chain we know about.
|
||||||
|
send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
|
||||||
|
(mi->second->GetBlockTime() > pindexBestHeader->GetBlockTime() - 30 * 24 * 60 * 60);
|
||||||
|
if (!send) {
|
||||||
|
LogPrintf("ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (send)
|
if (send)
|
||||||
|
@ -3588,7 +3557,7 @@ void static ProcessGetData(CNode* pfrom)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track requests for our stuff.
|
// Track requests for our stuff.
|
||||||
g_signals.Inventory(inv.hash);
|
GetMainSignals().Inventory(inv.hash);
|
||||||
|
|
||||||
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
|
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
|
||||||
break;
|
break;
|
||||||
|
@ -3754,6 +3723,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||||
else if (strCommand == "verack")
|
else if (strCommand == "verack")
|
||||||
{
|
{
|
||||||
pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
|
pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
|
||||||
|
|
||||||
|
// Mark this node as currently connected, so we update its timestamp later.
|
||||||
|
if (pfrom->fNetworkNode) {
|
||||||
|
LOCK(cs_main);
|
||||||
|
State(pfrom->GetId())->fCurrentlyConnected = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3876,7 +3851,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track requests for our stuff
|
// Track requests for our stuff
|
||||||
g_signals.Inventory(inv.hash);
|
GetMainSignals().Inventory(inv.hash);
|
||||||
|
|
||||||
if (pfrom->nSendSize > (SendBufferSize() * 2)) {
|
if (pfrom->nSendSize > (SendBufferSize() * 2)) {
|
||||||
Misbehaving(pfrom->GetId(), 50);
|
Misbehaving(pfrom->GetId(), 50);
|
||||||
|
@ -4170,7 +4145,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
else if (strCommand == "getaddr")
|
// This asymmetric behavior for inbound and outbound connections was introduced
|
||||||
|
// to prevent a fingerprinting attack: an attacker can send specific fake addresses
|
||||||
|
// to users' AddrMan and later request them by sending getaddr messages.
|
||||||
|
// Making users (which are behind NAT and can only make outgoing connections) ignore
|
||||||
|
// getaddr message mitigates the attack.
|
||||||
|
else if ((strCommand == "getaddr") && (pfrom->fInbound))
|
||||||
{
|
{
|
||||||
pfrom->vAddrToSend.clear();
|
pfrom->vAddrToSend.clear();
|
||||||
vector<CAddress> vAddr = addrman.GetAddr();
|
vector<CAddress> vAddr = addrman.GetAddr();
|
||||||
|
@ -4393,11 +4373,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Update the last seen time for this node's address
|
|
||||||
if (pfrom->fNetworkNode)
|
|
||||||
if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping")
|
|
||||||
AddressCurrentlyConnected(pfrom->addr);
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -4454,7 +4429,7 @@ bool ProcessMessages(CNode* pfrom)
|
||||||
|
|
||||||
// Read header
|
// Read header
|
||||||
CMessageHeader& hdr = msg.hdr;
|
CMessageHeader& hdr = msg.hdr;
|
||||||
if (!hdr.IsValid())
|
if (!hdr.IsValid(Params().MessageStart()))
|
||||||
{
|
{
|
||||||
LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
|
LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
|
||||||
continue;
|
continue;
|
||||||
|
@ -4467,8 +4442,7 @@ bool ProcessMessages(CNode* pfrom)
|
||||||
// Checksum
|
// Checksum
|
||||||
CDataStream& vRecv = msg.vRecv;
|
CDataStream& vRecv = msg.vRecv;
|
||||||
uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
|
uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
|
||||||
unsigned int nChecksum = 0;
|
unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
|
||||||
memcpy(&nChecksum, &hash, sizeof(nChecksum));
|
|
||||||
if (nChecksum != hdr.nChecksum)
|
if (nChecksum != hdr.nChecksum)
|
||||||
{
|
{
|
||||||
LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
|
LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
|
||||||
|
@ -4648,7 +4622,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||||
// transactions become unconfirmed and spams other nodes.
|
// transactions become unconfirmed and spams other nodes.
|
||||||
if (!fReindex && !fImporting && !IsInitialBlockDownload())
|
if (!fReindex && !fImporting && !IsInitialBlockDownload())
|
||||||
{
|
{
|
||||||
g_signals.Broadcast();
|
GetMainSignals().Broadcast();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
26
src/main.h
26
src/main.h
|
@ -134,15 +134,6 @@ extern CBlockIndex *pindexBestHeader;
|
||||||
/** Minimum disk space required - used in CheckDiskSpace() */
|
/** Minimum disk space required - used in CheckDiskSpace() */
|
||||||
static const uint64_t nMinDiskSpace = 52428800;
|
static const uint64_t nMinDiskSpace = 52428800;
|
||||||
|
|
||||||
/** Register a wallet to receive updates from core */
|
|
||||||
void RegisterValidationInterface(CValidationInterface* pwalletIn);
|
|
||||||
/** Unregister a wallet from core */
|
|
||||||
void UnregisterValidationInterface(CValidationInterface* pwalletIn);
|
|
||||||
/** Unregister all wallets from core */
|
|
||||||
void UnregisterAllValidationInterfaces();
|
|
||||||
/** Push an updated transaction to all registered wallets */
|
|
||||||
void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL);
|
|
||||||
|
|
||||||
/** Register with a network node to receive its signals */
|
/** Register with a network node to receive its signals */
|
||||||
void RegisterNodeSignals(CNodeSignals& nodeSignals);
|
void RegisterNodeSignals(CNodeSignals& nodeSignals);
|
||||||
/** Unregister a network node */
|
/** Unregister a network node */
|
||||||
|
@ -153,7 +144,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals);
|
||||||
* block is made active. Note that it does not, however, guarantee that the
|
* block is made active. Note that it does not, however, guarantee that the
|
||||||
* specific block passed to it has been checked for validity!
|
* specific block passed to it has been checked for validity!
|
||||||
*
|
*
|
||||||
* @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface - this will have its BlockChecked method called whenever *any* block completes validation.
|
* @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation.
|
||||||
* @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid.
|
* @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid.
|
||||||
* @param[in] pblock The block we want to process.
|
* @param[in] pblock The block we want to process.
|
||||||
* @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location.
|
* @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location.
|
||||||
|
@ -517,19 +508,4 @@ extern CNCCTrie *pnccTrie;
|
||||||
/** Global variable that points to the active block tree (protected by cs_main) */
|
/** Global variable that points to the active block tree (protected by cs_main) */
|
||||||
extern CBlockTreeDB *pblocktree;
|
extern CBlockTreeDB *pblocktree;
|
||||||
|
|
||||||
|
|
||||||
class CValidationInterface {
|
|
||||||
protected:
|
|
||||||
virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {};
|
|
||||||
virtual void EraseFromWallet(const uint256 &hash) {};
|
|
||||||
virtual void SetBestChain(const CBlockLocator &locator) {};
|
|
||||||
virtual void UpdatedTransaction(const uint256 &hash) {};
|
|
||||||
virtual void Inventory(const uint256 &hash) {};
|
|
||||||
virtual void ResendWalletTransactions() {};
|
|
||||||
virtual void BlockChecked(const CBlock&, const CValidationState&) {};
|
|
||||||
friend void ::RegisterValidationInterface(CValidationInterface*);
|
|
||||||
friend void ::UnregisterValidationInterface(CValidationInterface*);
|
|
||||||
friend void ::UnregisterAllValidationInterfaces();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BITCOIN_MAIN_H
|
#endif // BITCOIN_MAIN_H
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "utilmoneystr.h"
|
#include "utilmoneystr.h"
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
|
|
@ -109,6 +109,20 @@ bool CNCCTrie::queueEmpty() const
|
||||||
return valueQueue.empty();
|
return valueQueue.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CNCCTrie::clear()
|
||||||
|
{
|
||||||
|
clear(&root);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNCCTrie::clear(CNCCTrieNode* current)
|
||||||
|
{
|
||||||
|
for (nodeMapType::const_iterator itchildren = current->children.begin(); itchildren != current->children.end(); ++itchildren)
|
||||||
|
{
|
||||||
|
clear(itchildren->second);
|
||||||
|
delete itchildren->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CNCCTrie::haveClaim(const std::string& name, const uint256& txhash, uint32_t nOut) const
|
bool CNCCTrie::haveClaim(const std::string& name, const uint256& txhash, uint32_t nOut) const
|
||||||
{
|
{
|
||||||
const CNCCTrieNode* current = &root;
|
const CNCCTrieNode* current = &root;
|
||||||
|
|
|
@ -152,6 +152,7 @@ public:
|
||||||
uint256 getMerkleHash();
|
uint256 getMerkleHash();
|
||||||
CLevelDBWrapper db;
|
CLevelDBWrapper db;
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
|
void clear();
|
||||||
bool checkConsistency();
|
bool checkConsistency();
|
||||||
bool WriteToDisk();
|
bool WriteToDisk();
|
||||||
bool ReadFromDisk(bool check = false);
|
bool ReadFromDisk(bool check = false);
|
||||||
|
@ -162,6 +163,7 @@ public:
|
||||||
bool haveClaim(const std::string& name, const uint256& txhash, uint32_t nOut) const;
|
bool haveClaim(const std::string& name, const uint256& txhash, uint32_t nOut) const;
|
||||||
friend class CNCCTrieCache;
|
friend class CNCCTrieCache;
|
||||||
private:
|
private:
|
||||||
|
void clear(CNCCTrieNode* current);
|
||||||
bool update(nodeCacheType& cache, hashMapType& hashes, const uint256& hashBlock, valueQueueType& queueCache, int nNewHeight);
|
bool update(nodeCacheType& cache, hashMapType& hashes, const uint256& hashBlock, valueQueueType& queueCache, int nNewHeight);
|
||||||
bool updateName(const std::string& name, CNCCTrieNode* updatedNode);
|
bool updateName(const std::string& name, CNCCTrieNode* updatedNode);
|
||||||
bool updateHash(const std::string& name, uint256& hash);
|
bool updateHash(const std::string& name, uint256& hash);
|
||||||
|
|
12
src/net.cpp
12
src/net.cpp
|
@ -14,6 +14,7 @@
|
||||||
#include "clientversion.h"
|
#include "clientversion.h"
|
||||||
#include "primitives/transaction.h"
|
#include "primitives/transaction.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
|
#include "crypto/common.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -509,7 +510,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
|
||||||
// get current incomplete message, or create a new one
|
// get current incomplete message, or create a new one
|
||||||
if (vRecvMsg.empty() ||
|
if (vRecvMsg.empty() ||
|
||||||
vRecvMsg.back().complete())
|
vRecvMsg.back().complete())
|
||||||
vRecvMsg.push_back(CNetMessage(SER_NETWORK, nRecvVersion));
|
vRecvMsg.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK, nRecvVersion));
|
||||||
|
|
||||||
CNetMessage& msg = vRecvMsg.back();
|
CNetMessage& msg = vRecvMsg.back();
|
||||||
|
|
||||||
|
@ -523,6 +524,11 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
|
||||||
if (handled < 0)
|
if (handled < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
|
||||||
|
LogPrint("net", "Oversized message from peer=%i, disconnecting", GetId());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
pch += handled;
|
pch += handled;
|
||||||
nBytes -= handled;
|
nBytes -= handled;
|
||||||
|
|
||||||
|
@ -1970,7 +1976,7 @@ void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSen
|
||||||
{
|
{
|
||||||
ENTER_CRITICAL_SECTION(cs_vSend);
|
ENTER_CRITICAL_SECTION(cs_vSend);
|
||||||
assert(ssSend.size() == 0);
|
assert(ssSend.size() == 0);
|
||||||
ssSend << CMessageHeader(pszCommand, 0);
|
ssSend << CMessageHeader(Params().MessageStart(), pszCommand, 0);
|
||||||
LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
|
LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2002,7 +2008,7 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
|
||||||
|
|
||||||
// Set the size
|
// Set the size
|
||||||
unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
|
unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
|
||||||
memcpy((char*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], &nSize, sizeof(nSize));
|
WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
|
||||||
|
|
||||||
// Set the checksum
|
// Set the checksum
|
||||||
uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
|
uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
|
||||||
|
|
26
src/net.h
26
src/net.h
|
@ -46,6 +46,8 @@ static const int TIMEOUT_INTERVAL = 20 * 60;
|
||||||
static const unsigned int MAX_INV_SZ = 50000;
|
static const unsigned int MAX_INV_SZ = 50000;
|
||||||
/** The maximum number of new addresses to accumulate before announcing. */
|
/** The maximum number of new addresses to accumulate before announcing. */
|
||||||
static const unsigned int MAX_ADDR_TO_SEND = 1000;
|
static const unsigned int MAX_ADDR_TO_SEND = 1000;
|
||||||
|
/** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */
|
||||||
|
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024;
|
||||||
/** -listen default */
|
/** -listen default */
|
||||||
static const bool DEFAULT_LISTEN = true;
|
static const bool DEFAULT_LISTEN = true;
|
||||||
/** -upnp default */
|
/** -upnp default */
|
||||||
|
@ -76,12 +78,27 @@ void SocketSendData(CNode *pnode);
|
||||||
|
|
||||||
typedef int NodeId;
|
typedef int NodeId;
|
||||||
|
|
||||||
|
struct CombinerAll
|
||||||
|
{
|
||||||
|
typedef bool result_type;
|
||||||
|
|
||||||
|
template<typename I>
|
||||||
|
bool operator()(I first, I last) const
|
||||||
|
{
|
||||||
|
while (first != last) {
|
||||||
|
if (!(*first)) return false;
|
||||||
|
++first;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Signals for message handling
|
// Signals for message handling
|
||||||
struct CNodeSignals
|
struct CNodeSignals
|
||||||
{
|
{
|
||||||
boost::signals2::signal<int ()> GetHeight;
|
boost::signals2::signal<int ()> GetHeight;
|
||||||
boost::signals2::signal<bool (CNode*)> ProcessMessages;
|
boost::signals2::signal<bool (CNode*), CombinerAll> ProcessMessages;
|
||||||
boost::signals2::signal<bool (CNode*, bool)> SendMessages;
|
boost::signals2::signal<bool (CNode*, bool), CombinerAll> SendMessages;
|
||||||
boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
|
boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
|
||||||
boost::signals2::signal<void (NodeId)> FinalizeNode;
|
boost::signals2::signal<void (NodeId)> FinalizeNode;
|
||||||
};
|
};
|
||||||
|
@ -183,7 +200,7 @@ public:
|
||||||
|
|
||||||
int64_t nTime; // time (in microseconds) of message receipt.
|
int64_t nTime; // time (in microseconds) of message receipt.
|
||||||
|
|
||||||
CNetMessage(int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), vRecv(nTypeIn, nVersionIn) {
|
CNetMessage(const CMessageHeader::MessageStartChars& pchMessageStartIn, int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), hdr(pchMessageStartIn), vRecv(nTypeIn, nVersionIn) {
|
||||||
hdrbuf.resize(24);
|
hdrbuf.resize(24);
|
||||||
in_data = false;
|
in_data = false;
|
||||||
nHdrPos = 0;
|
nHdrPos = 0;
|
||||||
|
@ -570,9 +587,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSubscribed(unsigned int nChannel);
|
|
||||||
void Subscribe(unsigned int nChannel, unsigned int nHops=0);
|
|
||||||
void CancelSubscribe(unsigned int nChannel);
|
|
||||||
void CloseSocketDisconnect();
|
void CloseSocketDisconnect();
|
||||||
|
|
||||||
// Denial-of-service detection/prevention
|
// Denial-of-service detection/prevention
|
||||||
|
|
|
@ -162,7 +162,7 @@ class CService : public CNetAddr
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||||
READWRITE(FLATDATA(ip));
|
READWRITE(FLATDATA(ip));
|
||||||
unsigned short portN = htons(port);
|
unsigned short portN = htons(port);
|
||||||
READWRITE(portN);
|
READWRITE(FLATDATA(portN));
|
||||||
if (ser_action.ForRead())
|
if (ser_action.ForRead())
|
||||||
port = ntohs(portN);
|
port = ntohs(portN);
|
||||||
}
|
}
|
||||||
|
|
10
src/pow.cpp
10
src/pow.cpp
|
@ -48,8 +48,13 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
|
||||||
pindexFirst = pindexFirst->pprev;
|
pindexFirst = pindexFirst->pprev;
|
||||||
assert(pindexFirst);
|
assert(pindexFirst);
|
||||||
|
|
||||||
|
return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime)
|
||||||
|
{
|
||||||
// Limit adjustment step
|
// Limit adjustment step
|
||||||
int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
|
int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
|
||||||
LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
|
LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
|
||||||
if (nActualTimespan < Params().TargetTimespan()/4)
|
if (nActualTimespan < Params().TargetTimespan()/4)
|
||||||
nActualTimespan = Params().TargetTimespan()/4;
|
nActualTimespan = Params().TargetTimespan()/4;
|
||||||
|
@ -82,9 +87,6 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits)
|
||||||
bool fOverflow;
|
bool fOverflow;
|
||||||
arith_uint256 bnTarget;
|
arith_uint256 bnTarget;
|
||||||
|
|
||||||
if (Params().SkipProofOfWorkCheck())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
|
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
|
||||||
|
|
||||||
// Check range
|
// Check range
|
||||||
|
|
|
@ -14,6 +14,7 @@ class uint256;
|
||||||
class arith_uint256;
|
class arith_uint256;
|
||||||
|
|
||||||
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock);
|
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock);
|
||||||
|
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime);
|
||||||
|
|
||||||
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
|
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
|
||||||
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
|
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
|
||||||
|
|
|
@ -8,10 +8,11 @@
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "tinyformat.h"
|
#include "tinyformat.h"
|
||||||
#include "utilstrencodings.h"
|
#include "utilstrencodings.h"
|
||||||
|
#include "crypto/common.h"
|
||||||
|
|
||||||
uint256 CBlockHeader::GetHash() const
|
uint256 CBlockHeader::GetHash() const
|
||||||
{
|
{
|
||||||
return Hash(BEGIN(nVersion), END(nNonce));
|
return SerializeHash(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 CBlock::BuildMerkleTree(bool* fMutated) const
|
uint256 CBlock::BuildMerkleTree(bool* fMutated) const
|
||||||
|
|
|
@ -25,7 +25,8 @@ public:
|
||||||
|
|
||||||
template <typename Stream, typename Operation>
|
template <typename Stream, typename Operation>
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||||
READWRITE(FLATDATA(*this));
|
READWRITE(hash);
|
||||||
|
READWRITE(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetNull() { hash.SetNull(); n = (uint32_t) -1; }
|
void SetNull() { hash.SetNull(); n = (uint32_t) -1; }
|
||||||
|
@ -134,7 +135,7 @@ public:
|
||||||
|
|
||||||
uint256 GetHash() const;
|
uint256 GetHash() const;
|
||||||
|
|
||||||
bool IsDust(CFeeRate minRelayTxFee) const
|
CAmount GetDustThreshold(const CFeeRate &minRelayTxFee) const
|
||||||
{
|
{
|
||||||
// "Dust" is defined in terms of CTransaction::minRelayTxFee,
|
// "Dust" is defined in terms of CTransaction::minRelayTxFee,
|
||||||
// which has units satoshis-per-kilobyte.
|
// which has units satoshis-per-kilobyte.
|
||||||
|
@ -145,7 +146,12 @@ public:
|
||||||
// so dust is a txout less than 546 satoshis
|
// so dust is a txout less than 546 satoshis
|
||||||
// with default minRelayTxFee.
|
// with default minRelayTxFee.
|
||||||
size_t nSize = GetSerializeSize(SER_DISK,0)+148u;
|
size_t nSize = GetSerializeSize(SER_DISK,0)+148u;
|
||||||
return (nValue < 3*minRelayTxFee.GetFee(nSize));
|
return 3*minRelayTxFee.GetFee(nSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsDust(const CFeeRate &minRelayTxFee) const
|
||||||
|
{
|
||||||
|
return (nValue < GetDustThreshold(minRelayTxFee));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator==(const CTxOut& a, const CTxOut& b)
|
friend bool operator==(const CTxOut& a, const CTxOut& b)
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
#include "chainparams.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "utilstrencodings.h"
|
#include "utilstrencodings.h"
|
||||||
|
|
||||||
|
@ -21,17 +20,17 @@ static const char* ppszTypeName[] =
|
||||||
"filtered block"
|
"filtered block"
|
||||||
};
|
};
|
||||||
|
|
||||||
CMessageHeader::CMessageHeader()
|
CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn)
|
||||||
{
|
{
|
||||||
memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
|
memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
|
||||||
memset(pchCommand, 0, sizeof(pchCommand));
|
memset(pchCommand, 0, sizeof(pchCommand));
|
||||||
nMessageSize = -1;
|
nMessageSize = -1;
|
||||||
nChecksum = 0;
|
nChecksum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
|
CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
|
||||||
{
|
{
|
||||||
memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
|
memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
|
||||||
memset(pchCommand, 0, sizeof(pchCommand));
|
memset(pchCommand, 0, sizeof(pchCommand));
|
||||||
strncpy(pchCommand, pszCommand, COMMAND_SIZE);
|
strncpy(pchCommand, pszCommand, COMMAND_SIZE);
|
||||||
nMessageSize = nMessageSizeIn;
|
nMessageSize = nMessageSizeIn;
|
||||||
|
@ -43,10 +42,10 @@ std::string CMessageHeader::GetCommand() const
|
||||||
return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
|
return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMessageHeader::IsValid() const
|
bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const
|
||||||
{
|
{
|
||||||
// Check start string
|
// Check start string
|
||||||
if (memcmp(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0)
|
if (memcmp(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check the command string for errors
|
// Check the command string for errors
|
||||||
|
|
|
@ -29,11 +29,13 @@
|
||||||
class CMessageHeader
|
class CMessageHeader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMessageHeader();
|
typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
|
||||||
CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn);
|
|
||||||
|
CMessageHeader(const MessageStartChars& pchMessageStartIn);
|
||||||
|
CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn);
|
||||||
|
|
||||||
std::string GetCommand() const;
|
std::string GetCommand() const;
|
||||||
bool IsValid() const;
|
bool IsValid(const MessageStartChars& messageStart) const;
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
|
|
@ -6,25 +6,16 @@
|
||||||
|
|
||||||
#include "eccryptoverify.h"
|
#include "eccryptoverify.h"
|
||||||
|
|
||||||
#ifdef USE_SECP256K1
|
|
||||||
#include <secp256k1.h>
|
|
||||||
#else
|
|
||||||
#include "ecwrapper.h"
|
#include "ecwrapper.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
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, &vchSig[0], vchSig.size(), begin(), size()) != 1)
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
CECKey key;
|
CECKey key;
|
||||||
if (!key.SetPubKey(begin(), size()))
|
if (!key.SetPubKey(begin(), size()))
|
||||||
return false;
|
return false;
|
||||||
if (!key.Verify(hash, vchSig))
|
if (!key.Verify(hash, vchSig))
|
||||||
return false;
|
return false;
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,52 +24,33 @@ bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned cha
|
||||||
return false;
|
return false;
|
||||||
int recid = (vchSig[0] - 27) & 3;
|
int recid = (vchSig[0] - 27) & 3;
|
||||||
bool fComp = ((vchSig[0] - 27) & 4) != 0;
|
bool fComp = ((vchSig[0] - 27) & 4) != 0;
|
||||||
#ifdef USE_SECP256K1
|
|
||||||
int pubkeylen = 65;
|
|
||||||
if (!secp256k1_ecdsa_recover_compact((const unsigned char*)&hash, &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], recid))
|
if (!key.Recover(hash, &vchSig[1], recid))
|
||||||
return false;
|
return false;
|
||||||
std::vector<unsigned char> pubkey;
|
std::vector<unsigned char> pubkey;
|
||||||
key.GetPubKey(pubkey, fComp);
|
key.GetPubKey(pubkey, fComp);
|
||||||
Set(pubkey.begin(), pubkey.end());
|
Set(pubkey.begin(), pubkey.end());
|
||||||
#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(begin(), size()))
|
if (!key.SetPubKey(begin(), size()))
|
||||||
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(begin(), size()))
|
if (!key.SetPubKey(begin(), size()))
|
||||||
return false;
|
return false;
|
||||||
std::vector<unsigned char> pubkey;
|
std::vector<unsigned char> pubkey;
|
||||||
key.GetPubKey(pubkey, false);
|
key.GetPubKey(pubkey, false);
|
||||||
Set(pubkey.begin(), pubkey.end());
|
Set(pubkey.begin(), pubkey.end());
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,17 +61,12 @@ 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(begin(), size());
|
bool ret = key.SetPubKey(begin(), size());
|
||||||
ret &= key.TweakPublic(out);
|
ret &= key.TweakPublic(out);
|
||||||
std::vector<unsigned char> pubkey;
|
std::vector<unsigned char> pubkey;
|
||||||
key.GetPubKey(pubkey, true);
|
key.GetPubKey(pubkey, true);
|
||||||
pubkeyChild.Set(pubkey.begin(), pubkey.end());
|
pubkeyChild.Set(pubkey.begin(), pubkey.end());
|
||||||
#endif
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,9 @@
|
||||||
#include "walletmodel.h"
|
#include "walletmodel.h"
|
||||||
|
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "guiconstants.h"
|
#include "guiconstants.h"
|
||||||
#include "walletmodel.h"
|
#include "walletmodel.h"
|
||||||
|
|
||||||
#include "allocators.h"
|
#include "support/allocators/secure.h"
|
||||||
|
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
|
@ -151,7 +151,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
|
||||||
|
|
||||||
// Create actions for the toolbar, menu bar and tray/dock icon
|
// Create actions for the toolbar, menu bar and tray/dock icon
|
||||||
// Needs walletFrame to be initialized
|
// Needs walletFrame to be initialized
|
||||||
createActions(networkStyle);
|
createActions();
|
||||||
|
|
||||||
// Create application menu bar
|
// Create application menu bar
|
||||||
createMenuBar();
|
createMenuBar();
|
||||||
|
@ -237,13 +237,13 @@ BitcoinGUI::~BitcoinGUI()
|
||||||
trayIcon->hide();
|
trayIcon->hide();
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
delete appMenuBar;
|
delete appMenuBar;
|
||||||
MacDockIconHandler::instance()->setMainWindow(NULL);
|
MacDockIconHandler::cleanup();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
delete rpcConsole;
|
delete rpcConsole;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
|
void BitcoinGUI::createActions()
|
||||||
{
|
{
|
||||||
QActionGroup *tabGroup = new QActionGroup(this);
|
QActionGroup *tabGroup = new QActionGroup(this);
|
||||||
|
|
||||||
|
@ -340,6 +340,7 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
|
||||||
openAction->setStatusTip(tr("Open a bitcoin: URI or payment request"));
|
openAction->setStatusTip(tr("Open a bitcoin: URI or payment request"));
|
||||||
|
|
||||||
showHelpMessageAction = new QAction(TextColorIcon(":/icons/info"), tr("&Command-line options"), this);
|
showHelpMessageAction = new QAction(TextColorIcon(":/icons/info"), tr("&Command-line options"), this);
|
||||||
|
showHelpMessageAction->setMenuRole(QAction::NoRole);
|
||||||
showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options"));
|
showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options"));
|
||||||
|
|
||||||
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
|
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
|
||||||
|
@ -435,8 +436,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
|
||||||
setNumConnections(clientModel->getNumConnections());
|
setNumConnections(clientModel->getNumConnections());
|
||||||
connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
|
connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
|
||||||
|
|
||||||
setNumBlocks(clientModel->getNumBlocks());
|
setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate());
|
||||||
connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
|
connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
|
||||||
|
|
||||||
// Receive and report messages from client model
|
// Receive and report messages from client model
|
||||||
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
|
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
|
||||||
|
@ -652,7 +653,7 @@ void BitcoinGUI::setNumConnections(int count)
|
||||||
labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count));
|
labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcoinGUI::setNumBlocks(int count)
|
void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate)
|
||||||
{
|
{
|
||||||
if(!clientModel)
|
if(!clientModel)
|
||||||
return;
|
return;
|
||||||
|
@ -680,9 +681,8 @@ void BitcoinGUI::setNumBlocks(int count)
|
||||||
|
|
||||||
QString tooltip;
|
QString tooltip;
|
||||||
|
|
||||||
QDateTime lastBlockDate = clientModel->getLastBlockDate();
|
|
||||||
QDateTime currentDate = QDateTime::currentDateTime();
|
QDateTime currentDate = QDateTime::currentDateTime();
|
||||||
int secs = lastBlockDate.secsTo(currentDate);
|
qint64 secs = blockDate.secsTo(currentDate);
|
||||||
|
|
||||||
tooltip = tr("Processed %n blocks of transaction history.", "", count);
|
tooltip = tr("Processed %n blocks of transaction history.", "", count);
|
||||||
|
|
||||||
|
@ -722,8 +722,8 @@ void BitcoinGUI::setNumBlocks(int count)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int years = secs / YEAR_IN_SECONDS;
|
qint64 years = secs / YEAR_IN_SECONDS;
|
||||||
int remainder = secs % YEAR_IN_SECONDS;
|
qint64 remainder = secs % YEAR_IN_SECONDS;
|
||||||
timeBehindText = tr("%1 and %2").arg(tr("%n year(s)", "", years)).arg(tr("%n week(s)","", remainder/WEEK_IN_SECONDS));
|
timeBehindText = tr("%1 and %2").arg(tr("%n year(s)", "", years)).arg(tr("%n week(s)","", remainder/WEEK_IN_SECONDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ private:
|
||||||
int spinnerFrame;
|
int spinnerFrame;
|
||||||
|
|
||||||
/** Create the main UI actions. */
|
/** Create the main UI actions. */
|
||||||
void createActions(const NetworkStyle *networkStyle);
|
void createActions();
|
||||||
/** Create the menu bar and sub-menus. */
|
/** Create the menu bar and sub-menus. */
|
||||||
void createMenuBar();
|
void createMenuBar();
|
||||||
/** Create the toolbars */
|
/** Create the toolbars */
|
||||||
|
@ -143,8 +143,8 @@ signals:
|
||||||
public slots:
|
public slots:
|
||||||
/** Set number of connections shown in the UI */
|
/** Set number of connections shown in the UI */
|
||||||
void setNumConnections(int count);
|
void setNumConnections(int count);
|
||||||
/** Set number of blocks shown in the UI */
|
/** Set number of blocks and last block date shown in the UI */
|
||||||
void setNumBlocks(int count);
|
void setNumBlocks(int count, const QDateTime& blockDate);
|
||||||
|
|
||||||
/** Notify the user of an event from the core network or transaction handling code.
|
/** Notify the user of an event from the core network or transaction handling code.
|
||||||
@param[in] title the message box / notification title
|
@param[in] title the message box / notification title
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <QDateTime>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
@ -29,8 +28,10 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
|
||||||
optionsModel(optionsModel),
|
optionsModel(optionsModel),
|
||||||
peerTableModel(0),
|
peerTableModel(0),
|
||||||
cachedNumBlocks(0),
|
cachedNumBlocks(0),
|
||||||
cachedReindexing(0), cachedImporting(0),
|
cachedBlockDate(QDateTime()),
|
||||||
numBlocksAtStartup(-1), pollTimer(0)
|
cachedReindexing(0),
|
||||||
|
cachedImporting(0),
|
||||||
|
pollTimer(0)
|
||||||
{
|
{
|
||||||
peerTableModel = new PeerTableModel(this);
|
peerTableModel = new PeerTableModel(this);
|
||||||
pollTimer = new QTimer(this);
|
pollTimer = new QTimer(this);
|
||||||
|
@ -65,12 +66,6 @@ int ClientModel::getNumBlocks() const
|
||||||
return chainActive.Height();
|
return chainActive.Height();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ClientModel::getNumBlocksAtStartup()
|
|
||||||
{
|
|
||||||
if (numBlocksAtStartup == -1) numBlocksAtStartup = getNumBlocks();
|
|
||||||
return numBlocksAtStartup;
|
|
||||||
}
|
|
||||||
|
|
||||||
quint64 ClientModel::getTotalBytesRecv() const
|
quint64 ClientModel::getTotalBytesRecv() const
|
||||||
{
|
{
|
||||||
return CNode::GetTotalBytesRecv();
|
return CNode::GetTotalBytesRecv();
|
||||||
|
@ -84,10 +79,11 @@ quint64 ClientModel::getTotalBytesSent() const
|
||||||
QDateTime ClientModel::getLastBlockDate() const
|
QDateTime ClientModel::getLastBlockDate() const
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
|
||||||
if (chainActive.Tip())
|
if (chainActive.Tip())
|
||||||
return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());
|
return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());
|
||||||
else
|
|
||||||
return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
|
return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
|
||||||
}
|
}
|
||||||
|
|
||||||
double ClientModel::getVerificationProgress() const
|
double ClientModel::getVerificationProgress() const
|
||||||
|
@ -102,21 +98,26 @@ void ClientModel::updateTimer()
|
||||||
// periodical polls if the core is holding the locks for a longer time -
|
// periodical polls if the core is holding the locks for a longer time -
|
||||||
// for example, during a wallet rescan.
|
// for example, during a wallet rescan.
|
||||||
TRY_LOCK(cs_main, lockMain);
|
TRY_LOCK(cs_main, lockMain);
|
||||||
if(!lockMain)
|
if (!lockMain)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change.
|
// Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change.
|
||||||
// Periodically check and update with a timer.
|
// Periodically check and update with a timer.
|
||||||
int newNumBlocks = getNumBlocks();
|
int newNumBlocks = getNumBlocks();
|
||||||
|
QDateTime newBlockDate = getLastBlockDate();
|
||||||
|
|
||||||
// check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state
|
// check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state
|
||||||
if (cachedNumBlocks != newNumBlocks ||
|
if (cachedNumBlocks != newNumBlocks ||
|
||||||
cachedReindexing != fReindex || cachedImporting != fImporting)
|
cachedBlockDate != newBlockDate ||
|
||||||
|
cachedReindexing != fReindex ||
|
||||||
|
cachedImporting != fImporting)
|
||||||
{
|
{
|
||||||
cachedNumBlocks = newNumBlocks;
|
cachedNumBlocks = newNumBlocks;
|
||||||
|
cachedBlockDate = newBlockDate;
|
||||||
cachedReindexing = fReindex;
|
cachedReindexing = fReindex;
|
||||||
cachedImporting = fImporting;
|
cachedImporting = fImporting;
|
||||||
|
|
||||||
emit numBlocksChanged(newNumBlocks);
|
emit numBlocksChanged(newNumBlocks, newBlockDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit bytesChanged(getTotalBytesRecv(), getTotalBytesSent());
|
emit bytesChanged(getTotalBytesRecv(), getTotalBytesSent());
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#define BITCOIN_QT_CLIENTMODEL_H
|
#define BITCOIN_QT_CLIENTMODEL_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
class AddressTableModel;
|
class AddressTableModel;
|
||||||
class OptionsModel;
|
class OptionsModel;
|
||||||
|
@ -15,7 +16,6 @@ class TransactionTableModel;
|
||||||
class CWallet;
|
class CWallet;
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QDateTime;
|
|
||||||
class QTimer;
|
class QTimer;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
@ -48,7 +48,6 @@ public:
|
||||||
//! Return number of connections, default is in- and outbound (total)
|
//! Return number of connections, default is in- and outbound (total)
|
||||||
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
|
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
|
||||||
int getNumBlocks() const;
|
int getNumBlocks() const;
|
||||||
int getNumBlocksAtStartup();
|
|
||||||
|
|
||||||
quint64 getTotalBytesRecv() const;
|
quint64 getTotalBytesRecv() const;
|
||||||
quint64 getTotalBytesSent() const;
|
quint64 getTotalBytesSent() const;
|
||||||
|
@ -74,11 +73,10 @@ private:
|
||||||
PeerTableModel *peerTableModel;
|
PeerTableModel *peerTableModel;
|
||||||
|
|
||||||
int cachedNumBlocks;
|
int cachedNumBlocks;
|
||||||
|
QDateTime cachedBlockDate;
|
||||||
bool cachedReindexing;
|
bool cachedReindexing;
|
||||||
bool cachedImporting;
|
bool cachedImporting;
|
||||||
|
|
||||||
int numBlocksAtStartup;
|
|
||||||
|
|
||||||
QTimer *pollTimer;
|
QTimer *pollTimer;
|
||||||
|
|
||||||
void subscribeToCoreSignals();
|
void subscribeToCoreSignals();
|
||||||
|
@ -86,7 +84,7 @@ private:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void numConnectionsChanged(int count);
|
void numConnectionsChanged(int count);
|
||||||
void numBlocksChanged(int count);
|
void numBlocksChanged(int count, const QDateTime& blockDate);
|
||||||
void alertsChanged(const QString &warnings);
|
void alertsChanged(const QString &warnings);
|
||||||
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut);
|
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
#include "coincontrol.h"
|
#include "coincontrol.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
|
|
||||||
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
|
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
QList<CAmount> CoinControlDialog::payAmounts;
|
QList<CAmount> CoinControlDialog::payAmounts;
|
||||||
CCoinControl* CoinControlDialog::coinControl = new CCoinControl();
|
CCoinControl* CoinControlDialog::coinControl = new CCoinControl();
|
||||||
|
bool CoinControlDialog::fSubtractFeeFromAmount = false;
|
||||||
|
|
||||||
CoinControlDialog::CoinControlDialog(QWidget *parent) :
|
CoinControlDialog::CoinControlDialog(QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
|
@ -541,6 +542,11 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
||||||
dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29)); // 29 = 180 - 151 (uncompressed public keys are over the limit. max 151 bytes of the input are ignored for priority)
|
dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29)); // 29 = 180 - 151 (uncompressed public keys are over the limit. max 151 bytes of the input are ignored for priority)
|
||||||
sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority);
|
sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority);
|
||||||
|
|
||||||
|
// in the subtract fee from amount case, we can tell if zero change already and subtract the bytes, so that fee calculation afterwards is accurate
|
||||||
|
if (CoinControlDialog::fSubtractFeeFromAmount)
|
||||||
|
if (nAmount - nPayAmount == 0)
|
||||||
|
nBytes -= 34;
|
||||||
|
|
||||||
// Fee
|
// Fee
|
||||||
nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
|
nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
|
||||||
|
|
||||||
|
@ -556,7 +562,9 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
||||||
|
|
||||||
if (nPayAmount > 0)
|
if (nPayAmount > 0)
|
||||||
{
|
{
|
||||||
nChange = nAmount - nPayFee - nPayAmount;
|
nChange = nAmount - nPayAmount;
|
||||||
|
if (!CoinControlDialog::fSubtractFeeFromAmount)
|
||||||
|
nChange -= nPayFee;
|
||||||
|
|
||||||
// Never create dust outputs; if we would, just add the dust to the fee.
|
// Never create dust outputs; if we would, just add the dust to the fee.
|
||||||
if (nChange > 0 && nChange < CENT)
|
if (nChange > 0 && nChange < CENT)
|
||||||
|
@ -564,12 +572,17 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
||||||
CTxOut txout(nChange, (CScript)vector<unsigned char>(24, 0));
|
CTxOut txout(nChange, (CScript)vector<unsigned char>(24, 0));
|
||||||
if (txout.IsDust(::minRelayTxFee))
|
if (txout.IsDust(::minRelayTxFee))
|
||||||
{
|
{
|
||||||
nPayFee += nChange;
|
if (CoinControlDialog::fSubtractFeeFromAmount) // dust-change will be raised until no dust
|
||||||
nChange = 0;
|
nChange = txout.GetDustThreshold(::minRelayTxFee);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nPayFee += nChange;
|
||||||
|
nChange = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nChange == 0)
|
if (nChange == 0 && !CoinControlDialog::fSubtractFeeFromAmount)
|
||||||
nBytes -= 34;
|
nBytes -= 34;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,7 +625,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
||||||
{
|
{
|
||||||
l3->setText(ASYMP_UTF8 + l3->text());
|
l3->setText(ASYMP_UTF8 + l3->text());
|
||||||
l4->setText(ASYMP_UTF8 + l4->text());
|
l4->setText(ASYMP_UTF8 + l4->text());
|
||||||
if (nChange > 0)
|
if (nChange > 0 && !CoinControlDialog::fSubtractFeeFromAmount)
|
||||||
l8->setText(ASYMP_UTF8 + l8->text());
|
l8->setText(ASYMP_UTF8 + l8->text());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ public:
|
||||||
|
|
||||||
static QList<CAmount> payAmounts;
|
static QList<CAmount> payAmounts;
|
||||||
static CCoinControl *coinControl;
|
static CCoinControl *coinControl;
|
||||||
|
static bool fSubtractFeeFromAmount;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::CoinControlDialog *ui;
|
Ui::CoinControlDialog *ui;
|
||||||
|
|
|
@ -771,16 +771,6 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="buttonMinimizeFee">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>collapse fee-settings</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Minimize</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -811,6 +801,16 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="buttonMinimizeFee">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>collapse fee-settings</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Minimize</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|
|
@ -157,7 +157,21 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="BitcoinAmountField" name="payAmount"/>
|
<layout class="QHBoxLayout" name="horizontalLayoutAmount" stretch="0,1">
|
||||||
|
<item>
|
||||||
|
<widget class="BitcoinAmountField" name="payAmount"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkboxSubtractFeeFromAmount">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>S&ubtract fee from amount</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="messageLabel">
|
<widget class="QLabel" name="messageLabel">
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#if BOOST_FILESYSTEM_VERSION >= 3
|
#if BOOST_FILESYSTEM_VERSION >= 3
|
||||||
#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
|
#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
#include <boost/scoped_array.hpp>
|
||||||
|
|
||||||
#include <QAbstractItemView>
|
#include <QAbstractItemView>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
@ -567,12 +568,17 @@ TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* t
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
boost::filesystem::path static StartupShortcutPath()
|
boost::filesystem::path static StartupShortcutPath()
|
||||||
{
|
{
|
||||||
|
if (GetBoolArg("-testnet", false))
|
||||||
|
return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (testnet).lnk";
|
||||||
|
else if (GetBoolArg("-regtest", false))
|
||||||
|
return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (regtest).lnk";
|
||||||
|
|
||||||
return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk";
|
return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetStartOnSystemStartup()
|
bool GetStartOnSystemStartup()
|
||||||
{
|
{
|
||||||
// check for Bitcoin.lnk
|
// check for Bitcoin*.lnk
|
||||||
return boost::filesystem::exists(StartupShortcutPath());
|
return boost::filesystem::exists(StartupShortcutPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,8 +594,8 @@ bool SetStartOnSystemStartup(bool fAutoStart)
|
||||||
// Get a pointer to the IShellLink interface.
|
// Get a pointer to the IShellLink interface.
|
||||||
IShellLink* psl = NULL;
|
IShellLink* psl = NULL;
|
||||||
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
|
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
|
||||||
CLSCTX_INPROC_SERVER, IID_IShellLink,
|
CLSCTX_INPROC_SERVER, IID_IShellLink,
|
||||||
reinterpret_cast<void**>(&psl));
|
reinterpret_cast<void**>(&psl));
|
||||||
|
|
||||||
if (SUCCEEDED(hres))
|
if (SUCCEEDED(hres))
|
||||||
{
|
{
|
||||||
|
@ -597,20 +603,34 @@ bool SetStartOnSystemStartup(bool fAutoStart)
|
||||||
TCHAR pszExePath[MAX_PATH];
|
TCHAR pszExePath[MAX_PATH];
|
||||||
GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
|
GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
|
||||||
|
|
||||||
TCHAR pszArgs[5] = TEXT("-min");
|
// Start client minimized
|
||||||
|
QString strArgs = "-min";
|
||||||
|
// Set -testnet /-regtest options
|
||||||
|
strArgs += QString::fromStdString(strprintf(" -testnet=%d -regtest=%d", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false)));
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
boost::scoped_array<TCHAR> args(new TCHAR[strArgs.length() + 1]);
|
||||||
|
// Convert the QString to TCHAR*
|
||||||
|
strArgs.toWCharArray(args.get());
|
||||||
|
// Add missing '\0'-termination to string
|
||||||
|
args[strArgs.length()] = '\0';
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set the path to the shortcut target
|
// Set the path to the shortcut target
|
||||||
psl->SetPath(pszExePath);
|
psl->SetPath(pszExePath);
|
||||||
PathRemoveFileSpec(pszExePath);
|
PathRemoveFileSpec(pszExePath);
|
||||||
psl->SetWorkingDirectory(pszExePath);
|
psl->SetWorkingDirectory(pszExePath);
|
||||||
psl->SetShowCmd(SW_SHOWMINNOACTIVE);
|
psl->SetShowCmd(SW_SHOWMINNOACTIVE);
|
||||||
psl->SetArguments(pszArgs);
|
#ifndef UNICODE
|
||||||
|
psl->SetArguments(strArgs.toStdString().c_str());
|
||||||
|
#else
|
||||||
|
psl->SetArguments(args.get());
|
||||||
|
#endif
|
||||||
|
|
||||||
// Query IShellLink for the IPersistFile interface for
|
// Query IShellLink for the IPersistFile interface for
|
||||||
// saving the shortcut in persistent storage.
|
// saving the shortcut in persistent storage.
|
||||||
IPersistFile* ppf = NULL;
|
IPersistFile* ppf = NULL;
|
||||||
hres = psl->QueryInterface(IID_IPersistFile,
|
hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&ppf));
|
||||||
reinterpret_cast<void**>(&ppf));
|
|
||||||
if (SUCCEEDED(hres))
|
if (SUCCEEDED(hres))
|
||||||
{
|
{
|
||||||
WCHAR pwsz[MAX_PATH];
|
WCHAR pwsz[MAX_PATH];
|
||||||
|
@ -630,11 +650,10 @@ bool SetStartOnSystemStartup(bool fAutoStart)
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(Q_OS_LINUX)
|
#elif defined(Q_OS_LINUX)
|
||||||
|
|
||||||
// Follow the Desktop Application Autostart Spec:
|
// Follow the Desktop Application Autostart Spec:
|
||||||
// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
|
// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
|
||||||
|
|
||||||
boost::filesystem::path static GetAutostartDir()
|
boost::filesystem::path static GetAutostartDir()
|
||||||
{
|
{
|
||||||
|
@ -690,8 +709,13 @@ bool SetStartOnSystemStartup(bool fAutoStart)
|
||||||
// Write a bitcoin.desktop file to the autostart directory:
|
// Write a bitcoin.desktop file to the autostart directory:
|
||||||
optionFile << "[Desktop Entry]\n";
|
optionFile << "[Desktop Entry]\n";
|
||||||
optionFile << "Type=Application\n";
|
optionFile << "Type=Application\n";
|
||||||
optionFile << "Name=Bitcoin\n";
|
if (GetBoolArg("-testnet", false))
|
||||||
optionFile << "Exec=" << pszExePath << " -min\n";
|
optionFile << "Name=Bitcoin (testnet)\n";
|
||||||
|
else if (GetBoolArg("-regtest", false))
|
||||||
|
optionFile << "Name=Bitcoin (regtest)\n";
|
||||||
|
else
|
||||||
|
optionFile << "Name=Bitcoin\n";
|
||||||
|
optionFile << "Exec=" << pszExePath << strprintf(" -min -testnet=%d -regtest=%d\n", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false));
|
||||||
optionFile << "Terminal=false\n";
|
optionFile << "Terminal=false\n";
|
||||||
optionFile << "Hidden=false\n";
|
optionFile << "Hidden=false\n";
|
||||||
optionFile.close();
|
optionFile.close();
|
||||||
|
|
|
@ -14,12 +14,6 @@ class QMenu;
|
||||||
class QWidget;
|
class QWidget;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#ifdef __OBJC__
|
|
||||||
@class DockIconClickEventHandler;
|
|
||||||
#else
|
|
||||||
class DockIconClickEventHandler;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Macintosh-specific dock icon handler.
|
/** Macintosh-specific dock icon handler.
|
||||||
*/
|
*/
|
||||||
class MacDockIconHandler : public QObject
|
class MacDockIconHandler : public QObject
|
||||||
|
@ -33,7 +27,7 @@ public:
|
||||||
void setIcon(const QIcon &icon);
|
void setIcon(const QIcon &icon);
|
||||||
void setMainWindow(QMainWindow *window);
|
void setMainWindow(QMainWindow *window);
|
||||||
static MacDockIconHandler *instance();
|
static MacDockIconHandler *instance();
|
||||||
|
static void cleanup();
|
||||||
void handleDockIconClickEvent();
|
void handleDockIconClickEvent();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -42,7 +36,6 @@ signals:
|
||||||
private:
|
private:
|
||||||
MacDockIconHandler();
|
MacDockIconHandler();
|
||||||
|
|
||||||
DockIconClickEventHandler *m_dockIconClickEventHandler;
|
|
||||||
QWidget *m_dummyWidget;
|
QWidget *m_dummyWidget;
|
||||||
QMenu *m_dockMenu;
|
QMenu *m_dockMenu;
|
||||||
QMainWindow *mainWindow;
|
QMainWindow *mainWindow;
|
||||||
|
|
|
@ -11,52 +11,46 @@
|
||||||
|
|
||||||
#undef slots
|
#undef slots
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
|
#include <objc/objc.h>
|
||||||
|
#include <objc/message.h>
|
||||||
|
|
||||||
#if QT_VERSION < 0x050000
|
#if QT_VERSION < 0x050000
|
||||||
extern void qt_mac_set_dock_menu(QMenu *);
|
extern void qt_mac_set_dock_menu(QMenu *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@interface DockIconClickEventHandler : NSObject
|
static MacDockIconHandler *s_instance = NULL;
|
||||||
{
|
|
||||||
MacDockIconHandler* dockIconHandler;
|
bool dockClickHandler(id self,SEL _cmd,...) {
|
||||||
|
Q_UNUSED(self)
|
||||||
|
Q_UNUSED(_cmd)
|
||||||
|
|
||||||
|
s_instance->handleDockIconClickEvent();
|
||||||
|
|
||||||
|
// Return NO (false) to suppress the default OS X actions
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
void setupDockClickHandler() {
|
||||||
|
Class cls = objc_getClass("NSApplication");
|
||||||
|
id appInst = objc_msgSend((id)cls, sel_registerName("sharedApplication"));
|
||||||
|
|
||||||
@implementation DockIconClickEventHandler
|
if (appInst != NULL) {
|
||||||
|
id delegate = objc_msgSend(appInst, sel_registerName("delegate"));
|
||||||
- (id)initWithDockIconHandler:(MacDockIconHandler *)aDockIconHandler
|
Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class"));
|
||||||
{
|
SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
|
||||||
self = [super init];
|
if (class_getInstanceMethod(delClass, shouldHandle))
|
||||||
if (self) {
|
class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:");
|
||||||
dockIconHandler = aDockIconHandler;
|
else
|
||||||
|
class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler,"B@:");
|
||||||
[[NSAppleEventManager sharedAppleEventManager]
|
|
||||||
setEventHandler:self
|
|
||||||
andSelector:@selector(handleDockClickEvent:withReplyEvent:)
|
|
||||||
forEventClass:kCoreEventClass
|
|
||||||
andEventID:kAEReopenApplication];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)handleDockClickEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
|
|
||||||
{
|
|
||||||
Q_UNUSED(event)
|
|
||||||
Q_UNUSED(replyEvent)
|
|
||||||
|
|
||||||
if (dockIconHandler) {
|
|
||||||
dockIconHandler->handleDockIconClickEvent();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
MacDockIconHandler::MacDockIconHandler() : QObject()
|
MacDockIconHandler::MacDockIconHandler() : QObject()
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
this->m_dockIconClickEventHandler = [[DockIconClickEventHandler alloc] initWithDockIconHandler:this];
|
setupDockClickHandler();
|
||||||
this->m_dummyWidget = new QWidget();
|
this->m_dummyWidget = new QWidget();
|
||||||
this->m_dockMenu = new QMenu(this->m_dummyWidget);
|
this->m_dockMenu = new QMenu(this->m_dummyWidget);
|
||||||
this->setMainWindow(NULL);
|
this->setMainWindow(NULL);
|
||||||
|
@ -74,7 +68,6 @@ void MacDockIconHandler::setMainWindow(QMainWindow *window) {
|
||||||
|
|
||||||
MacDockIconHandler::~MacDockIconHandler()
|
MacDockIconHandler::~MacDockIconHandler()
|
||||||
{
|
{
|
||||||
[this->m_dockIconClickEventHandler release];
|
|
||||||
delete this->m_dummyWidget;
|
delete this->m_dummyWidget;
|
||||||
this->setMainWindow(NULL);
|
this->setMainWindow(NULL);
|
||||||
}
|
}
|
||||||
|
@ -119,12 +112,16 @@ void MacDockIconHandler::setIcon(const QIcon &icon)
|
||||||
|
|
||||||
MacDockIconHandler *MacDockIconHandler::instance()
|
MacDockIconHandler *MacDockIconHandler::instance()
|
||||||
{
|
{
|
||||||
static MacDockIconHandler *s_instance = NULL;
|
|
||||||
if (!s_instance)
|
if (!s_instance)
|
||||||
s_instance = new MacDockIconHandler();
|
s_instance = new MacDockIconHandler();
|
||||||
return s_instance;
|
return s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacDockIconHandler::cleanup()
|
||||||
|
{
|
||||||
|
delete s_instance;
|
||||||
|
}
|
||||||
|
|
||||||
void MacDockIconHandler::handleDockIconClickEvent()
|
void MacDockIconHandler::handleDockIconClickEvent()
|
||||||
{
|
{
|
||||||
if (this->mainWindow)
|
if (this->mainWindow)
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include "txdb.h" // for -dbcache defaults
|
#include "txdb.h" // for -dbcache defaults
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
#include "wallet.h" // for CWallet::minTxFee
|
#include "wallet/wallet.h" // for CWallet::minTxFee
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
@ -38,7 +38,6 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
|
||||||
fProxyIpValid(true)
|
fProxyIpValid(true)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
GUIUtil::restoreWindowGeometry("nOptionsDialogWindow", this->size(), this);
|
|
||||||
|
|
||||||
/* Main elements init */
|
/* Main elements init */
|
||||||
ui->databaseCache->setMinimum(nMinDbCache);
|
ui->databaseCache->setMinimum(nMinDbCache);
|
||||||
|
@ -117,7 +116,6 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
|
||||||
|
|
||||||
OptionsDialog::~OptionsDialog()
|
OptionsDialog::~OptionsDialog()
|
||||||
{
|
{
|
||||||
GUIUtil::saveWindowGeometry("nOptionsDialogWindow", this);
|
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
#include "txdb.h" // for -dbcache defaults
|
#include "txdb.h" // for -dbcache defaults
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
#include "walletdb.h"
|
#include "wallet/walletdb.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QNetworkProxy>
|
#include <QNetworkProxy>
|
||||||
|
|
|
@ -10,9 +10,10 @@
|
||||||
|
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "chainparams.h"
|
#include "chainparams.h"
|
||||||
|
#include "main.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
|
@ -293,8 +293,8 @@ void RPCConsole::setClientModel(ClientModel *model)
|
||||||
setNumConnections(model->getNumConnections());
|
setNumConnections(model->getNumConnections());
|
||||||
connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
|
connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
|
||||||
|
|
||||||
setNumBlocks(model->getNumBlocks());
|
setNumBlocks(model->getNumBlocks(), model->getLastBlockDate());
|
||||||
connect(model, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
|
connect(model, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
|
||||||
|
|
||||||
updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent());
|
updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent());
|
||||||
connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64)));
|
connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64)));
|
||||||
|
@ -404,11 +404,10 @@ void RPCConsole::setNumConnections(int count)
|
||||||
ui->numberOfConnections->setText(connections);
|
ui->numberOfConnections->setText(connections);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPCConsole::setNumBlocks(int count)
|
void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate)
|
||||||
{
|
{
|
||||||
ui->numberOfBlocks->setText(QString::number(count));
|
ui->numberOfBlocks->setText(QString::number(count));
|
||||||
if(clientModel)
|
ui->lastBlockTime->setText(blockDate.toString());
|
||||||
ui->lastBlockTime->setText(clientModel->getLastBlockDate().toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPCConsole::on_lineEdit_returnPressed()
|
void RPCConsole::on_lineEdit_returnPressed()
|
||||||
|
|
|
@ -63,8 +63,8 @@ public slots:
|
||||||
void message(int category, const QString &message, bool html = false);
|
void message(int category, const QString &message, bool html = false);
|
||||||
/** Set number of connections shown in the UI */
|
/** Set number of connections shown in the UI */
|
||||||
void setNumConnections(int count);
|
void setNumConnections(int count);
|
||||||
/** Set number of blocks shown in the UI */
|
/** Set number of blocks and last block date shown in the UI */
|
||||||
void setNumBlocks(int count);
|
void setNumBlocks(int count, const QDateTime& blockDate);
|
||||||
/** Go forward or back in history */
|
/** Go forward or back in history */
|
||||||
void browseHistory(int offset);
|
void browseHistory(int offset);
|
||||||
/** Scroll console view to end */
|
/** Scroll console view to end */
|
||||||
|
|
|
@ -17,8 +17,9 @@
|
||||||
|
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "coincontrol.h"
|
#include "coincontrol.h"
|
||||||
|
#include "main.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
|
@ -121,7 +122,7 @@ void SendCoinsDialog::setClientModel(ClientModel *clientModel)
|
||||||
this->clientModel = clientModel;
|
this->clientModel = clientModel;
|
||||||
|
|
||||||
if (clientModel) {
|
if (clientModel) {
|
||||||
connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(updateSmartFeeLabel()));
|
connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(updateSmartFeeLabel()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,9 +221,37 @@ void SendCoinsDialog::on_sendButton_clicked()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fNewRecipientAllowed = false;
|
||||||
|
WalletModel::UnlockContext ctx(model->requestUnlock());
|
||||||
|
if(!ctx.isValid())
|
||||||
|
{
|
||||||
|
// Unlock wallet was cancelled
|
||||||
|
fNewRecipientAllowed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare transaction for getting txFee earlier
|
||||||
|
WalletModelTransaction currentTransaction(recipients);
|
||||||
|
WalletModel::SendCoinsReturn prepareStatus;
|
||||||
|
if (model->getOptionsModel()->getCoinControlFeatures()) // coin control enabled
|
||||||
|
prepareStatus = model->prepareTransaction(currentTransaction, CoinControlDialog::coinControl);
|
||||||
|
else
|
||||||
|
prepareStatus = model->prepareTransaction(currentTransaction);
|
||||||
|
|
||||||
|
// process prepareStatus and on error generate message shown to user
|
||||||
|
processSendCoinsReturn(prepareStatus,
|
||||||
|
BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee()));
|
||||||
|
|
||||||
|
if(prepareStatus.status != WalletModel::OK) {
|
||||||
|
fNewRecipientAllowed = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAmount txFee = currentTransaction.getTransactionFee();
|
||||||
|
|
||||||
// Format confirmation message
|
// Format confirmation message
|
||||||
QStringList formatted;
|
QStringList formatted;
|
||||||
foreach(const SendCoinsRecipient &rcp, recipients)
|
foreach(const SendCoinsRecipient &rcp, currentTransaction.getRecipients())
|
||||||
{
|
{
|
||||||
// generate bold amount string
|
// generate bold amount string
|
||||||
QString amount = "<b>" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
|
QString amount = "<b>" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
|
||||||
|
@ -257,35 +286,6 @@ void SendCoinsDialog::on_sendButton_clicked()
|
||||||
formatted.append(recipientElement);
|
formatted.append(recipientElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
fNewRecipientAllowed = false;
|
|
||||||
|
|
||||||
|
|
||||||
WalletModel::UnlockContext ctx(model->requestUnlock());
|
|
||||||
if(!ctx.isValid())
|
|
||||||
{
|
|
||||||
// Unlock wallet was cancelled
|
|
||||||
fNewRecipientAllowed = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare transaction for getting txFee earlier
|
|
||||||
WalletModelTransaction currentTransaction(recipients);
|
|
||||||
WalletModel::SendCoinsReturn prepareStatus;
|
|
||||||
if (model->getOptionsModel()->getCoinControlFeatures()) // coin control enabled
|
|
||||||
prepareStatus = model->prepareTransaction(currentTransaction, CoinControlDialog::coinControl);
|
|
||||||
else
|
|
||||||
prepareStatus = model->prepareTransaction(currentTransaction);
|
|
||||||
|
|
||||||
// process prepareStatus and on error generate message shown to user
|
|
||||||
processSendCoinsReturn(prepareStatus,
|
|
||||||
BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee()));
|
|
||||||
|
|
||||||
if(prepareStatus.status != WalletModel::OK) {
|
|
||||||
fNewRecipientAllowed = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CAmount txFee = currentTransaction.getTransactionFee();
|
|
||||||
QString questionString = tr("Are you sure you want to send?");
|
QString questionString = tr("Are you sure you want to send?");
|
||||||
questionString.append("<br /><br />%1");
|
questionString.append("<br /><br />%1");
|
||||||
|
|
||||||
|
@ -368,6 +368,7 @@ SendCoinsEntry *SendCoinsDialog::addEntry()
|
||||||
ui->entries->addWidget(entry);
|
ui->entries->addWidget(entry);
|
||||||
connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*)));
|
connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*)));
|
||||||
connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels()));
|
connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels()));
|
||||||
|
connect(entry, SIGNAL(subtractFeeFromAmountChanged()), this, SLOT(coinControlUpdateLabels()));
|
||||||
|
|
||||||
updateTabsAndLabels();
|
updateTabsAndLabels();
|
||||||
|
|
||||||
|
@ -783,11 +784,17 @@ void SendCoinsDialog::coinControlUpdateLabels()
|
||||||
|
|
||||||
// set pay amounts
|
// set pay amounts
|
||||||
CoinControlDialog::payAmounts.clear();
|
CoinControlDialog::payAmounts.clear();
|
||||||
|
CoinControlDialog::fSubtractFeeFromAmount = false;
|
||||||
for(int i = 0; i < ui->entries->count(); ++i)
|
for(int i = 0; i < ui->entries->count(); ++i)
|
||||||
{
|
{
|
||||||
SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
|
SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
|
||||||
if(entry)
|
if(entry)
|
||||||
CoinControlDialog::payAmounts.append(entry->getValue().amount);
|
{
|
||||||
|
SendCoinsRecipient rcp = entry->getValue();
|
||||||
|
CoinControlDialog::payAmounts.append(rcp.amount);
|
||||||
|
if (rcp.fSubtractFeeFromAmount)
|
||||||
|
CoinControlDialog::fSubtractFeeFromAmount = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CoinControlDialog::coinControl->HasSelected())
|
if (CoinControlDialog::coinControl->HasSelected())
|
||||||
|
|
|
@ -44,6 +44,7 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
|
||||||
|
|
||||||
// Connect signals
|
// Connect signals
|
||||||
connect(ui->payAmount, SIGNAL(valueChanged()), this, SIGNAL(payAmountChanged()));
|
connect(ui->payAmount, SIGNAL(valueChanged()), this, SIGNAL(payAmountChanged()));
|
||||||
|
connect(ui->checkboxSubtractFeeFromAmount, SIGNAL(toggled(bool)), this, SIGNAL(subtractFeeFromAmountChanged()));
|
||||||
connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(deleteClicked()));
|
connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(deleteClicked()));
|
||||||
connect(ui->deleteButton_is, SIGNAL(clicked()), this, SLOT(deleteClicked()));
|
connect(ui->deleteButton_is, SIGNAL(clicked()), this, SLOT(deleteClicked()));
|
||||||
connect(ui->deleteButton_s, SIGNAL(clicked()), this, SLOT(deleteClicked()));
|
connect(ui->deleteButton_s, SIGNAL(clicked()), this, SLOT(deleteClicked()));
|
||||||
|
@ -94,6 +95,7 @@ void SendCoinsEntry::clear()
|
||||||
ui->payTo->clear();
|
ui->payTo->clear();
|
||||||
ui->addAsLabel->clear();
|
ui->addAsLabel->clear();
|
||||||
ui->payAmount->clear();
|
ui->payAmount->clear();
|
||||||
|
ui->checkboxSubtractFeeFromAmount->setCheckState(Qt::Unchecked);
|
||||||
ui->messageTextLabel->clear();
|
ui->messageTextLabel->clear();
|
||||||
ui->messageTextLabel->hide();
|
ui->messageTextLabel->hide();
|
||||||
ui->messageLabel->hide();
|
ui->messageLabel->hide();
|
||||||
|
@ -165,6 +167,7 @@ SendCoinsRecipient SendCoinsEntry::getValue()
|
||||||
recipient.label = ui->addAsLabel->text();
|
recipient.label = ui->addAsLabel->text();
|
||||||
recipient.amount = ui->payAmount->value();
|
recipient.amount = ui->payAmount->value();
|
||||||
recipient.message = ui->messageTextLabel->text();
|
recipient.message = ui->messageTextLabel->text();
|
||||||
|
recipient.fSubtractFeeFromAmount = (ui->checkboxSubtractFeeFromAmount->checkState() == Qt::Checked);
|
||||||
|
|
||||||
return recipient;
|
return recipient;
|
||||||
}
|
}
|
||||||
|
@ -174,7 +177,8 @@ QWidget *SendCoinsEntry::setupTabChain(QWidget *prev)
|
||||||
QWidget::setTabOrder(prev, ui->payTo);
|
QWidget::setTabOrder(prev, ui->payTo);
|
||||||
QWidget::setTabOrder(ui->payTo, ui->addAsLabel);
|
QWidget::setTabOrder(ui->payTo, ui->addAsLabel);
|
||||||
QWidget *w = ui->payAmount->setupTabChain(ui->addAsLabel);
|
QWidget *w = ui->payAmount->setupTabChain(ui->addAsLabel);
|
||||||
QWidget::setTabOrder(w, ui->addressBookButton);
|
QWidget::setTabOrder(w, ui->checkboxSubtractFeeFromAmount);
|
||||||
|
QWidget::setTabOrder(ui->checkboxSubtractFeeFromAmount, ui->addressBookButton);
|
||||||
QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton);
|
QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton);
|
||||||
QWidget::setTabOrder(ui->pasteButton, ui->deleteButton);
|
QWidget::setTabOrder(ui->pasteButton, ui->deleteButton);
|
||||||
return ui->deleteButton;
|
return ui->deleteButton;
|
||||||
|
|
|
@ -51,6 +51,7 @@ public slots:
|
||||||
signals:
|
signals:
|
||||||
void removeEntry(SendCoinsEntry *entry);
|
void removeEntry(SendCoinsEntry *entry);
|
||||||
void payAmountChanged();
|
void payAmountChanged();
|
||||||
|
void subtractFeeFromAmountChanged();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void deleteClicked();
|
void deleteClicked();
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
|
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "wallet.h"
|
#include "main.h" // For strMessageMagic
|
||||||
|
#include "wallet/wallet.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
|
@ -10,13 +10,13 @@
|
||||||
#include "transactionrecord.h"
|
#include "transactionrecord.h"
|
||||||
|
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "db.h"
|
#include "wallet/db.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "script/script.h"
|
#include "script/script.h"
|
||||||
#include "timedata.h"
|
#include "timedata.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
@ -5,11 +5,14 @@
|
||||||
#include "transactionrecord.h"
|
#include "transactionrecord.h"
|
||||||
|
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
|
#include "main.h"
|
||||||
#include "timedata.h"
|
#include "timedata.h"
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
/* Return positive answer if transaction should be shown in list.
|
/* Return positive answer if transaction should be shown in list.
|
||||||
*/
|
*/
|
||||||
bool TransactionRecord::showTransaction(const CWalletTx &wtx)
|
bool TransactionRecord::showTransaction(const CWalletTx &wtx)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
|
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
|
@ -29,7 +29,6 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
|
||||||
ui(new Ui::HelpMessageDialog)
|
ui(new Ui::HelpMessageDialog)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
GUIUtil::restoreWindowGeometry("nHelpMessageDialogWindow", this->size(), this);
|
|
||||||
|
|
||||||
QString version = tr("Bitcoin Core") + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion());
|
QString version = tr("Bitcoin Core") + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion());
|
||||||
/* On x86 add a bit specifier to the version so that users can distinguish between
|
/* On x86 add a bit specifier to the version so that users can distinguish between
|
||||||
|
@ -63,13 +62,17 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
|
||||||
ui->helpMessage->setVisible(false);
|
ui->helpMessage->setVisible(false);
|
||||||
} else {
|
} else {
|
||||||
setWindowTitle(tr("Command-line options"));
|
setWindowTitle(tr("Command-line options"));
|
||||||
|
QString header = tr("Usage:") + "\n" +
|
||||||
|
" bitcoin-qt [" + tr("command-line options") + "] " + "\n";
|
||||||
QTextCursor cursor(ui->helpMessage->document());
|
QTextCursor cursor(ui->helpMessage->document());
|
||||||
cursor.insertText(version);
|
cursor.insertText(version);
|
||||||
cursor.insertBlock();
|
cursor.insertBlock();
|
||||||
cursor.insertText(tr("Usage:") + '\n' +
|
cursor.insertText(header);
|
||||||
" bitcoin-qt [" + tr("command-line options") + "]\n");
|
|
||||||
|
|
||||||
cursor.insertBlock();
|
cursor.insertBlock();
|
||||||
|
|
||||||
|
QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT));
|
||||||
|
text = version + "\n" + header + "\n" + coreOptions;
|
||||||
|
|
||||||
QTextTableFormat tf;
|
QTextTableFormat tf;
|
||||||
tf.setBorderStyle(QTextFrameFormat::BorderStyle_None);
|
tf.setBorderStyle(QTextFrameFormat::BorderStyle_None);
|
||||||
tf.setCellPadding(2);
|
tf.setCellPadding(2);
|
||||||
|
@ -77,64 +80,30 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
|
||||||
widths << QTextLength(QTextLength::PercentageLength, 35);
|
widths << QTextLength(QTextLength::PercentageLength, 35);
|
||||||
widths << QTextLength(QTextLength::PercentageLength, 65);
|
widths << QTextLength(QTextLength::PercentageLength, 65);
|
||||||
tf.setColumnWidthConstraints(widths);
|
tf.setColumnWidthConstraints(widths);
|
||||||
QTextTable *table = cursor.insertTable(2, 2, tf);
|
|
||||||
|
|
||||||
QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT));
|
|
||||||
bool first = true;
|
|
||||||
QTextCharFormat bold;
|
QTextCharFormat bold;
|
||||||
bold.setFontWeight(QFont::Bold);
|
bold.setFontWeight(QFont::Bold);
|
||||||
// note that coreOptions is not translated.
|
|
||||||
foreach (const QString &line, coreOptions.split('\n')) {
|
foreach (const QString &line, coreOptions.split("\n")) {
|
||||||
if (!first) {
|
if (line.startsWith(" -"))
|
||||||
table->appendRows(1);
|
{
|
||||||
|
cursor.currentTable()->appendRows(1);
|
||||||
|
cursor.movePosition(QTextCursor::PreviousCell);
|
||||||
cursor.movePosition(QTextCursor::NextRow);
|
cursor.movePosition(QTextCursor::NextRow);
|
||||||
|
cursor.insertText(line.trimmed());
|
||||||
|
cursor.movePosition(QTextCursor::NextCell);
|
||||||
|
} else if (line.startsWith(" ")) {
|
||||||
|
cursor.insertText(line.trimmed()+' ');
|
||||||
|
} else if (line.size() > 0) {
|
||||||
|
//Title of a group
|
||||||
|
if (cursor.currentTable())
|
||||||
|
cursor.currentTable()->appendRows(1);
|
||||||
|
cursor.movePosition(QTextCursor::Down);
|
||||||
|
cursor.insertText(line.trimmed(), bold);
|
||||||
|
cursor.insertTable(1, 2, tf);
|
||||||
}
|
}
|
||||||
first = false;
|
|
||||||
|
|
||||||
if (line.startsWith(" ")) {
|
|
||||||
int index = line.indexOf(' ', 3);
|
|
||||||
if (index > 0) {
|
|
||||||
cursor.insertText(line.left(index).trimmed());
|
|
||||||
cursor.movePosition(QTextCursor::NextCell);
|
|
||||||
cursor.insertText(line.mid(index).trimmed());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cursor.movePosition(QTextCursor::NextCell, QTextCursor::KeepAnchor);
|
|
||||||
table->mergeCells(cursor);
|
|
||||||
cursor.insertText(line.trimmed(), bold);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table->appendRows(6);
|
|
||||||
cursor.movePosition(QTextCursor::NextRow);
|
|
||||||
cursor.insertText(tr("UI options") + ":", bold);
|
|
||||||
cursor.movePosition(QTextCursor::NextRow);
|
|
||||||
if (GetBoolArg("-help-debug", false)) {
|
|
||||||
cursor.insertText("-allowselfsignedrootcertificates");
|
|
||||||
cursor.movePosition(QTextCursor::NextCell);
|
|
||||||
cursor.insertText(tr("Allow self signed root certificates (default: 0)"));
|
|
||||||
cursor.movePosition(QTextCursor::NextCell);
|
|
||||||
}
|
|
||||||
cursor.insertText("-choosedatadir");
|
|
||||||
cursor.movePosition(QTextCursor::NextCell);
|
|
||||||
cursor.insertText(tr("Choose data directory on startup (default: 0)"));
|
|
||||||
cursor.movePosition(QTextCursor::NextCell);
|
|
||||||
cursor.insertText("-lang=<lang>");
|
|
||||||
cursor.movePosition(QTextCursor::NextCell);
|
|
||||||
cursor.insertText(tr("Set language, for example \"de_DE\" (default: system locale)"));
|
|
||||||
cursor.movePosition(QTextCursor::NextCell);
|
|
||||||
cursor.insertText("-min");
|
|
||||||
cursor.movePosition(QTextCursor::NextCell);
|
|
||||||
cursor.insertText(tr("Start minimized"));
|
|
||||||
cursor.movePosition(QTextCursor::NextCell);
|
|
||||||
cursor.insertText("-rootcertificates=<file>");
|
|
||||||
cursor.movePosition(QTextCursor::NextCell);
|
|
||||||
cursor.insertText(tr("Set SSL root certificates for payment request (default: -system-)"));
|
|
||||||
cursor.movePosition(QTextCursor::NextCell);
|
|
||||||
cursor.insertText("-splash");
|
|
||||||
cursor.movePosition(QTextCursor::NextCell);
|
|
||||||
cursor.insertText(tr("Show splash screen on startup (default: 1)"));
|
|
||||||
|
|
||||||
ui->helpMessage->moveCursor(QTextCursor::Start);
|
ui->helpMessage->moveCursor(QTextCursor::Start);
|
||||||
ui->scrollArea->setVisible(false);
|
ui->scrollArea->setVisible(false);
|
||||||
ui->aboutLogo->setVisible(false);
|
ui->aboutLogo->setVisible(false);
|
||||||
|
@ -143,7 +112,6 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
|
||||||
|
|
||||||
HelpMessageDialog::~HelpMessageDialog()
|
HelpMessageDialog::~HelpMessageDialog()
|
||||||
{
|
{
|
||||||
GUIUtil::saveWindowGeometry("nHelpMessageDialogWindow", this);
|
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,18 +6,19 @@
|
||||||
|
|
||||||
#include "addresstablemodel.h"
|
#include "addresstablemodel.h"
|
||||||
#include "guiconstants.h"
|
#include "guiconstants.h"
|
||||||
|
#include "guiutil.h"
|
||||||
#include "paymentserver.h"
|
#include "paymentserver.h"
|
||||||
#include "recentrequeststablemodel.h"
|
#include "recentrequeststablemodel.h"
|
||||||
#include "transactiontablemodel.h"
|
#include "transactiontablemodel.h"
|
||||||
|
|
||||||
#include "base58.h"
|
#include "base58.h"
|
||||||
#include "db.h"
|
#include "wallet/db.h"
|
||||||
#include "keystore.h"
|
#include "keystore.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
#include "walletdb.h" // for BackupWallet
|
#include "wallet/walletdb.h" // for BackupWallet
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
@ -192,8 +193,9 @@ bool WalletModel::validateAddress(const QString &address)
|
||||||
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl)
|
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl)
|
||||||
{
|
{
|
||||||
CAmount total = 0;
|
CAmount total = 0;
|
||||||
|
bool fSubtractFeeFromAmount = false;
|
||||||
QList<SendCoinsRecipient> recipients = transaction.getRecipients();
|
QList<SendCoinsRecipient> recipients = transaction.getRecipients();
|
||||||
std::vector<std::pair<CScript, CAmount> > vecSend;
|
std::vector<CRecipient> vecSend;
|
||||||
|
|
||||||
if(recipients.empty())
|
if(recipients.empty())
|
||||||
{
|
{
|
||||||
|
@ -206,6 +208,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
||||||
// Pre-check input data for validity
|
// Pre-check input data for validity
|
||||||
foreach(const SendCoinsRecipient &rcp, recipients)
|
foreach(const SendCoinsRecipient &rcp, recipients)
|
||||||
{
|
{
|
||||||
|
if (rcp.fSubtractFeeFromAmount)
|
||||||
|
fSubtractFeeFromAmount = true;
|
||||||
|
|
||||||
if (rcp.paymentRequest.IsInitialized())
|
if (rcp.paymentRequest.IsInitialized())
|
||||||
{ // PaymentRequest...
|
{ // PaymentRequest...
|
||||||
CAmount subtotal = 0;
|
CAmount subtotal = 0;
|
||||||
|
@ -217,7 +222,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
||||||
subtotal += out.amount();
|
subtotal += out.amount();
|
||||||
const unsigned char* scriptStr = (const unsigned char*)out.script().data();
|
const unsigned char* scriptStr = (const unsigned char*)out.script().data();
|
||||||
CScript scriptPubKey(scriptStr, scriptStr+out.script().size());
|
CScript scriptPubKey(scriptStr, scriptStr+out.script().size());
|
||||||
vecSend.push_back(std::pair<CScript, CAmount>(scriptPubKey, out.amount()));
|
CAmount nAmount = out.amount();
|
||||||
|
CRecipient recipient = {scriptPubKey, nAmount, rcp.fSubtractFeeFromAmount};
|
||||||
|
vecSend.push_back(recipient);
|
||||||
}
|
}
|
||||||
if (subtotal <= 0)
|
if (subtotal <= 0)
|
||||||
{
|
{
|
||||||
|
@ -239,7 +246,8 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
||||||
++nAddresses;
|
++nAddresses;
|
||||||
|
|
||||||
CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
|
CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
|
||||||
vecSend.push_back(std::pair<CScript, CAmount>(scriptPubKey, rcp.amount));
|
CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount};
|
||||||
|
vecSend.push_back(recipient);
|
||||||
|
|
||||||
total += rcp.amount;
|
total += rcp.amount;
|
||||||
}
|
}
|
||||||
|
@ -260,17 +268,21 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
||||||
LOCK2(cs_main, wallet->cs_wallet);
|
LOCK2(cs_main, wallet->cs_wallet);
|
||||||
|
|
||||||
transaction.newPossibleKeyChange(wallet);
|
transaction.newPossibleKeyChange(wallet);
|
||||||
|
|
||||||
CAmount nFeeRequired = 0;
|
CAmount nFeeRequired = 0;
|
||||||
|
int nChangePosRet = -1;
|
||||||
std::string strFailReason;
|
std::string strFailReason;
|
||||||
|
|
||||||
CWalletTx *newTx = transaction.getTransaction();
|
CWalletTx *newTx = transaction.getTransaction();
|
||||||
CReserveKey *keyChange = transaction.getPossibleKeyChange();
|
CReserveKey *keyChange = transaction.getPossibleKeyChange();
|
||||||
bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, strFailReason, coinControl);
|
bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
|
||||||
transaction.setTransactionFee(nFeeRequired);
|
transaction.setTransactionFee(nFeeRequired);
|
||||||
|
if (fSubtractFeeFromAmount && fCreated)
|
||||||
|
transaction.reassignAmounts(nChangePosRet);
|
||||||
|
|
||||||
if(!fCreated)
|
if(!fCreated)
|
||||||
{
|
{
|
||||||
if((total + nFeeRequired) > nBalance)
|
if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance)
|
||||||
{
|
{
|
||||||
return SendCoinsReturn(AmountWithFeeExceedsBalance);
|
return SendCoinsReturn(AmountWithFeeExceedsBalance);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "paymentrequestplus.h"
|
#include "paymentrequestplus.h"
|
||||||
#include "walletmodeltransaction.h"
|
#include "walletmodeltransaction.h"
|
||||||
|
|
||||||
#include "allocators.h" /* for SecureString */
|
#include "support/allocators/secure.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -36,9 +36,9 @@ QT_END_NAMESPACE
|
||||||
class SendCoinsRecipient
|
class SendCoinsRecipient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SendCoinsRecipient() : amount(0), nVersion(SendCoinsRecipient::CURRENT_VERSION) { }
|
explicit SendCoinsRecipient() : amount(0), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) { }
|
||||||
explicit SendCoinsRecipient(const QString &addr, const QString &label, const CAmount& amount, const QString &message):
|
explicit SendCoinsRecipient(const QString &addr, const QString &label, const CAmount& amount, const QString &message):
|
||||||
address(addr), label(label), amount(amount), message(message), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
|
address(addr), label(label), amount(amount), message(message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
|
||||||
|
|
||||||
// If from an unauthenticated payment request, this is used for storing
|
// If from an unauthenticated payment request, this is used for storing
|
||||||
// the addresses, e.g. address-A<br />address-B<br />address-C.
|
// the addresses, e.g. address-A<br />address-B<br />address-C.
|
||||||
|
@ -56,6 +56,8 @@ public:
|
||||||
// Empty if no authentication or invalid signature/cert/etc.
|
// Empty if no authentication or invalid signature/cert/etc.
|
||||||
QString authenticatedMerchant;
|
QString authenticatedMerchant;
|
||||||
|
|
||||||
|
bool fSubtractFeeFromAmount; // memory only
|
||||||
|
|
||||||
static const int CURRENT_VERSION = 1;
|
static const int CURRENT_VERSION = 1;
|
||||||
int nVersion;
|
int nVersion;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include "walletmodeltransaction.h"
|
#include "walletmodeltransaction.h"
|
||||||
|
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
|
|
||||||
WalletModelTransaction::WalletModelTransaction(const QList<SendCoinsRecipient> &recipients) :
|
WalletModelTransaction::WalletModelTransaction(const QList<SendCoinsRecipient> &recipients) :
|
||||||
recipients(recipients),
|
recipients(recipients),
|
||||||
|
@ -46,6 +46,38 @@ void WalletModelTransaction::setTransactionFee(const CAmount& newFee)
|
||||||
fee = newFee;
|
fee = newFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WalletModelTransaction::reassignAmounts(int nChangePosRet)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
for (QList<SendCoinsRecipient>::iterator it = recipients.begin(); it != recipients.end(); ++it)
|
||||||
|
{
|
||||||
|
SendCoinsRecipient& rcp = (*it);
|
||||||
|
|
||||||
|
if (rcp.paymentRequest.IsInitialized())
|
||||||
|
{
|
||||||
|
CAmount subtotal = 0;
|
||||||
|
const payments::PaymentDetails& details = rcp.paymentRequest.getDetails();
|
||||||
|
for (int j = 0; j < details.outputs_size(); j++)
|
||||||
|
{
|
||||||
|
const payments::Output& out = details.outputs(j);
|
||||||
|
if (out.amount() <= 0) continue;
|
||||||
|
if (i == nChangePosRet)
|
||||||
|
i++;
|
||||||
|
subtotal += walletTransaction->vout[i].nValue;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
rcp.amount = subtotal;
|
||||||
|
}
|
||||||
|
else // normal recipient (no payment request)
|
||||||
|
{
|
||||||
|
if (i == nChangePosRet)
|
||||||
|
i++;
|
||||||
|
rcp.amount = walletTransaction->vout[i].nValue;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CAmount WalletModelTransaction::getTotalTransactionAmount()
|
CAmount WalletModelTransaction::getTotalTransactionAmount()
|
||||||
{
|
{
|
||||||
CAmount totalTransactionAmount = 0;
|
CAmount totalTransactionAmount = 0;
|
||||||
|
|
|
@ -35,8 +35,10 @@ public:
|
||||||
void newPossibleKeyChange(CWallet *wallet);
|
void newPossibleKeyChange(CWallet *wallet);
|
||||||
CReserveKey *getPossibleKeyChange();
|
CReserveKey *getPossibleKeyChange();
|
||||||
|
|
||||||
|
void reassignAmounts(int nChangePosRet); // needed for the subtract-fee-from-amount feature
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QList<SendCoinsRecipient> recipients;
|
QList<SendCoinsRecipient> recipients;
|
||||||
CWalletTx *walletTransaction;
|
CWalletTx *walletTransaction;
|
||||||
CReserveKey *keyChange;
|
CReserveKey *keyChange;
|
||||||
CAmount fee;
|
CAmount fee;
|
||||||
|
|
|
@ -47,15 +47,16 @@ void RandAddSeedPerfmon()
|
||||||
{
|
{
|
||||||
RandAddSeed();
|
RandAddSeed();
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
// Don't need this on Linux, OpenSSL automatically uses /dev/urandom
|
||||||
|
// Seed with the entire set of perfmon data
|
||||||
|
|
||||||
// This can take up to 2 seconds, so only do it every 10 minutes
|
// This can take up to 2 seconds, so only do it every 10 minutes
|
||||||
static int64_t nLastPerfmon;
|
static int64_t nLastPerfmon;
|
||||||
if (GetTime() < nLastPerfmon + 10 * 60)
|
if (GetTime() < nLastPerfmon + 10 * 60)
|
||||||
return;
|
return;
|
||||||
nLastPerfmon = GetTime();
|
nLastPerfmon = GetTime();
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
// Don't need this on Linux, OpenSSL automatically uses /dev/urandom
|
|
||||||
// Seed with the entire set of perfmon data
|
|
||||||
std::vector<unsigned char> vData(250000, 0);
|
std::vector<unsigned char> vData(250000, 0);
|
||||||
long ret = 0;
|
long ret = 0;
|
||||||
unsigned long nSize = 0;
|
unsigned long nSize = 0;
|
||||||
|
|
|
@ -32,6 +32,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||||
{ "getnetworkhashps", 0 },
|
{ "getnetworkhashps", 0 },
|
||||||
{ "getnetworkhashps", 1 },
|
{ "getnetworkhashps", 1 },
|
||||||
{ "sendtoaddress", 1 },
|
{ "sendtoaddress", 1 },
|
||||||
|
{ "sendtoaddress", 4 },
|
||||||
{ "settxfee", 0 },
|
{ "settxfee", 0 },
|
||||||
{ "getreceivedbyaddress", 1 },
|
{ "getreceivedbyaddress", 1 },
|
||||||
{ "getreceivedbyaccount", 1 },
|
{ "getreceivedbyaccount", 1 },
|
||||||
|
@ -59,6 +60,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||||
{ "listsinceblock", 2 },
|
{ "listsinceblock", 2 },
|
||||||
{ "sendmany", 1 },
|
{ "sendmany", 1 },
|
||||||
{ "sendmany", 2 },
|
{ "sendmany", 2 },
|
||||||
|
{ "sendmany", 4 },
|
||||||
{ "addmultisigaddress", 0 },
|
{ "addmultisigaddress", 0 },
|
||||||
{ "addmultisigaddress", 1 },
|
{ "addmultisigaddress", 1 },
|
||||||
{ "createmultisig", 0 },
|
{ "createmultisig", 0 },
|
||||||
|
|
|
@ -13,9 +13,10 @@
|
||||||
#include "pow.h"
|
#include "pow.h"
|
||||||
#include "rpcserver.h"
|
#include "rpcserver.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "validationinterface.h"
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
#include "db.h"
|
#include "wallet/db.h"
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
#include "timedata.h"
|
#include "timedata.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
#include "walletdb.h"
|
#include "wallet/walletdb.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "script/standard.h"
|
#include "script/standard.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "utilstrencodings.h"
|
#include "utilstrencodings.h"
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
#include "wallet.h"
|
#include "wallet/wallet.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "crypto/common.h"
|
||||||
|
|
||||||
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
|
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
|
||||||
|
|
||||||
|
@ -417,14 +418,16 @@ public:
|
||||||
else if (b.size() <= 0xffff)
|
else if (b.size() <= 0xffff)
|
||||||
{
|
{
|
||||||
insert(end(), OP_PUSHDATA2);
|
insert(end(), OP_PUSHDATA2);
|
||||||
unsigned short nSize = b.size();
|
uint8_t data[2];
|
||||||
insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
|
WriteLE16(data, b.size());
|
||||||
|
insert(end(), data, data + sizeof(data));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
insert(end(), OP_PUSHDATA4);
|
insert(end(), OP_PUSHDATA4);
|
||||||
unsigned int nSize = b.size();
|
uint8_t data[4];
|
||||||
insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
|
WriteLE32(data, b.size());
|
||||||
|
insert(end(), data, data + sizeof(data));
|
||||||
}
|
}
|
||||||
insert(end(), b.begin(), b.end());
|
insert(end(), b.begin(), b.end());
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -497,15 +500,14 @@ public:
|
||||||
{
|
{
|
||||||
if (end() - pc < 2)
|
if (end() - pc < 2)
|
||||||
return false;
|
return false;
|
||||||
nSize = 0;
|
nSize = ReadLE16(&pc[0]);
|
||||||
memcpy(&nSize, &pc[0], 2);
|
|
||||||
pc += 2;
|
pc += 2;
|
||||||
}
|
}
|
||||||
else if (opcode == OP_PUSHDATA4)
|
else if (opcode == OP_PUSHDATA4)
|
||||||
{
|
{
|
||||||
if (end() - pc < 4)
|
if (end() - pc < 4)
|
||||||
return false;
|
return false;
|
||||||
memcpy(&nSize, &pc[0], 4);
|
nSize = ReadLE32(&pc[0]);
|
||||||
pc += 4;
|
pc += 4;
|
||||||
}
|
}
|
||||||
if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize)
|
if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize)
|
||||||
|
|
|
@ -17,22 +17,31 @@ using namespace std;
|
||||||
|
|
||||||
typedef vector<unsigned char> valtype;
|
typedef vector<unsigned char> valtype;
|
||||||
|
|
||||||
bool Sign1(const CKeyID& address, const CKeyStore& keystore, uint256 hash, int nHashType, CScript& scriptSigRet)
|
TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), checker(txTo, nIn) {}
|
||||||
|
|
||||||
|
bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode) const
|
||||||
{
|
{
|
||||||
CKey key;
|
CKey key;
|
||||||
if (!keystore.GetKey(address, key))
|
if (!keystore->GetKey(address, key))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
vector<unsigned char> vchSig;
|
uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType);
|
||||||
if (!key.Sign(hash, vchSig))
|
if (!key.Sign(hash, vchSig))
|
||||||
return false;
|
return false;
|
||||||
vchSig.push_back((unsigned char)nHashType);
|
vchSig.push_back((unsigned char)nHashType);
|
||||||
scriptSigRet << vchSig;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SignN(const vector<valtype>& multisigdata, const CKeyStore& keystore, uint256 hash, int nHashType, CScript& scriptSigRet)
|
static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, CScript& scriptSigRet)
|
||||||
|
{
|
||||||
|
vector<unsigned char> vchSig;
|
||||||
|
if (!creator.CreateSig(vchSig, address, scriptCode))
|
||||||
|
return false;
|
||||||
|
scriptSigRet << vchSig;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SignN(const vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, CScript& scriptSigRet)
|
||||||
{
|
{
|
||||||
int nSigned = 0;
|
int nSigned = 0;
|
||||||
int nRequired = multisigdata.front()[0];
|
int nRequired = multisigdata.front()[0];
|
||||||
|
@ -40,20 +49,20 @@ bool SignN(const vector<valtype>& multisigdata, const CKeyStore& keystore, uint2
|
||||||
{
|
{
|
||||||
const valtype& pubkey = multisigdata[i];
|
const valtype& pubkey = multisigdata[i];
|
||||||
CKeyID keyID = CPubKey(pubkey).GetID();
|
CKeyID keyID = CPubKey(pubkey).GetID();
|
||||||
if (Sign1(keyID, keystore, hash, nHashType, scriptSigRet))
|
if (Sign1(keyID, creator, scriptCode, scriptSigRet))
|
||||||
++nSigned;
|
++nSigned;
|
||||||
}
|
}
|
||||||
return nSigned==nRequired;
|
return nSigned==nRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign scriptPubKey with private keys stored in keystore, given transaction hash and hash type.
|
* Sign scriptPubKey using signature made with creator.
|
||||||
* Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
|
* Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
|
||||||
* unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
|
* unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
|
||||||
* Returns false if scriptPubKey could not be completely satisfied.
|
* Returns false if scriptPubKey could not be completely satisfied.
|
||||||
*/
|
*/
|
||||||
bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash, int nHashType,
|
static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey,
|
||||||
CScript& scriptSigRet, txnouttype& whichTypeRet)
|
CScript& scriptSigRet, txnouttype& whichTypeRet)
|
||||||
{
|
{
|
||||||
scriptSigRet.clear();
|
scriptSigRet.clear();
|
||||||
|
|
||||||
|
@ -71,39 +80,32 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
|
||||||
return false;
|
return false;
|
||||||
case TX_PUBKEY:
|
case TX_PUBKEY:
|
||||||
keyID = CPubKey(vSolutions[0]).GetID();
|
keyID = CPubKey(vSolutions[0]).GetID();
|
||||||
return Sign1(keyID, keystore, hash, nHashType, scriptSigRet);
|
return Sign1(keyID, creator, scriptPubKey, scriptSigRet);
|
||||||
case TX_PUBKEYHASH:
|
case TX_PUBKEYHASH:
|
||||||
keyID = CKeyID(uint160(vSolutions[0]));
|
keyID = CKeyID(uint160(vSolutions[0]));
|
||||||
if (!Sign1(keyID, keystore, hash, nHashType, scriptSigRet))
|
if (!Sign1(keyID, creator, scriptPubKey, scriptSigRet))
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CPubKey vch;
|
CPubKey vch;
|
||||||
keystore.GetPubKey(keyID, vch);
|
creator.KeyStore().GetPubKey(keyID, vch);
|
||||||
scriptSigRet << ToByteVector(vch);
|
scriptSigRet << ToByteVector(vch);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case TX_SCRIPTHASH:
|
case TX_SCRIPTHASH:
|
||||||
return keystore.GetCScript(uint160(vSolutions[0]), scriptSigRet);
|
return creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptSigRet);
|
||||||
|
|
||||||
case TX_MULTISIG:
|
case TX_MULTISIG:
|
||||||
scriptSigRet << OP_0; // workaround CHECKMULTISIG bug
|
scriptSigRet << OP_0; // workaround CHECKMULTISIG bug
|
||||||
return (SignN(vSolutions, keystore, hash, nHashType, scriptSigRet));
|
return (SignN(vSolutions, creator, scriptPubKey, scriptSigRet));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
|
bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, CScript& scriptSig)
|
||||||
{
|
{
|
||||||
assert(nIn < txTo.vin.size());
|
|
||||||
CTxIn& txin = txTo.vin[nIn];
|
|
||||||
|
|
||||||
// Leave out the signature from the hash, since a signature can't sign itself.
|
|
||||||
// The checksig op will also drop the signatures from its hash.
|
|
||||||
uint256 hash = SignatureHash(fromPubKey, txTo, nIn, nHashType);
|
|
||||||
|
|
||||||
txnouttype whichType;
|
txnouttype whichType;
|
||||||
if (!Solver(keystore, fromPubKey, hash, nHashType, txin.scriptSig, whichType))
|
if (!SignStep(creator, fromPubKey, scriptSig, whichType))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (whichType == TX_SCRIPTHASH)
|
if (whichType == TX_SCRIPTHASH)
|
||||||
|
@ -111,21 +113,29 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutabl
|
||||||
// Solver returns the subscript that need to be evaluated;
|
// Solver returns the subscript that need to be evaluated;
|
||||||
// the final scriptSig is the signatures from that
|
// the final scriptSig is the signatures from that
|
||||||
// and then the serialized subscript:
|
// and then the serialized subscript:
|
||||||
CScript subscript = txin.scriptSig;
|
CScript subscript = scriptSig;
|
||||||
|
|
||||||
// Recompute txn hash using subscript in place of scriptPubKey:
|
|
||||||
uint256 hash2 = SignatureHash(subscript, txTo, nIn, nHashType);
|
|
||||||
|
|
||||||
txnouttype subType;
|
txnouttype subType;
|
||||||
bool fSolved =
|
bool fSolved =
|
||||||
Solver(keystore, subscript, hash2, nHashType, txin.scriptSig, subType) && subType != TX_SCRIPTHASH;
|
SignStep(creator, subscript, scriptSig, subType) && subType != TX_SCRIPTHASH;
|
||||||
// Append serialized subscript whether or not it is completely signed:
|
// Append serialized subscript whether or not it is completely signed:
|
||||||
txin.scriptSig << static_cast<valtype>(subscript);
|
scriptSig << static_cast<valtype>(subscript);
|
||||||
if (!fSolved) return false;
|
if (!fSolved) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test solution
|
// Test solution
|
||||||
return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&txTo, nIn));
|
return VerifyScript(scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
|
||||||
|
{
|
||||||
|
assert(nIn < txTo.vin.size());
|
||||||
|
CTxIn& txin = txTo.vin[nIn];
|
||||||
|
|
||||||
|
CTransaction txToConst(txTo);
|
||||||
|
TransactionSignatureCreator creator(&keystore, &txToConst, nIn, nHashType);
|
||||||
|
|
||||||
|
return ProduceSignature(creator, fromPubKey, txin.scriptSig);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
|
bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
|
||||||
|
@ -146,7 +156,7 @@ static CScript PushAll(const vector<valtype>& values)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
|
static CScript CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
|
||||||
const vector<valtype>& vSolutions,
|
const vector<valtype>& vSolutions,
|
||||||
const vector<valtype>& sigs1, const vector<valtype>& sigs2)
|
const vector<valtype>& sigs1, const vector<valtype>& sigs2)
|
||||||
{
|
{
|
||||||
|
@ -176,7 +186,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction&
|
||||||
if (sigs.count(pubkey))
|
if (sigs.count(pubkey))
|
||||||
continue; // Already got a sig for this pubkey
|
continue; // Already got a sig for this pubkey
|
||||||
|
|
||||||
if (TransactionSignatureChecker(&txTo, nIn).CheckSig(sig, pubkey, scriptPubKey))
|
if (checker.CheckSig(sig, pubkey, scriptPubKey))
|
||||||
{
|
{
|
||||||
sigs[pubkey] = sig;
|
sigs[pubkey] = sig;
|
||||||
break;
|
break;
|
||||||
|
@ -201,7 +211,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction&
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
|
static CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
|
||||||
const txnouttype txType, const vector<valtype>& vSolutions,
|
const txnouttype txType, const vector<valtype>& vSolutions,
|
||||||
vector<valtype>& sigs1, vector<valtype>& sigs2)
|
vector<valtype>& sigs1, vector<valtype>& sigs2)
|
||||||
{
|
{
|
||||||
|
@ -235,12 +245,12 @@ static CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction
|
||||||
Solver(pubKey2, txType2, vSolutions2);
|
Solver(pubKey2, txType2, vSolutions2);
|
||||||
sigs1.pop_back();
|
sigs1.pop_back();
|
||||||
sigs2.pop_back();
|
sigs2.pop_back();
|
||||||
CScript result = CombineSignatures(pubKey2, txTo, nIn, txType2, vSolutions2, sigs1, sigs2);
|
CScript result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2);
|
||||||
result << spk;
|
result << spk;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
case TX_MULTISIG:
|
case TX_MULTISIG:
|
||||||
return CombineMultisig(scriptPubKey, txTo, nIn, vSolutions, sigs1, sigs2);
|
return CombineMultisig(scriptPubKey, checker, vSolutions, sigs1, sigs2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CScript();
|
return CScript();
|
||||||
|
@ -248,6 +258,13 @@ static CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction
|
||||||
|
|
||||||
CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
|
CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
|
||||||
const CScript& scriptSig1, const CScript& scriptSig2)
|
const CScript& scriptSig1, const CScript& scriptSig2)
|
||||||
|
{
|
||||||
|
TransactionSignatureChecker checker(&txTo, nIn);
|
||||||
|
return CombineSignatures(scriptPubKey, checker, scriptSig1, scriptSig2);
|
||||||
|
}
|
||||||
|
|
||||||
|
CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
|
||||||
|
const CScript& scriptSig1, const CScript& scriptSig2)
|
||||||
{
|
{
|
||||||
txnouttype txType;
|
txnouttype txType;
|
||||||
vector<vector<unsigned char> > vSolutions;
|
vector<vector<unsigned char> > vSolutions;
|
||||||
|
@ -258,5 +275,5 @@ CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo,
|
||||||
vector<valtype> stack2;
|
vector<valtype> stack2;
|
||||||
EvalScript(stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker());
|
EvalScript(stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker());
|
||||||
|
|
||||||
return CombineSignatures(scriptPubKey, txTo, nIn, txType, vSolutions, stack1, stack2);
|
return CombineSignatures(scriptPubKey, checker, txType, vSolutions, stack1, stack2);
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue