merge bitcoin changes
This commit is contained in:
commit
361c99b104
171 changed files with 2633 additions and 1514 deletions
25
.travis.yml
25
.travis.yml
|
@ -10,6 +10,7 @@ env:
|
|||
global:
|
||||
- MAKEJOBS=-j3
|
||||
- RUN_TESTS=false
|
||||
- BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID
|
||||
- CCACHE_SIZE=100M
|
||||
- CCACHE_TEMPDIR=/tmp/.ccache-temp
|
||||
- CCACHE_COMPRESS=1
|
||||
|
@ -25,19 +26,19 @@ matrix:
|
|||
fast_finish: true
|
||||
include:
|
||||
- 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"
|
||||
- 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"
|
||||
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: ": 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:
|
||||
- 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
|
||||
|
|
55
configure.ac
55
configure.ac
|
@ -115,9 +115,9 @@ AC_ARG_ENABLE([hardening],
|
|||
|
||||
AC_ARG_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=auto])
|
||||
[use_reduce_exports=no])
|
||||
|
||||
AC_ARG_ENABLE([ccache],
|
||||
[AS_HELP_STRING([--enable-ccache],
|
||||
|
@ -133,7 +133,7 @@ AC_ARG_ENABLE([lcov],
|
|||
|
||||
AC_ARG_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=no])
|
||||
|
||||
|
@ -350,8 +350,8 @@ if test x$use_lcov = xyes; then
|
|||
[AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")])
|
||||
fi
|
||||
|
||||
dnl Require little endian
|
||||
AC_C_BIGENDIAN([AC_MSG_ERROR("Big Endian not supported")])
|
||||
dnl Check for endianness
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
dnl Check for pthread compile/link requirements
|
||||
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"])
|
||||
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([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([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
|
||||
#include <endian.h>
|
||||
#endif])
|
||||
|
||||
AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,,
|
||||
[#if HAVE_BYTESWAP_H
|
||||
#include <byteswap.h>
|
||||
#endif])
|
||||
|
||||
dnl Check for MSG_NOSIGNAL
|
||||
AC_MSG_CHECKING(for MSG_NOSIGNAL)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]],
|
||||
|
@ -471,22 +476,14 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([
|
|||
[
|
||||
AC_MSG_RESULT(no)
|
||||
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
|
||||
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"],
|
||||
[
|
||||
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
|
||||
])
|
||||
[AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])])
|
||||
fi
|
||||
|
||||
LEVELDB_CPPFLAGS=
|
||||
|
@ -533,7 +530,7 @@ AX_BOOST_THREAD
|
|||
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])
|
||||
TEMP_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS"
|
||||
|
@ -547,25 +544,14 @@ if test x$use_reduce_exports != xno; then
|
|||
#endif
|
||||
]])],[
|
||||
AC_MSG_RESULT(yes)
|
||||
],[:
|
||||
if test x$use_reduce_exports = xauto; then
|
||||
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.])
|
||||
],[
|
||||
AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduce-exports.])
|
||||
])
|
||||
CPPFLAGS="$TEMP_CPPFLAGS"
|
||||
fi
|
||||
|
||||
elif test x$use_reduce_exports = xauto; then
|
||||
use_reduce_exports=yes
|
||||
fi
|
||||
|
||||
if test x$use_reduce_exports != xno; then
|
||||
if test x$use_reduce_exports = xyes; then
|
||||
CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS"
|
||||
AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"])
|
||||
fi
|
||||
|
@ -827,7 +813,7 @@ else
|
|||
fi
|
||||
|
||||
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])
|
||||
else
|
||||
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_REORG_TESTS],[test x$use_comparison_tool_reorg_test != xno])
|
||||
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_MINOR, _CLIENT_VERSION_MINOR, [Minor version])
|
||||
|
|
|
@ -16,6 +16,9 @@ Repository Tools
|
|||
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.
|
||||
|
||||
### [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) ###
|
||||
Construct a linear, no-fork, best version of the blockchain.
|
||||
|
||||
|
|
|
@ -20,9 +20,9 @@ if cmd == "backupwallet":
|
|||
try:
|
||||
path = raw_input("Enter destination path/filename: ")
|
||||
print access.backupwallet(path)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "encryptwallet":
|
||||
try:
|
||||
pwd = getpass.getpass(prompt="Enter passphrase: ")
|
||||
|
@ -32,29 +32,29 @@ elif cmd == "encryptwallet":
|
|||
print "\n---Wallet encrypted. Server stopping, restart to run with encrypted wallet---\n"
|
||||
else:
|
||||
print "\n---Passphrases do not match---\n"
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getaccount":
|
||||
try:
|
||||
addr = raw_input("Enter a Bitcoin address: ")
|
||||
print access.getaccount(addr)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getaccountaddress":
|
||||
try:
|
||||
acct = raw_input("Enter an account name: ")
|
||||
print access.getaccountaddress(acct)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getaddressesbyaccount":
|
||||
try:
|
||||
acct = raw_input("Enter an account name: ")
|
||||
print access.getaddressesbyaccount(acct)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getbalance":
|
||||
try:
|
||||
|
@ -64,57 +64,57 @@ elif cmd == "getbalance":
|
|||
print access.getbalance(acct, mc)
|
||||
except:
|
||||
print access.getbalance()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getblockbycount":
|
||||
try:
|
||||
height = raw_input("Height: ")
|
||||
print access.getblockbycount(height)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getblockcount":
|
||||
try:
|
||||
print access.getblockcount()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getblocknumber":
|
||||
try:
|
||||
print access.getblocknumber()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getconnectioncount":
|
||||
try:
|
||||
print access.getconnectioncount()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getdifficulty":
|
||||
try:
|
||||
print access.getdifficulty()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getgenerate":
|
||||
try:
|
||||
print access.getgenerate()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "gethashespersec":
|
||||
try:
|
||||
print access.gethashespersec()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getinfo":
|
||||
try:
|
||||
print access.getinfo()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getnewaddress":
|
||||
try:
|
||||
|
@ -123,8 +123,8 @@ elif cmd == "getnewaddress":
|
|||
print access.getnewaddress(acct)
|
||||
except:
|
||||
print access.getnewaddress()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getreceivedbyaccount":
|
||||
try:
|
||||
|
@ -134,8 +134,8 @@ elif cmd == "getreceivedbyaccount":
|
|||
print access.getreceivedbyaccount(acct, mc)
|
||||
except:
|
||||
print access.getreceivedbyaccount()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getreceivedbyaddress":
|
||||
try:
|
||||
|
@ -145,15 +145,15 @@ elif cmd == "getreceivedbyaddress":
|
|||
print access.getreceivedbyaddress(addr, mc)
|
||||
except:
|
||||
print access.getreceivedbyaddress()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "gettransaction":
|
||||
try:
|
||||
txid = raw_input("Enter a transaction ID: ")
|
||||
print access.gettransaction(txid)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "getwork":
|
||||
try:
|
||||
|
@ -162,8 +162,8 @@ elif cmd == "getwork":
|
|||
print access.gettransaction(data)
|
||||
except:
|
||||
print access.gettransaction()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "help":
|
||||
try:
|
||||
|
@ -172,8 +172,8 @@ elif cmd == "help":
|
|||
print access.help(cmd)
|
||||
except:
|
||||
print access.help()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "listaccounts":
|
||||
try:
|
||||
|
@ -182,8 +182,8 @@ elif cmd == "listaccounts":
|
|||
print access.listaccounts(mc)
|
||||
except:
|
||||
print access.listaccounts()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "listreceivedbyaccount":
|
||||
try:
|
||||
|
@ -193,8 +193,8 @@ elif cmd == "listreceivedbyaccount":
|
|||
print access.listreceivedbyaccount(mc, incemp)
|
||||
except:
|
||||
print access.listreceivedbyaccount()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "listreceivedbyaddress":
|
||||
try:
|
||||
|
@ -204,8 +204,8 @@ elif cmd == "listreceivedbyaddress":
|
|||
print access.listreceivedbyaddress(mc, incemp)
|
||||
except:
|
||||
print access.listreceivedbyaddress()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "listtransactions":
|
||||
try:
|
||||
|
@ -216,8 +216,8 @@ elif cmd == "listtransactions":
|
|||
print access.listtransactions(acct, count, frm)
|
||||
except:
|
||||
print access.listtransactions()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "move":
|
||||
try:
|
||||
|
@ -230,8 +230,8 @@ elif cmd == "move":
|
|||
print access.move(frm, to, amt, mc, comment)
|
||||
except:
|
||||
print access.move(frm, to, amt)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "sendfrom":
|
||||
try:
|
||||
|
@ -245,8 +245,8 @@ elif cmd == "sendfrom":
|
|||
print access.sendfrom(frm, to, amt, mc, comment, commentto)
|
||||
except:
|
||||
print access.sendfrom(frm, to, amt)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "sendmany":
|
||||
try:
|
||||
|
@ -258,8 +258,8 @@ elif cmd == "sendmany":
|
|||
print access.sendmany(frm,to,mc,comment)
|
||||
except:
|
||||
print access.sendmany(frm,to)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "sendtoaddress":
|
||||
try:
|
||||
|
@ -271,16 +271,16 @@ elif cmd == "sendtoaddress":
|
|||
print access.sendtoaddress(to,amt,comment,commentto)
|
||||
except:
|
||||
print access.sendtoaddress(to,amt)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "setaccount":
|
||||
try:
|
||||
addr = raw_input("Address: ")
|
||||
acct = raw_input("Account:")
|
||||
print access.setaccount(addr,acct)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "setgenerate":
|
||||
try:
|
||||
|
@ -290,36 +290,36 @@ elif cmd == "setgenerate":
|
|||
print access.setgenerate(gen, cpus)
|
||||
except:
|
||||
print access.setgenerate(gen)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "settxfee":
|
||||
try:
|
||||
amt = raw_input("Amount:")
|
||||
print access.settxfee(amt)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "stop":
|
||||
try:
|
||||
print access.stop()
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "validateaddress":
|
||||
try:
|
||||
addr = raw_input("Address: ")
|
||||
print access.validateaddress(addr)
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "walletpassphrase":
|
||||
try:
|
||||
pwd = getpass.getpass(prompt="Enter wallet passphrase: ")
|
||||
access.walletpassphrase(pwd, 60)
|
||||
print "\n---Wallet unlocked---\n"
|
||||
except:
|
||||
print "\n---An error occurred---\n"
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
elif cmd == "walletpassphrasechange":
|
||||
try:
|
||||
|
@ -328,10 +328,8 @@ elif cmd == "walletpassphrasechange":
|
|||
access.walletpassphrasechange(pwd, pwd2)
|
||||
print
|
||||
print "\n---Passphrase changed---\n"
|
||||
except:
|
||||
print
|
||||
print "\n---An error occurred---\n"
|
||||
print
|
||||
except Exception as inst:
|
||||
print inst
|
||||
|
||||
else:
|
||||
print "Command not found or not supported"
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
debian/manpages/bitcoind.1
|
||||
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"
|
||||
- "bsdmainutils"
|
||||
- "binutils-gold"
|
||||
- "libstdc++6-4.6-pic"
|
||||
reference_datetime: "2013-06-01 00:00:00"
|
||||
remotes:
|
||||
- "url": "https://github.com/bitcoin/bitcoin.git"
|
||||
|
@ -23,7 +24,7 @@ files: []
|
|||
script: |
|
||||
WRAP_DIR=$HOME/wrapped
|
||||
HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu"
|
||||
CONFIGFLAGS="--enable-upnp-default --enable-glibc-back-compat"
|
||||
CONFIGFLAGS="--enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++"
|
||||
FAKETIME_HOST_PROGS=""
|
||||
FAKETIME_PROGS="date ar ranlib nm strip"
|
||||
|
||||
|
@ -69,6 +70,14 @@ script: |
|
|||
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
|
||||
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
|
||||
./autogen.sh
|
||||
./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
|
||||
|
|
|
@ -27,7 +27,7 @@ files:
|
|||
script: |
|
||||
WRAP_DIR=$HOME/wrapped
|
||||
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_PROGS="ar ranlib date dmg genisoimage"
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ files: []
|
|||
script: |
|
||||
WRAP_DIR=$HOME/wrapped
|
||||
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_PROGS="date makensis zip"
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ SystemD: bitcoind.service
|
|||
Upstart: bitcoind.conf
|
||||
OpenRC: bitcoind.openrc
|
||||
bitcoind.openrcconf
|
||||
CentOS: bitcoind.init
|
||||
|
||||
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_PIDFILE=${BITCOIND_PIDFILE:-${BITCOIND_PIDDIR}/bitcoind.pid}
|
||||
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_BIN=${BITCOIND_BIN:-/usr/bin/bitcoind}
|
||||
BITCOIND_NICE=${BITCOIND_NICE:-${NICELEVEL:-0}}
|
||||
BITCOIND_OPTS="${BITCOIND_OPTS:-${BITCOIN_OPTS}}"
|
||||
|
||||
name="Bitcoin Core Daemon"
|
||||
description="Bitcoin crypto-currency p2p network daemon"
|
||||
|
@ -28,7 +30,7 @@ command_args="-pid=\"${BITCOIND_PIDFILE}\" \
|
|||
|
||||
required_files="${BITCOIND_CONFIGFILE}"
|
||||
start_stop_daemon_args="-u ${BITCOIND_USER} \
|
||||
-N ${BITCOIND_NICE:-0} -w 2000"
|
||||
-N ${BITCOIND_NICE} -w 2000"
|
||||
pidfile="${BITCOIND_PIDFILE}"
|
||||
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_WALLET ?=
|
||||
NO_UPNP ?=
|
||||
USE_LINUX_STATIC_QT5 ?=
|
||||
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
|
||||
|
||||
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_UPNP: Don't download/build/cache packages needed for enabling upnp
|
||||
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
|
||||
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
|
||||
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
|
||||
$($(package)_autoconf)
|
||||
$($(package)_autoconf) --includedir=$(host_prefix)/include/xcb-shared
|
||||
endef
|
||||
|
||||
define $(package)_build_cmds
|
||||
|
|
|
@ -4,15 +4,10 @@ native_packages := native_ccache native_comparisontool
|
|||
qt_native_packages = native_protobuf
|
||||
qt_packages = qrencode protobuf
|
||||
|
||||
qt46_linux_packages = qt46 expat dbus libxcb xcb_proto libXau xproto freetype libX11 xextproto libXext xtrans libICE libSM
|
||||
qt5_linux_packages= qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans
|
||||
|
||||
qt_linux_packages= qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans
|
||||
qt_darwin_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
|
||||
|
||||
|
|
|
@ -1,21 +1,31 @@
|
|||
--- old/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2014-07-30 18:17:27.384458441 -0400
|
||||
+++ new/qtbase/src/plugins/platforms/xcb/xcb-plugin.pro 2014-07-30 18:18:28.620459303 -0400
|
||||
@@ -101,10 +101,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
-DEFINES += $$QMAKE_DEFINES_XCB
|
||||
-LIBS += $$QMAKE_LIBS_XCB
|
||||
--- 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 2015-03-17 02:08:41.281926351 +0000
|
||||
@@ -103,7 +103,6 @@
|
||||
|
||||
DEFINES += $$QMAKE_DEFINES_XCB
|
||||
LIBS += $$QMAKE_LIBS_XCB
|
||||
-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
|
||||
-
|
||||
|
||||
CONFIG += qpa/genericunixfontdatabase
|
||||
|
||||
contains(QT_CONFIG, dbus) {
|
||||
@@ -141,3 +137,7 @@
|
||||
INCLUDEPATH += ../../../3rdparty/xkbcommon/xkbcommon/
|
||||
}
|
||||
}
|
||||
+
|
||||
+DEFINES += $$QMAKE_DEFINES_XCB
|
||||
+LIBS += $$QMAKE_LIBS_XCB
|
||||
+INCLUDEPATH += $$QMAKE_CFLAGS_XCB
|
||||
|
||||
@@ -118,7 +117,8 @@
|
||||
contains(QT_CONFIG, xcb-qt) {
|
||||
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
|
||||
+ QMAKE_CXXFLAGS += -I$$XCB_DIR/include -I$$XCB_DIR/sysinclude $$QMAKE_CFLAGS_XCB
|
||||
LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static
|
||||
} 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.openrcconf: OpenRC conf.d file
|
||||
contrib/init/bitcoind.conf: Upstart service configuration file
|
||||
contrib/init/bitcoind.init: CentOS compatible SysV style init script
|
||||
|
||||
1. Service User
|
||||
---------------------------------
|
||||
|
@ -49,6 +50,7 @@ Configuration file: /etc/bitcoin/bitcoin.conf
|
|||
Data directory: /var/lib/bitcoind
|
||||
PID file: /var/run/bitcoind/bitcoind.pid (OpenRC and Upstart)
|
||||
/var/lib/bitcoind/bitcoind.pid (systemd)
|
||||
Lock file: /var/lock/subsys/bitcoind (CentOS)
|
||||
|
||||
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
|
||||
|
@ -81,7 +83,15 @@ Drop bitcoind.conf in /etc/init. Test by running "service bitcoind start"
|
|||
it will automatically start on reboot.
|
||||
|
||||
NOTE: This script is incompatible with CentOS 5 and Amazon Linux 2014 as they
|
||||
use old versions of Upstart and do not supply the start-stop-daemon uitility.
|
||||
use old versions of Upstart and do not supply the start-stop-daemon utility.
|
||||
|
||||
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
|
||||
-----------------------------------
|
||||
|
|
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("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__':
|
||||
WalletTest ().main ()
|
||||
|
|
|
@ -72,7 +72,6 @@ endif
|
|||
BITCOIN_CORE_H = \
|
||||
addrman.h \
|
||||
alert.h \
|
||||
allocators.h \
|
||||
amount.h \
|
||||
arith_uint256.h \
|
||||
base58.h \
|
||||
|
@ -89,8 +88,7 @@ BITCOIN_CORE_H = \
|
|||
compat.h \
|
||||
compressor.h \
|
||||
core_io.h \
|
||||
crypter.h \
|
||||
db.h \
|
||||
wallet/db.h \
|
||||
eccryptoverify.h \
|
||||
ecwrapper.h \
|
||||
hash.h \
|
||||
|
@ -125,7 +123,10 @@ BITCOIN_CORE_H = \
|
|||
script/standard.h \
|
||||
serialize.h \
|
||||
streams.h \
|
||||
support/allocators/secure.h \
|
||||
support/allocators/zeroafterfree.h \
|
||||
support/cleanse.h \
|
||||
support/pagelocker.h \
|
||||
sync.h \
|
||||
threadsafety.h \
|
||||
timedata.h \
|
||||
|
@ -139,10 +140,14 @@ BITCOIN_CORE_H = \
|
|||
utilmoneystr.h \
|
||||
utilstrencodings.h \
|
||||
utiltime.h \
|
||||
validationinterface.h \
|
||||
version.h \
|
||||
walletdb.h \
|
||||
wallet.h \
|
||||
wallet_ismine.h \
|
||||
wallet/crypter.h \
|
||||
wallet/walletdb.h \
|
||||
wallet/wallet.h \
|
||||
wallet/wallet_ismine.h \
|
||||
compat/byteswap.h \
|
||||
compat/endian.h \
|
||||
compat/sanity.h
|
||||
|
||||
JSON_H = \
|
||||
|
@ -191,6 +196,7 @@ libbitcoin_server_a_SOURCES = \
|
|||
timedata.cpp \
|
||||
txdb.cpp \
|
||||
txmempool.cpp \
|
||||
validationinterface.cpp \
|
||||
$(JSON_H) \
|
||||
$(BITCOIN_CORE_H)
|
||||
|
||||
|
@ -198,13 +204,13 @@ libbitcoin_server_a_SOURCES = \
|
|||
# when wallet enabled
|
||||
libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
||||
libbitcoin_wallet_a_SOURCES = \
|
||||
db.cpp \
|
||||
crypter.cpp \
|
||||
rpcdump.cpp \
|
||||
rpcwallet.cpp \
|
||||
wallet.cpp \
|
||||
wallet_ismine.cpp \
|
||||
walletdb.cpp \
|
||||
wallet/crypter.cpp \
|
||||
wallet/db.cpp \
|
||||
wallet/rpcdump.cpp \
|
||||
wallet/rpcwallet.cpp \
|
||||
wallet/wallet.cpp \
|
||||
wallet/wallet_ismine.cpp \
|
||||
wallet/walletdb.cpp \
|
||||
$(BITCOIN_CORE_H)
|
||||
|
||||
# crypto primitives library
|
||||
|
@ -235,7 +241,6 @@ univalue_libbitcoin_univalue_a_SOURCES = \
|
|||
# common: shared between bitcoind, and bitcoin-qt and non-server tools
|
||||
libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
||||
libbitcoin_common_a_SOURCES = \
|
||||
allocators.cpp \
|
||||
arith_uint256.cpp \
|
||||
amount.cpp \
|
||||
base58.cpp \
|
||||
|
@ -267,6 +272,7 @@ libbitcoin_common_a_SOURCES = \
|
|||
# backward-compatibility objects and their sanity checks are linked.
|
||||
libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES)
|
||||
libbitcoin_util_a_SOURCES = \
|
||||
support/pagelocker.cpp \
|
||||
chainparamsbase.cpp \
|
||||
clientversion.cpp \
|
||||
compat/glibc_sanity.cpp \
|
||||
|
@ -285,7 +291,6 @@ libbitcoin_util_a_SOURCES = \
|
|||
|
||||
if GLIBC_BACK_COMPAT
|
||||
libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
|
||||
libbitcoin_util_a_SOURCES += compat/glibcxx_compat.cpp
|
||||
endif
|
||||
|
||||
# cli: shared between bitcoin-cli and bitcoin-qt
|
||||
|
@ -377,16 +382,12 @@ libbitcoinconsensus_la_SOURCES = \
|
|||
|
||||
if GLIBC_BACK_COMPAT
|
||||
libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp
|
||||
libbitcoinconsensus_la_SOURCES += compat/glibcxx_compat.cpp
|
||||
endif
|
||||
|
||||
libbitcoinconsensus_la_LDFLAGS = -no-undefined $(RELDFLAGS)
|
||||
libbitcoinconsensus_la_LIBADD = $(CRYPTO_LIBS)
|
||||
libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BITCOIN_INTERNAL
|
||||
|
||||
if USE_LIBSECP256K1
|
||||
libbitcoinconsensus_la_LIBADD += secp256k1/libsecp256k1.la
|
||||
endif
|
||||
endif
|
||||
#
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ BITCOIN_TESTS =\
|
|||
test/ncctrie_tests.cpp \
|
||||
test/netbase_tests.cpp \
|
||||
test/pmt_tests.cpp \
|
||||
test/pow_tests.cpp \
|
||||
test/rpc_tests.cpp \
|
||||
test/sanity_tests.cpp \
|
||||
test/script_P2SH_tests.cpp \
|
||||
|
@ -66,6 +67,7 @@ BITCOIN_TESTS =\
|
|||
test/sigopcount_tests.cpp \
|
||||
test/skiplist_tests.cpp \
|
||||
test/test_bitcoin.cpp \
|
||||
test/test_bitcoin.h \
|
||||
test/timedata_tests.cpp \
|
||||
test/transaction_tests.cpp \
|
||||
test/uint256_tests.cpp \
|
||||
|
@ -75,7 +77,7 @@ BITCOIN_TESTS =\
|
|||
if ENABLE_WALLET
|
||||
BITCOIN_TESTS += \
|
||||
test/accounting_tests.cpp \
|
||||
test/wallet_tests.cpp \
|
||||
wallet/test/wallet_tests.cpp \
|
||||
test/rpc_wallet_tests.cpp
|
||||
endif
|
||||
|
||||
|
|
|
@ -272,8 +272,9 @@ void CAddrMan::Good_(const CService& addr, int64_t nTime)
|
|||
// update info
|
||||
info.nLastSuccess = nTime;
|
||||
info.nLastTry = nTime;
|
||||
info.nTime = nTime;
|
||||
info.nAttempts = 0;
|
||||
// nTime is not updated here, to avoid leaking information about
|
||||
// currently-connected peers.
|
||||
|
||||
// if it is already in the tried set, don't do anything else
|
||||
if (info.fInTried)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "uint256.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "crypto/common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -246,14 +247,14 @@ uint32_t arith_uint256::GetCompact(bool fNegative) const
|
|||
uint256 ArithToUint256(const arith_uint256 &a)
|
||||
{
|
||||
uint256 b;
|
||||
// TODO: needs bswap32 on big-endian
|
||||
memcpy(b.begin(), a.pn, a.size());
|
||||
for(int x=0; x<a.WIDTH; ++x)
|
||||
WriteLE32(b.begin() + x*4, a.pn[x]);
|
||||
return b;
|
||||
}
|
||||
arith_uint256 UintToArith256(const uint256 &a)
|
||||
{
|
||||
arith_uint256 b;
|
||||
// TODO: needs bswap32 on big-endian
|
||||
memcpy(b.pn, a.begin(), a.size());
|
||||
for(int x=0; x<b.WIDTH; ++x)
|
||||
b.pn[x] = ReadLE32(a.begin() + x*4);
|
||||
return b;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "pubkey.h"
|
||||
#include "script/script.h"
|
||||
#include "script/standard.h"
|
||||
#include "support/allocators/zeroafterfree.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
|
|
@ -20,21 +20,21 @@ using namespace json_spirit;
|
|||
std::string HelpMessageCli()
|
||||
{
|
||||
string strUsage;
|
||||
strUsage += _("Options:") + "\n";
|
||||
strUsage += " -? " + _("This help message") + "\n";
|
||||
strUsage += " -conf=<file> " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n";
|
||||
strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
|
||||
strUsage += " -testnet " + _("Use the test network") + "\n";
|
||||
strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be "
|
||||
"solved instantly. This is intended for regression testing tools and app development.") + "\n";
|
||||
strUsage += " -rpcconnect=<ip> " + strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1") + "\n";
|
||||
strUsage += " -rpcport=<port> " + strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n";
|
||||
strUsage += " -rpcwait " + _("Wait for RPC server to start") + "\n";
|
||||
strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
|
||||
strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
|
||||
strUsage += HelpMessageGroup(_("Options:"));
|
||||
strUsage += HelpMessageOpt("-?", _("This help message"));
|
||||
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
|
||||
strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
|
||||
strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
|
||||
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."));
|
||||
strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1"));
|
||||
strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8332, 18332));
|
||||
strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start"));
|
||||
strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
|
||||
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
|
||||
|
||||
strUsage += "\n" + _("SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
|
||||
strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
|
||||
strUsage += HelpMessageGroup(_("SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
|
||||
strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
|
||||
|
||||
return strUsage;
|
||||
}
|
||||
|
|
|
@ -54,38 +54,34 @@ static bool AppInitRawTx(int argc, char* argv[])
|
|||
|
||||
fprintf(stdout, "%s", strUsage.c_str());
|
||||
|
||||
strUsage = _("Options:") + "\n";
|
||||
strUsage += " -? " + _("This help message") + "\n";
|
||||
strUsage += " -create " + _("Create new, empty TX.") + "\n";
|
||||
strUsage += " -json " + _("Select JSON output") + "\n";
|
||||
strUsage += " -txid " + _("Output only the hex-encoded transaction id of the resultant transaction.") + "\n";
|
||||
strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n";
|
||||
strUsage += " -testnet " + _("Use the test network") + "\n";
|
||||
strUsage += "\n";
|
||||
strUsage = HelpMessageGroup(_("Options:"));
|
||||
strUsage += HelpMessageOpt("-?", _("This help message"));
|
||||
strUsage += HelpMessageOpt("-create", _("Create new, empty TX."));
|
||||
strUsage += HelpMessageOpt("-json", _("Select JSON output"));
|
||||
strUsage += HelpMessageOpt("-txid", _("Output only the hex-encoded transaction id of the resultant transaction."));
|
||||
strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly."));
|
||||
strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
|
||||
|
||||
fprintf(stdout, "%s", strUsage.c_str());
|
||||
|
||||
|
||||
strUsage = _("Commands:") + "\n";
|
||||
strUsage += " delin=N " + _("Delete input N from TX") + "\n";
|
||||
strUsage += " delout=N " + _("Delete output N from TX") + "\n";
|
||||
strUsage += " in=TXID:VOUT " + _("Add input to TX") + "\n";
|
||||
strUsage += " locktime=N " + _("Set TX lock time to N") + "\n";
|
||||
strUsage += " nversion=N " + _("Set TX version to N") + "\n";
|
||||
strUsage += " outaddr=VALUE:ADDRESS " + _("Add address-based output to TX") + "\n";
|
||||
strUsage += " outscript=VALUE:SCRIPT " + _("Add raw script output to TX") + "\n";
|
||||
strUsage += " sign=SIGHASH-FLAGS " + _("Add zero or more signatures to transaction") + "\n";
|
||||
strUsage += " This command requires JSON registers:\n";
|
||||
strUsage += " prevtxs=JSON object\n";
|
||||
strUsage += " privatekeys=JSON object\n";
|
||||
strUsage += " See signrawtransaction docs for format of sighash flags, JSON objects.\n";
|
||||
strUsage += "\n";
|
||||
strUsage = HelpMessageGroup(_("Commands:"));
|
||||
strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX"));
|
||||
strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX"));
|
||||
strUsage += HelpMessageOpt("in=TXID:VOUT", _("Add input to TX"));
|
||||
strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N"));
|
||||
strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N"));
|
||||
strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX"));
|
||||
strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX"));
|
||||
strUsage += HelpMessageOpt("sign=SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " +
|
||||
_("This command requires JSON registers:") +
|
||||
_("prevtxs=JSON object") + ", " +
|
||||
_("privatekeys=JSON object") + ". " +
|
||||
_("See signrawtransaction docs for format of sighash flags, JSON objects."));
|
||||
fprintf(stdout, "%s", strUsage.c_str());
|
||||
|
||||
strUsage = _("Register Commands:") + "\n";
|
||||
strUsage += " load=NAME:FILENAME " + _("Load JSON file FILENAME into register NAME") + "\n";
|
||||
strUsage += " set=NAME:JSON-STRING " + _("Set register NAME to given JSON-STRING") + "\n";
|
||||
strUsage += "\n";
|
||||
strUsage = HelpMessageGroup(_("Register Commands:"));
|
||||
strUsage += HelpMessageOpt("load=NAME:FILENAME", _("Load JSON file FILENAME into register NAME"));
|
||||
strUsage += HelpMessageOpt("set=NAME:JSON-STRING", _("Set register NAME to given JSON-STRING"));
|
||||
fprintf(stdout, "%s", strUsage.c_str());
|
||||
|
||||
return false;
|
||||
|
|
|
@ -200,7 +200,6 @@ public:
|
|||
fAllowMinDifficultyBlocks = false;
|
||||
fRequireStandard = true;
|
||||
fMineBlocksOnDemand = false;
|
||||
fSkipProofOfWorkCheck = false;
|
||||
fTestnetToBeDeprecatedFieldRPC = false;
|
||||
}
|
||||
|
||||
|
@ -311,51 +310,8 @@ public:
|
|||
};
|
||||
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;
|
||||
|
||||
CModifiableParams *ModifiableParams()
|
||||
{
|
||||
assert(pCurrentParams);
|
||||
assert(pCurrentParams==&unitTestParams);
|
||||
return (CModifiableParams*)&unitTestParams;
|
||||
}
|
||||
|
||||
const CChainParams &Params() {
|
||||
assert(pCurrentParams);
|
||||
return *pCurrentParams;
|
||||
|
@ -369,8 +325,6 @@ CChainParams &Params(CBaseChainParams::Network network) {
|
|||
return testNetParams;
|
||||
case CBaseChainParams::REGTEST:
|
||||
return regTestParams;
|
||||
case CBaseChainParams::UNITTEST:
|
||||
return unitTestParams;
|
||||
default:
|
||||
assert(false && "Unimplemented network");
|
||||
return mainParams;
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
|
||||
|
||||
struct CDNSSeedData {
|
||||
std::string name, host;
|
||||
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 MessageStartChars& MessageStart() const { return pchMessageStart; }
|
||||
const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; }
|
||||
const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
|
||||
int GetDefaultPort() const { return nDefaultPort; }
|
||||
const arith_uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
|
||||
|
@ -62,8 +60,6 @@ public:
|
|||
bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; }
|
||||
/** Allow mining of a min-difficulty block */
|
||||
bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; }
|
||||
/** Skip proof-of-work check: allow mining of any difficulty block */
|
||||
bool SkipProofOfWorkCheck() const { return fSkipProofOfWorkCheck; }
|
||||
/** Make standard checks */
|
||||
bool RequireStandard() const { return fRequireStandard; }
|
||||
int64_t TargetTimespan() const { return nTargetTimespan; }
|
||||
|
@ -83,7 +79,7 @@ protected:
|
|||
CChainParams() {}
|
||||
|
||||
uint256 hashGenesisBlock;
|
||||
MessageStartChars pchMessageStart;
|
||||
CMessageHeader::MessageStartChars pchMessageStart;
|
||||
//! Raw pub key bytes for the broadcast alert signing key.
|
||||
std::vector<unsigned char> vAlertPubKey;
|
||||
int nDefaultPort;
|
||||
|
@ -106,29 +102,9 @@ protected:
|
|||
bool fAllowMinDifficultyBlocks;
|
||||
bool fRequireStandard;
|
||||
bool fMineBlocksOnDemand;
|
||||
bool fSkipProofOfWorkCheck;
|
||||
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
|
||||
* outside of the unit tests.
|
||||
|
@ -138,9 +114,6 @@ const CChainParams &Params();
|
|||
/** Return parameters for the given 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. */
|
||||
void SelectParams(CBaseChainParams::Network network);
|
||||
|
||||
|
|
|
@ -82,9 +82,6 @@ void SelectBaseParams(CBaseChainParams::Network network)
|
|||
case CBaseChainParams::REGTEST:
|
||||
pCurrentBaseParams = ®TestParams;
|
||||
break;
|
||||
case CBaseChainParams::UNITTEST:
|
||||
pCurrentBaseParams = &unitTestParams;
|
||||
break;
|
||||
default:
|
||||
assert(false && "Unimplemented network");
|
||||
return;
|
||||
|
|
|
@ -19,7 +19,6 @@ public:
|
|||
MAIN,
|
||||
TESTNET,
|
||||
REGTEST,
|
||||
UNITTEST,
|
||||
|
||||
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>
|
||||
|
||||
#if defined(HAVE_ENDIAN_H)
|
||||
#include <endian.h>
|
||||
#endif
|
||||
#include "compat/endian.h"
|
||||
|
||||
uint16_t static inline ReadLE16(const unsigned char* ptr)
|
||||
{
|
||||
return le16toh(*((uint16_t*)ptr));
|
||||
}
|
||||
|
||||
uint32_t static inline ReadLE32(const unsigned char* ptr)
|
||||
{
|
||||
#if HAVE_DECL_LE32TOH == 1
|
||||
return le32toh(*((uint32_t*)ptr));
|
||||
#elif !defined(WORDS_BIGENDIAN)
|
||||
return *((uint32_t*)ptr);
|
||||
#else
|
||||
return ((uint32_t)ptr[3] << 24 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t static inline ReadLE64(const unsigned char* ptr)
|
||||
{
|
||||
#if HAVE_DECL_LE64TOH == 1
|
||||
return le64toh(*((uint64_t*)ptr));
|
||||
#elif !defined(WORDS_BIGENDIAN)
|
||||
return *((uint64_t*)ptr);
|
||||
#else
|
||||
return ((uint64_t)ptr[7] << 56 | (uint64_t)ptr[6] << 48 | (uint64_t)ptr[5] << 40 | (uint64_t)ptr[4] << 32 |
|
||||
(uint64_t)ptr[3] << 24 | (uint64_t)ptr[2] << 16 | (uint64_t)ptr[1] << 8 | (uint64_t)ptr[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void static inline WriteLE16(unsigned char* ptr, uint16_t x)
|
||||
{
|
||||
*((uint16_t*)ptr) = htole16(x);
|
||||
}
|
||||
|
||||
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
|
||||
{
|
||||
#if HAVE_DECL_HTOLE32 == 1
|
||||
*((uint32_t*)ptr) = htole32(x);
|
||||
#elif !defined(WORDS_BIGENDIAN)
|
||||
*((uint32_t*)ptr) = x;
|
||||
#else
|
||||
ptr[3] = x >> 24;
|
||||
ptr[2] = x >> 16;
|
||||
ptr[1] = x >> 8;
|
||||
ptr[0] = x;
|
||||
#endif
|
||||
}
|
||||
|
||||
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
|
||||
{
|
||||
#if HAVE_DECL_HTOLE64 == 1
|
||||
*((uint64_t*)ptr) = htole64(x);
|
||||
#elif !defined(WORDS_BIGENDIAN)
|
||||
*((uint64_t*)ptr) = x;
|
||||
#else
|
||||
ptr[7] = x >> 56;
|
||||
ptr[6] = x >> 48;
|
||||
ptr[5] = x >> 40;
|
||||
ptr[4] = x >> 32;
|
||||
ptr[3] = x >> 24;
|
||||
ptr[2] = x >> 16;
|
||||
ptr[1] = x >> 8;
|
||||
ptr[0] = x;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t static inline ReadBE32(const unsigned char* ptr)
|
||||
{
|
||||
#if HAVE_DECL_BE32TOH == 1
|
||||
return be32toh(*((uint32_t*)ptr));
|
||||
#else
|
||||
return ((uint32_t)ptr[0] << 24 | (uint32_t)ptr[1] << 16 | (uint32_t)ptr[2] << 8 | (uint32_t)ptr[3]);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t static inline ReadBE64(const unsigned char* ptr)
|
||||
{
|
||||
#if HAVE_DECL_BE64TOH == 1
|
||||
return be64toh(*((uint64_t*)ptr));
|
||||
#else
|
||||
return ((uint64_t)ptr[0] << 56 | (uint64_t)ptr[1] << 48 | (uint64_t)ptr[2] << 40 | (uint64_t)ptr[3] << 32 |
|
||||
(uint64_t)ptr[4] << 24 | (uint64_t)ptr[5] << 16 | (uint64_t)ptr[6] << 8 | (uint64_t)ptr[7]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
|
||||
{
|
||||
#if HAVE_DECL_HTOBE32 == 1
|
||||
*((uint32_t*)ptr) = htobe32(x);
|
||||
#else
|
||||
ptr[0] = x >> 24;
|
||||
ptr[1] = x >> 16;
|
||||
ptr[2] = x >> 8;
|
||||
ptr[3] = x;
|
||||
#endif
|
||||
}
|
||||
|
||||
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
|
||||
{
|
||||
#if HAVE_DECL_HTOBE64 == 1
|
||||
*((uint64_t*)ptr) = htobe64(x);
|
||||
#else
|
||||
ptr[0] = x >> 56;
|
||||
ptr[1] = x >> 48;
|
||||
ptr[2] = x >> 40;
|
||||
ptr[3] = x >> 32;
|
||||
ptr[4] = x >> 24;
|
||||
ptr[5] = x >> 16;
|
||||
ptr[6] = x >> 8;
|
||||
ptr[7] = x;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // BITCOIN_CRYPTO_COMMON_H
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "hash.h"
|
||||
#include "crypto/common.h"
|
||||
#include "crypto/hmac_sha512.h"
|
||||
|
||||
|
||||
inline uint32_t ROTL32(uint32_t x, int8_t r)
|
||||
{
|
||||
return (x << r) | (x >> (32 - r));
|
||||
|
@ -23,10 +25,10 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
|
|||
|
||||
//----------
|
||||
// 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++) {
|
||||
uint32_t k1 = blocks[i];
|
||||
uint32_t k1 = ReadLE32(blocks + i*4);
|
||||
|
||||
k1 *= c1;
|
||||
k1 = ROTL32(k1, 15);
|
||||
|
|
307
src/init.cpp
307
src/init.cpp
|
@ -23,10 +23,10 @@
|
|||
#include "ui_interface.h"
|
||||
#include "util.h"
|
||||
#include "utilmoneystr.h"
|
||||
#include "validationinterface.h"
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "db.h"
|
||||
#include "wallet.h"
|
||||
#include "walletdb.h"
|
||||
#include "wallet/wallet.h"
|
||||
#include "wallet/walletdb.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
@ -151,7 +151,7 @@ void Shutdown()
|
|||
StopRPCThreads();
|
||||
#ifdef ENABLE_WALLET
|
||||
if (pwalletMain)
|
||||
bitdb.Flush(false);
|
||||
pwalletMain->Flush(false);
|
||||
GenerateBitcoins(false, NULL, 0);
|
||||
#endif
|
||||
StopNode();
|
||||
|
@ -186,7 +186,7 @@ void Shutdown()
|
|||
}
|
||||
#ifdef ENABLE_WALLET
|
||||
if (pwalletMain)
|
||||
bitdb.Flush(true);
|
||||
pwalletMain->Flush(true);
|
||||
#endif
|
||||
#ifndef WIN32
|
||||
boost::filesystem::remove(GetPidFile());
|
||||
|
@ -258,157 +258,174 @@ void OnRPCPreCommand(const CRPCCommand& cmd)
|
|||
|
||||
std::string HelpMessage(HelpMessageMode mode)
|
||||
{
|
||||
|
||||
// When adding new options to the categories, please keep and ensure alphabetical ordering.
|
||||
string strUsage = _("Options:") + "\n";
|
||||
strUsage += " -? " + _("This help message") + "\n";
|
||||
strUsage += " -alertnotify=<cmd> " + _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)") + "\n";
|
||||
strUsage += " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n";
|
||||
strUsage += " -checkblocks=<n> " + strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288) + "\n";
|
||||
strUsage += " -checklevel=<n> " + strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3) + "\n";
|
||||
strUsage += " -conf=<file> " + strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf") + "\n";
|
||||
string strUsage = HelpMessageGroup(_("Options:"));
|
||||
strUsage += HelpMessageOpt("-?", _("This help message"));
|
||||
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 += HelpMessageOpt("-blocknotify=<cmd>", _("Execute command when the best block changes (%s in cmd is replaced by block hash)"));
|
||||
strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288));
|
||||
strUsage += HelpMessageOpt("-checklevel=<n>", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3));
|
||||
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
|
||||
if (mode == HMM_BITCOIND)
|
||||
{
|
||||
#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
|
||||
}
|
||||
strUsage += " -datadir=<dir> " + _("Specify data directory") + "\n";
|
||||
strUsage += " -dbcache=<n> " + strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache) + "\n";
|
||||
strUsage += " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + " " + _("on startup") + "\n";
|
||||
strUsage += " -maxorphantx=<n> " + strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "\n";
|
||||
strUsage += " -par=<n> " + strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS) + "\n";
|
||||
strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
|
||||
strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache));
|
||||
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup"));
|
||||
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
|
||||
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
|
||||
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
|
||||
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)
|
||||
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
|
||||
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 += " -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n";
|
||||
strUsage += " -banscore=<n> " + strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100) + "\n";
|
||||
strUsage += " -bantime=<n> " + strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400) + "\n";
|
||||
strUsage += " -bind=<addr> " + _("Bind to given address and always listen on it. Use [host]:port notation for IPv6") + "\n";
|
||||
strUsage += " -connect=<ip> " + _("Connect only to the specified node(s)") + "\n";
|
||||
strUsage += " -discover " + _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)") + "\n";
|
||||
strUsage += " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)") + "\n";
|
||||
strUsage += " -dnsseed " + _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)") + "\n";
|
||||
strUsage += " -externalip=<ip> " + _("Specify your own public address") + "\n";
|
||||
strUsage += " -forcednsseed " + strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0) + "\n";
|
||||
strUsage += " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n";
|
||||
strUsage += " -maxconnections=<n> " + strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125) + "\n";
|
||||
strUsage += " -maxreceivebuffer=<n> " + strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000) + "\n";
|
||||
strUsage += " -maxsendbuffer=<n> " + strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000) + "\n";
|
||||
strUsage += " -onion=<ip:port> " + strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy") + "\n";
|
||||
strUsage += " -onlynet=<net> " + _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)") + "\n";
|
||||
strUsage += " -permitbaremultisig " + strprintf(_("Relay non-P2SH multisig (default: %u)"), 1) + "\n";
|
||||
strUsage += " -port=<port> " + strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 8333, 18333) + "\n";
|
||||
strUsage += " -proxy=<ip:port> " + _("Connect through SOCKS5 proxy") + "\n";
|
||||
strUsage += " -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n";
|
||||
strUsage += " -timeout=<n> " + strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT) + "\n";
|
||||
strUsage += HelpMessageGroup(_("Connection options:"));
|
||||
strUsage += HelpMessageOpt("-addnode=<ip>", _("Add a node to connect to and attempt to keep the connection open"));
|
||||
strUsage += HelpMessageOpt("-banscore=<n>", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100));
|
||||
strUsage += HelpMessageOpt("-bantime=<n>", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400));
|
||||
strUsage += HelpMessageOpt("-bind=<addr>", _("Bind to given address and always listen on it. Use [host]:port notation for IPv6"));
|
||||
strUsage += HelpMessageOpt("-connect=<ip>", _("Connect only to the specified node(s)"));
|
||||
strUsage += HelpMessageOpt("-discover", _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)"));
|
||||
strUsage += HelpMessageOpt("-dns", _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)"));
|
||||
strUsage += HelpMessageOpt("-dnsseed", _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)"));
|
||||
strUsage += HelpMessageOpt("-externalip=<ip>", _("Specify your own public address"));
|
||||
strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0));
|
||||
strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)"));
|
||||
strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), 125));
|
||||
strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000));
|
||||
strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000));
|
||||
strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy"));
|
||||
strUsage += HelpMessageOpt("-onlynet=<net>", _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)"));
|
||||
strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), 1));
|
||||
strUsage += HelpMessageOpt("-port=<port>", strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 8333, 18333));
|
||||
strUsage += HelpMessageOpt("-proxy=<ip:port>", _("Connect through SOCKS5 proxy"));
|
||||
strUsage += HelpMessageOpt("-seednode=<ip>", _("Connect to a node to retrieve peer addresses, and disconnect"));
|
||||
strUsage += HelpMessageOpt("-timeout=<n>", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT));
|
||||
#ifdef 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
|
||||
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
|
||||
strUsage += " -whitebind=<addr> " + _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6") + "\n";
|
||||
strUsage += " -whitelist=<netmask> " + _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + "\n";
|
||||
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";
|
||||
strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6"));
|
||||
strUsage += HelpMessageOpt("-whitelist=<netmask>", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") +
|
||||
" " + _("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
|
||||
strUsage += "\n" + _("Wallet options:") + "\n";
|
||||
strUsage += " -disablewallet " + _("Do not load the wallet and disable wallet RPC calls") + "\n";
|
||||
strUsage += " -keypool=<n> " + strprintf(_("Set key pool size to <n> (default: %u)"), 100) + "\n";
|
||||
strUsage += HelpMessageGroup(_("Wallet options:"));
|
||||
strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
|
||||
strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100));
|
||||
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 += " -paytxfee=<amt> " + strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())) + "\n";
|
||||
strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + " " + _("on startup") + "\n";
|
||||
strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n";
|
||||
strUsage += " -sendfreetransactions " + strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0) + "\n";
|
||||
strUsage += " -spendzeroconfchange " + strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1) + "\n";
|
||||
strUsage += " -txconfirmtarget=<n> " + strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1) + "\n";
|
||||
strUsage += " -maxtxfee=<amt> " + strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), FormatMoney(maxTxFee)) + "\n";
|
||||
strUsage += " -upgradewallet " + _("Upgrade wallet to latest format") + " " + _("on startup") + "\n";
|
||||
strUsage += " -wallet=<file> " + _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat") + "\n";
|
||||
strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n";
|
||||
strUsage += " -zapwallettxes=<mode> " + _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + "\n";
|
||||
strUsage += " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)") + "\n";
|
||||
strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"),
|
||||
FormatMoney(CWallet::minTxFee.GetFeePerK())));
|
||||
strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())));
|
||||
strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup"));
|
||||
strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup"));
|
||||
strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0));
|
||||
strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1));
|
||||
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 += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"),
|
||||
FormatMoney(maxTxFee)));
|
||||
strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup"));
|
||||
strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat"));
|
||||
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
|
||||
|
||||
strUsage += "\n" + _("Debugging/Testing options:") + "\n";
|
||||
strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
|
||||
if (GetBoolArg("-help-debug", false))
|
||||
{
|
||||
strUsage += " -checkpoints " + strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1) + "\n";
|
||||
strUsage += " -dblogsize=<n> " + strprintf(_("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)"), 100) + "\n";
|
||||
strUsage += " -disablesafemode " + strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0) + "\n";
|
||||
strUsage += " -testsafemode " + strprintf(_("Force safe mode (default: %u)"), 0) + "\n";
|
||||
strUsage += " -dropmessagestest=<n> " + _("Randomly drop 1 of every <n> network messages") + "\n";
|
||||
strUsage += " -fuzzmessagestest=<n> " + _("Randomly fuzz 1 of every <n> network messages") + "\n";
|
||||
strUsage += " -flushwallet " + strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1) + "\n";
|
||||
strUsage += " -stopafterblockimport " + strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0) + "\n";
|
||||
strUsage += HelpMessageOpt("-checkpoints", strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1));
|
||||
strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf(_("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)"), 100));
|
||||
strUsage += HelpMessageOpt("-disablesafemode", strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0));
|
||||
strUsage += HelpMessageOpt("-testsafemode", strprintf(_("Force safe mode (default: %u)"), 0));
|
||||
strUsage += HelpMessageOpt("-dropmessagestest=<n>", _("Randomly drop 1 of every <n> network messages"));
|
||||
strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", _("Randomly fuzz 1 of every <n> network messages"));
|
||||
strUsage += HelpMessageOpt("-flushwallet", strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1));
|
||||
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";
|
||||
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
|
||||
string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net"; // Don't translate these and qt below
|
||||
if (mode == HMM_BITCOIN_QT)
|
||||
strUsage += ", qt";
|
||||
strUsage += ".\n";
|
||||
debugCategories += ", qt";
|
||||
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
|
||||
strUsage += " -gen " + strprintf(_("Generate coins (default: %u)"), 0) + "\n";
|
||||
strUsage += " -genproclimit=<n> " + strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1) + "\n";
|
||||
strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0));
|
||||
strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1));
|
||||
#endif
|
||||
strUsage += " -help-debug " + _("Show all debugging options (usage: --help -help-debug)") + "\n";
|
||||
strUsage += " -logips " + strprintf(_("Include IP addresses in debug output (default: %u)"), 0) + "\n";
|
||||
strUsage += " -logtimestamps " + strprintf(_("Prepend debug output with timestamp (default: %u)"), 1) + "\n";
|
||||
strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)"));
|
||||
strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0));
|
||||
strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1));
|
||||
if (GetBoolArg("-help-debug", false))
|
||||
{
|
||||
strUsage += " -limitfreerelay=<n> " + strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15) + "\n";
|
||||
strUsage += " -relaypriority " + strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1) + "\n";
|
||||
strUsage += " -maxsigcachesize=<n> " + strprintf(_("Limit size of signature cache to <n> entries (default: %u)"), 50000) + "\n";
|
||||
strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf(_("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u)"), 15));
|
||||
strUsage += HelpMessageOpt("-relaypriority", strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1));
|
||||
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 += " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\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 += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file"));
|
||||
if (GetBoolArg("-help-debug", false))
|
||||
{
|
||||
strUsage += " -printpriority " + strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0) + "\n";
|
||||
strUsage += " -privdb " + strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1) + "\n";
|
||||
strUsage += " -regtest " + _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + "\n";
|
||||
strUsage += " " + _("This is intended for regression testing tools and app development.") + "\n";
|
||||
strUsage += " " + _("In this mode -genproclimit controls how many blocks are generated immediately.") + "\n";
|
||||
strUsage += HelpMessageOpt("-printpriority", strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0));
|
||||
strUsage += HelpMessageOpt("-privdb", strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1));
|
||||
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.") + " " +
|
||||
_("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 += " -testnet " + _("Use the test network") + "\n";
|
||||
strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)"));
|
||||
strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
|
||||
|
||||
strUsage += "\n" + _("Node relay options:") + "\n";
|
||||
strUsage += " -datacarrier " + strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1) + "\n";
|
||||
strUsage += " -datacarriersize " + strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY) + "\n";
|
||||
strUsage += HelpMessageGroup(_("Node relay options:"));
|
||||
strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1));
|
||||
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 += " -blockminsize=<n> " + strprintf(_("Set minimum block size in bytes (default: %u)"), 0) + "\n";
|
||||
strUsage += " -blockmaxsize=<n> " + strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE) + "\n";
|
||||
strUsage += " -blockprioritysize=<n> " + strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE) + "\n";
|
||||
strUsage += HelpMessageGroup(_("Block creation options:"));
|
||||
strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), 0));
|
||||
strUsage += HelpMessageOpt("-blockmaxsize=<n>", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE));
|
||||
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 += " -server " + _("Accept command line and JSON-RPC commands") + "\n";
|
||||
strUsage += " -rest " + strprintf(_("Accept public REST requests (default: %u)"), 0) + "\n";
|
||||
strUsage += " -rpcbind=<addr> " + _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)") + "\n";
|
||||
strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
|
||||
strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
|
||||
strUsage += " -rpcport=<port> " + strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332) + "\n";
|
||||
strUsage += " -rpcallowip=<ip> " + _("Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times") + "\n";
|
||||
strUsage += " -rpcthreads=<n> " + strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4) + "\n";
|
||||
strUsage += " -rpckeepalive " + strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1) + "\n";
|
||||
strUsage += HelpMessageGroup(_("RPC server options:"));
|
||||
strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands"));
|
||||
strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), 0));
|
||||
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 += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
|
||||
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
|
||||
strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332));
|
||||
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 += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4));
|
||||
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 += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
|
||||
strUsage += " -rpcsslcertificatechainfile=<file.cert> " + strprintf(_("Server certificate file (default: %s)"), "server.cert") + "\n";
|
||||
strUsage += " -rpcsslprivatekeyfile=<file.pem> " + strprintf(_("Server private key (default: %s)"), "server.pem") + "\n";
|
||||
strUsage += " -rpcsslciphers=<ciphers> " + strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH") + "\n";
|
||||
strUsage += HelpMessageGroup(_("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
|
||||
strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
|
||||
strUsage += HelpMessageOpt("-rpcsslcertificatechainfile=<file.cert>", strprintf(_("Server certificate file (default: %s)"), "server.cert"));
|
||||
strUsage += HelpMessageOpt("-rpcsslprivatekeyfile=<file.pem>", strprintf(_("Server private key (default: %s)"), "server.pem"));
|
||||
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;
|
||||
}
|
||||
|
@ -837,47 +854,17 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||
LogPrintf("Using wallet %s\n", strWalletFile);
|
||||
uiInterface.InitMessage(_("Verifying wallet..."));
|
||||
|
||||
if (!bitdb.Open(GetDataDir()))
|
||||
{
|
||||
// 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 (!bitdb.Open(GetDataDir())) {
|
||||
// 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))
|
||||
{
|
||||
// Recover readable keypairs:
|
||||
if (!CWalletDB::Recover(bitdb, strWalletFile, true))
|
||||
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"));
|
||||
}
|
||||
std::string warningString;
|
||||
std::string errorString;
|
||||
|
||||
if (!CWallet::Verify(strWalletFile, warningString, errorString))
|
||||
return false;
|
||||
|
||||
if (!warningString.empty())
|
||||
InitWarning(warningString);
|
||||
if (!errorString.empty())
|
||||
return InitError(warningString);
|
||||
|
||||
} // (!fDisableWallet)
|
||||
#endif // ENABLE_WALLET
|
||||
// ********************************************************* Step 6: network initialization
|
||||
|
|
|
@ -208,11 +208,9 @@ void CExtKey::Decode(const unsigned char code[74]) {
|
|||
}
|
||||
|
||||
bool ECC_InitSanityCheck() {
|
||||
#if !defined(USE_SECP256K1)
|
||||
if (!CECKey::SanityCheck()) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
CKey key;
|
||||
key.MakeNewKey(true);
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
#ifndef BITCOIN_KEY_H
|
||||
#define BITCOIN_KEY_H
|
||||
|
||||
#include "allocators.h"
|
||||
#include "serialize.h"
|
||||
#include "support/allocators/secure.h"
|
||||
#include "uint256.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "keystore.h"
|
||||
|
||||
#include "crypter.h"
|
||||
#include "key.h"
|
||||
#include "util.h"
|
||||
|
||||
|
|
168
src/main.cpp
168
src/main.cpp
|
@ -5,9 +5,9 @@
|
|||
|
||||
#include "main.h"
|
||||
|
||||
#include "arith_uint256.h"
|
||||
#include "addrman.h"
|
||||
#include "alert.h"
|
||||
#include "arith_uint256.h"
|
||||
#include "chainparams.h"
|
||||
#include "checkpoints.h"
|
||||
#include "checkqueue.h"
|
||||
|
@ -23,6 +23,7 @@
|
|||
#include "util.h"
|
||||
#include "utilmoneystr.h"
|
||||
#include "ncc.h"
|
||||
#include "validationinterface.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
@ -56,7 +57,6 @@ bool fTxIndex = false;
|
|||
bool fIsBareMultisigStd = true;
|
||||
unsigned int nCoinCacheSize = 5000;
|
||||
|
||||
|
||||
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */
|
||||
CFeeRate minRelayTxFee = CFeeRate(1000);
|
||||
|
||||
|
@ -159,68 +159,6 @@ namespace {
|
|||
set<int> setDirtyFileInfo;
|
||||
} // 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.
|
||||
|
@ -241,6 +179,10 @@ struct CBlockReject {
|
|||
* and we're no longer holding the node's locks.
|
||||
*/
|
||||
struct CNodeState {
|
||||
//! The peer's address
|
||||
CService address;
|
||||
//! Whether we have a fully established connection.
|
||||
bool fCurrentlyConnected;
|
||||
//! Accumulated misbehaviour score for this peer.
|
||||
int nMisbehavior;
|
||||
//! Whether this peer should be disconnected and banned (unless whitelisted).
|
||||
|
@ -265,6 +207,7 @@ struct CNodeState {
|
|||
bool fPreferredDownload;
|
||||
|
||||
CNodeState() {
|
||||
fCurrentlyConnected = false;
|
||||
nMisbehavior = 0;
|
||||
fShouldBan = false;
|
||||
pindexBestKnownBlock = NULL;
|
||||
|
@ -308,6 +251,7 @@ void InitializeNode(NodeId nodeid, const CNode *pnode) {
|
|||
LOCK(cs_main);
|
||||
CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
|
||||
state.name = pnode->addrName;
|
||||
state.address = pnode->addr;
|
||||
}
|
||||
|
||||
void FinalizeNode(NodeId nodeid) {
|
||||
|
@ -317,6 +261,10 @@ void FinalizeNode(NodeId nodeid) {
|
|||
if (state->fSyncStarted)
|
||||
nSyncStarted--;
|
||||
|
||||
if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
|
||||
AddressCurrentlyConnected(state->address);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight)
|
||||
mapBlocksInFlight.erase(entry.hash);
|
||||
EraseOrphansFor(nodeid);
|
||||
|
@ -2026,7 +1974,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
|
||||
// Watch for changes to the previous coinbase transaction.
|
||||
static uint256 hashPrevBestCoinBase;
|
||||
g_signals.UpdatedTransaction(hashPrevBestCoinBase);
|
||||
GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
|
||||
hashPrevBestCoinBase = block.vtx[0].GetHash();
|
||||
|
||||
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");
|
||||
// Update best block in wallet (so we can detect restored wallets).
|
||||
if (mode != FLUSH_STATE_IF_NEEDED) {
|
||||
g_signals.SetBestChain(chainActive.GetLocator());
|
||||
GetMainSignals().SetBestChain(chainActive.GetLocator());
|
||||
}
|
||||
nLastWrite = GetTimeMicros();
|
||||
}
|
||||
|
@ -2215,7 +2163,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
|
|||
CNCCTrieCache trieCache(pnccTrie);
|
||||
CInv inv(MSG_BLOCK, pindexNew->GetBlockHash());
|
||||
bool rv = ConnectBlock(*pblock, state, pindexNew, view, trieCache);
|
||||
g_signals.BlockChecked(*pblock, state);
|
||||
GetMainSignals().BlockChecked(*pblock, state);
|
||||
if (!rv) {
|
||||
if (state.IsInvalid())
|
||||
InvalidBlockFound(pindexNew, state);
|
||||
|
@ -2456,8 +2404,8 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
|
|||
// add them again.
|
||||
BlockMap::iterator it = mapBlockIndex.begin();
|
||||
while (it != mapBlockIndex.end()) {
|
||||
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) {
|
||||
setBlockIndexCandidates.insert(pindex);
|
||||
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
|
||||
setBlockIndexCandidates.insert(it->second);
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
@ -2600,8 +2548,11 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd
|
|||
}
|
||||
|
||||
nLastBlockFile = nFile;
|
||||
vinfoBlockFile[nFile].nSize += nAddSize;
|
||||
vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
|
||||
if (fKnown)
|
||||
vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
|
||||
else
|
||||
vinfoBlockFile[nFile].nSize += nAddSize;
|
||||
|
||||
if (!fKnown) {
|
||||
unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE;
|
||||
|
@ -2739,8 +2690,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
|
|||
int nHeight = pindexPrev->nHeight+1;
|
||||
|
||||
// Check proof of work
|
||||
if ((!Params().SkipProofOfWorkCheck()) &&
|
||||
(block.nBits != GetNextWorkRequired(pindexPrev, &block)))
|
||||
if ((block.nBits != GetNextWorkRequired(pindexPrev, &block)))
|
||||
return state.DoS(100, error("%s: incorrect proof of work", __func__),
|
||||
REJECT_INVALID, "bad-diffbits");
|
||||
|
||||
|
@ -3232,10 +3182,31 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth
|
|||
|
||||
void UnloadBlockIndex()
|
||||
{
|
||||
mapBlockIndex.clear();
|
||||
LOCK(cs_main);
|
||||
setBlockIndexCandidates.clear();
|
||||
chainActive.SetTip(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()
|
||||
|
@ -3502,19 +3473,17 @@ void static ProcessGetData(CNode* pfrom)
|
|||
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
|
||||
if (mi != mapBlockIndex.end())
|
||||
{
|
||||
// If the requested block is at a height below our last
|
||||
// checkpoint, only serve it if it's in the checkpointed chain
|
||||
int nHeight = mi->second->nHeight;
|
||||
CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
|
||||
if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
|
||||
if (!chainActive.Contains(mi->second))
|
||||
{
|
||||
LogPrintf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n");
|
||||
} else {
|
||||
send = true;
|
||||
}
|
||||
} else {
|
||||
if (chainActive.Contains(mi->second)) {
|
||||
send = true;
|
||||
} else {
|
||||
// To prevent fingerprinting attacks, only send blocks outside of the active
|
||||
// chain if they are valid, and no more than a month older than the best header
|
||||
// chain we know about.
|
||||
send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
|
||||
(mi->second->GetBlockTime() > pindexBestHeader->GetBlockTime() - 30 * 24 * 60 * 60);
|
||||
if (!send) {
|
||||
LogPrintf("ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (send)
|
||||
|
@ -3588,7 +3557,7 @@ void static ProcessGetData(CNode* pfrom)
|
|||
}
|
||||
|
||||
// Track requests for our stuff.
|
||||
g_signals.Inventory(inv.hash);
|
||||
GetMainSignals().Inventory(inv.hash);
|
||||
|
||||
if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK)
|
||||
break;
|
||||
|
@ -3754,6 +3723,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||
else if (strCommand == "verack")
|
||||
{
|
||||
pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION));
|
||||
|
||||
// Mark this node as currently connected, so we update its timestamp later.
|
||||
if (pfrom->fNetworkNode) {
|
||||
LOCK(cs_main);
|
||||
State(pfrom->GetId())->fCurrentlyConnected = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -3876,7 +3851,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||
}
|
||||
|
||||
// Track requests for our stuff
|
||||
g_signals.Inventory(inv.hash);
|
||||
GetMainSignals().Inventory(inv.hash);
|
||||
|
||||
if (pfrom->nSendSize > (SendBufferSize() * 2)) {
|
||||
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();
|
||||
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;
|
||||
}
|
||||
|
@ -4454,7 +4429,7 @@ bool ProcessMessages(CNode* pfrom)
|
|||
|
||||
// Read header
|
||||
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);
|
||||
continue;
|
||||
|
@ -4467,8 +4442,7 @@ bool ProcessMessages(CNode* pfrom)
|
|||
// Checksum
|
||||
CDataStream& vRecv = msg.vRecv;
|
||||
uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
|
||||
unsigned int nChecksum = 0;
|
||||
memcpy(&nChecksum, &hash, sizeof(nChecksum));
|
||||
unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
|
||||
if (nChecksum != hdr.nChecksum)
|
||||
{
|
||||
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.
|
||||
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() */
|
||||
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 */
|
||||
void RegisterNodeSignals(CNodeSignals& nodeSignals);
|
||||
/** 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
|
||||
* 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] 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.
|
||||
|
@ -517,19 +508,4 @@ extern CNCCTrie *pnccTrie;
|
|||
/** Global variable that points to the active block tree (protected by cs_main) */
|
||||
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
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "util.h"
|
||||
#include "utilmoneystr.h"
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
#endif
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
|
|
@ -109,6 +109,20 @@ bool CNCCTrie::queueEmpty() const
|
|||
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
|
||||
{
|
||||
const CNCCTrieNode* current = &root;
|
||||
|
|
|
@ -152,6 +152,7 @@ public:
|
|||
uint256 getMerkleHash();
|
||||
CLevelDBWrapper db;
|
||||
bool empty() const;
|
||||
void clear();
|
||||
bool checkConsistency();
|
||||
bool WriteToDisk();
|
||||
bool ReadFromDisk(bool check = false);
|
||||
|
@ -162,6 +163,7 @@ public:
|
|||
bool haveClaim(const std::string& name, const uint256& txhash, uint32_t nOut) const;
|
||||
friend class CNCCTrieCache;
|
||||
private:
|
||||
void clear(CNCCTrieNode* current);
|
||||
bool update(nodeCacheType& cache, hashMapType& hashes, const uint256& hashBlock, valueQueueType& queueCache, int nNewHeight);
|
||||
bool updateName(const std::string& name, CNCCTrieNode* updatedNode);
|
||||
bool updateHash(const std::string& name, uint256& hash);
|
||||
|
|
12
src/net.cpp
12
src/net.cpp
|
@ -14,6 +14,7 @@
|
|||
#include "clientversion.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "ui_interface.h"
|
||||
#include "crypto/common.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#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
|
||||
if (vRecvMsg.empty() ||
|
||||
vRecvMsg.back().complete())
|
||||
vRecvMsg.push_back(CNetMessage(SER_NETWORK, nRecvVersion));
|
||||
vRecvMsg.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK, nRecvVersion));
|
||||
|
||||
CNetMessage& msg = vRecvMsg.back();
|
||||
|
||||
|
@ -523,6 +524,11 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
|
|||
if (handled < 0)
|
||||
return false;
|
||||
|
||||
if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
|
||||
LogPrint("net", "Oversized message from peer=%i, disconnecting", GetId());
|
||||
return false;
|
||||
}
|
||||
|
||||
pch += handled;
|
||||
nBytes -= handled;
|
||||
|
||||
|
@ -1970,7 +1976,7 @@ void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSen
|
|||
{
|
||||
ENTER_CRITICAL_SECTION(cs_vSend);
|
||||
assert(ssSend.size() == 0);
|
||||
ssSend << CMessageHeader(pszCommand, 0);
|
||||
ssSend << CMessageHeader(Params().MessageStart(), pszCommand, 0);
|
||||
LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
|
||||
}
|
||||
|
||||
|
@ -2002,7 +2008,7 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
|
|||
|
||||
// Set the 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
|
||||
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;
|
||||
/** The maximum number of new addresses to accumulate before announcing. */
|
||||
static const unsigned int MAX_ADDR_TO_SEND = 1000;
|
||||
/** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */
|
||||
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024;
|
||||
/** -listen default */
|
||||
static const bool DEFAULT_LISTEN = true;
|
||||
/** -upnp default */
|
||||
|
@ -76,12 +78,27 @@ void SocketSendData(CNode *pnode);
|
|||
|
||||
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
|
||||
struct CNodeSignals
|
||||
{
|
||||
boost::signals2::signal<int ()> GetHeight;
|
||||
boost::signals2::signal<bool (CNode*)> ProcessMessages;
|
||||
boost::signals2::signal<bool (CNode*, bool)> SendMessages;
|
||||
boost::signals2::signal<bool (CNode*), CombinerAll> ProcessMessages;
|
||||
boost::signals2::signal<bool (CNode*, bool), CombinerAll> SendMessages;
|
||||
boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
|
||||
boost::signals2::signal<void (NodeId)> FinalizeNode;
|
||||
};
|
||||
|
@ -183,7 +200,7 @@ public:
|
|||
|
||||
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);
|
||||
in_data = false;
|
||||
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();
|
||||
|
||||
// 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) {
|
||||
READWRITE(FLATDATA(ip));
|
||||
unsigned short portN = htons(port);
|
||||
READWRITE(portN);
|
||||
READWRITE(FLATDATA(portN));
|
||||
if (ser_action.ForRead())
|
||||
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;
|
||||
assert(pindexFirst);
|
||||
|
||||
return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime());
|
||||
}
|
||||
|
||||
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime)
|
||||
{
|
||||
// Limit adjustment step
|
||||
int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
|
||||
int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
|
||||
LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
|
||||
if (nActualTimespan < Params().TargetTimespan()/4)
|
||||
nActualTimespan = Params().TargetTimespan()/4;
|
||||
|
@ -82,9 +87,6 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits)
|
|||
bool fOverflow;
|
||||
arith_uint256 bnTarget;
|
||||
|
||||
if (Params().SkipProofOfWorkCheck())
|
||||
return true;
|
||||
|
||||
bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
|
||||
|
||||
// Check range
|
||||
|
|
|
@ -14,6 +14,7 @@ class uint256;
|
|||
class arith_uint256;
|
||||
|
||||
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 */
|
||||
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
#include "hash.h"
|
||||
#include "tinyformat.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "crypto/common.h"
|
||||
|
||||
uint256 CBlockHeader::GetHash() const
|
||||
{
|
||||
return Hash(BEGIN(nVersion), END(nNonce));
|
||||
return SerializeHash(*this);
|
||||
}
|
||||
|
||||
uint256 CBlock::BuildMerkleTree(bool* fMutated) const
|
||||
|
|
|
@ -25,7 +25,8 @@ public:
|
|||
|
||||
template <typename Stream, typename Operation>
|
||||
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; }
|
||||
|
@ -134,7 +135,7 @@ public:
|
|||
|
||||
uint256 GetHash() const;
|
||||
|
||||
bool IsDust(CFeeRate minRelayTxFee) const
|
||||
CAmount GetDustThreshold(const CFeeRate &minRelayTxFee) const
|
||||
{
|
||||
// "Dust" is defined in terms of CTransaction::minRelayTxFee,
|
||||
// which has units satoshis-per-kilobyte.
|
||||
|
@ -145,7 +146,12 @@ public:
|
|||
// so dust is a txout less than 546 satoshis
|
||||
// with default minRelayTxFee.
|
||||
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)
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "protocol.h"
|
||||
|
||||
#include "chainparams.h"
|
||||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
|
@ -21,17 +20,17 @@ static const char* ppszTypeName[] =
|
|||
"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));
|
||||
nMessageSize = -1;
|
||||
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));
|
||||
strncpy(pchCommand, pszCommand, COMMAND_SIZE);
|
||||
nMessageSize = nMessageSizeIn;
|
||||
|
@ -43,10 +42,10 @@ std::string CMessageHeader::GetCommand() const
|
|||
return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
|
||||
}
|
||||
|
||||
bool CMessageHeader::IsValid() const
|
||||
bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const
|
||||
{
|
||||
// Check start string
|
||||
if (memcmp(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0)
|
||||
if (memcmp(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE) != 0)
|
||||
return false;
|
||||
|
||||
// Check the command string for errors
|
||||
|
|
|
@ -29,11 +29,13 @@
|
|||
class CMessageHeader
|
||||
{
|
||||
public:
|
||||
CMessageHeader();
|
||||
CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn);
|
||||
typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
|
||||
|
||||
CMessageHeader(const MessageStartChars& pchMessageStartIn);
|
||||
CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn);
|
||||
|
||||
std::string GetCommand() const;
|
||||
bool IsValid() const;
|
||||
bool IsValid(const MessageStartChars& messageStart) const;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
|
|
|
@ -6,25 +6,16 @@
|
|||
|
||||
#include "eccryptoverify.h"
|
||||
|
||||
#ifdef USE_SECP256K1
|
||||
#include <secp256k1.h>
|
||||
#else
|
||||
#include "ecwrapper.h"
|
||||
#endif
|
||||
|
||||
bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
|
||||
if (!IsValid())
|
||||
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;
|
||||
if (!key.SetPubKey(begin(), size()))
|
||||
return false;
|
||||
if (!key.Verify(hash, vchSig))
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -33,52 +24,33 @@ bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned cha
|
|||
return false;
|
||||
int recid = (vchSig[0] - 27) & 3;
|
||||
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;
|
||||
if (!key.Recover(hash, &vchSig[1], recid))
|
||||
return false;
|
||||
std::vector<unsigned char> pubkey;
|
||||
key.GetPubKey(pubkey, fComp);
|
||||
Set(pubkey.begin(), pubkey.end());
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPubKey::IsFullyValid() const {
|
||||
if (!IsValid())
|
||||
return false;
|
||||
#ifdef USE_SECP256K1
|
||||
if (!secp256k1_ecdsa_pubkey_verify(begin(), size()))
|
||||
return false;
|
||||
#else
|
||||
CECKey key;
|
||||
if (!key.SetPubKey(begin(), size()))
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPubKey::Decompress() {
|
||||
if (!IsValid())
|
||||
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;
|
||||
if (!key.SetPubKey(begin(), size()))
|
||||
return false;
|
||||
std::vector<unsigned char> pubkey;
|
||||
key.GetPubKey(pubkey, false);
|
||||
Set(pubkey.begin(), pubkey.end());
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -89,17 +61,12 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned i
|
|||
unsigned char out[64];
|
||||
BIP32Hash(cc, nChild, *begin(), begin()+1, out);
|
||||
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;
|
||||
bool ret = key.SetPubKey(begin(), size());
|
||||
ret &= key.TweakPublic(out);
|
||||
std::vector<unsigned char> pubkey;
|
||||
key.GetPubKey(pubkey, true);
|
||||
pubkeyChild.Set(pubkey.begin(), pubkey.end());
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
#include "walletmodel.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "wallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <QFont>
|
||||
#include <QDebug>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "guiconstants.h"
|
||||
#include "walletmodel.h"
|
||||
|
||||
#include "allocators.h"
|
||||
#include "support/allocators/secure.h"
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QMessageBox>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "util.h"
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
#endif
|
||||
|
||||
#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
|
||||
// Needs walletFrame to be initialized
|
||||
createActions(networkStyle);
|
||||
createActions();
|
||||
|
||||
// Create application menu bar
|
||||
createMenuBar();
|
||||
|
@ -237,13 +237,13 @@ BitcoinGUI::~BitcoinGUI()
|
|||
trayIcon->hide();
|
||||
#ifdef Q_OS_MAC
|
||||
delete appMenuBar;
|
||||
MacDockIconHandler::instance()->setMainWindow(NULL);
|
||||
MacDockIconHandler::cleanup();
|
||||
#endif
|
||||
|
||||
delete rpcConsole;
|
||||
}
|
||||
|
||||
void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
|
||||
void BitcoinGUI::createActions()
|
||||
{
|
||||
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"));
|
||||
|
||||
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"));
|
||||
|
||||
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
|
||||
|
@ -435,8 +436,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
|
|||
setNumConnections(clientModel->getNumConnections());
|
||||
connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
|
||||
|
||||
setNumBlocks(clientModel->getNumBlocks());
|
||||
connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
|
||||
setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate());
|
||||
connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
|
||||
|
||||
// Receive and report messages from client model
|
||||
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));
|
||||
}
|
||||
|
||||
void BitcoinGUI::setNumBlocks(int count)
|
||||
void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate)
|
||||
{
|
||||
if(!clientModel)
|
||||
return;
|
||||
|
@ -680,9 +681,8 @@ void BitcoinGUI::setNumBlocks(int count)
|
|||
|
||||
QString tooltip;
|
||||
|
||||
QDateTime lastBlockDate = clientModel->getLastBlockDate();
|
||||
QDateTime currentDate = QDateTime::currentDateTime();
|
||||
int secs = lastBlockDate.secsTo(currentDate);
|
||||
qint64 secs = blockDate.secsTo(currentDate);
|
||||
|
||||
tooltip = tr("Processed %n blocks of transaction history.", "", count);
|
||||
|
||||
|
@ -722,8 +722,8 @@ void BitcoinGUI::setNumBlocks(int count)
|
|||
}
|
||||
else
|
||||
{
|
||||
int years = secs / YEAR_IN_SECONDS;
|
||||
int remainder = secs % YEAR_IN_SECONDS;
|
||||
qint64 years = 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));
|
||||
}
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ private:
|
|||
int spinnerFrame;
|
||||
|
||||
/** Create the main UI actions. */
|
||||
void createActions(const NetworkStyle *networkStyle);
|
||||
void createActions();
|
||||
/** Create the menu bar and sub-menus. */
|
||||
void createMenuBar();
|
||||
/** Create the toolbars */
|
||||
|
@ -143,8 +143,8 @@ signals:
|
|||
public slots:
|
||||
/** Set number of connections shown in the UI */
|
||||
void setNumConnections(int count);
|
||||
/** Set number of blocks shown in the UI */
|
||||
void setNumBlocks(int count);
|
||||
/** Set number of blocks and last block date shown in the UI */
|
||||
void setNumBlocks(int count, const QDateTime& blockDate);
|
||||
|
||||
/** Notify the user of an event from the core network or transaction handling code.
|
||||
@param[in] title the message box / notification title
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
|
||||
|
@ -29,8 +28,10 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
|
|||
optionsModel(optionsModel),
|
||||
peerTableModel(0),
|
||||
cachedNumBlocks(0),
|
||||
cachedReindexing(0), cachedImporting(0),
|
||||
numBlocksAtStartup(-1), pollTimer(0)
|
||||
cachedBlockDate(QDateTime()),
|
||||
cachedReindexing(0),
|
||||
cachedImporting(0),
|
||||
pollTimer(0)
|
||||
{
|
||||
peerTableModel = new PeerTableModel(this);
|
||||
pollTimer = new QTimer(this);
|
||||
|
@ -65,12 +66,6 @@ int ClientModel::getNumBlocks() const
|
|||
return chainActive.Height();
|
||||
}
|
||||
|
||||
int ClientModel::getNumBlocksAtStartup()
|
||||
{
|
||||
if (numBlocksAtStartup == -1) numBlocksAtStartup = getNumBlocks();
|
||||
return numBlocksAtStartup;
|
||||
}
|
||||
|
||||
quint64 ClientModel::getTotalBytesRecv() const
|
||||
{
|
||||
return CNode::GetTotalBytesRecv();
|
||||
|
@ -84,10 +79,11 @@ quint64 ClientModel::getTotalBytesSent() const
|
|||
QDateTime ClientModel::getLastBlockDate() const
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
||||
if (chainActive.Tip())
|
||||
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
|
||||
|
@ -102,21 +98,26 @@ void ClientModel::updateTimer()
|
|||
// periodical polls if the core is holding the locks for a longer time -
|
||||
// for example, during a wallet rescan.
|
||||
TRY_LOCK(cs_main, lockMain);
|
||||
if(!lockMain)
|
||||
if (!lockMain)
|
||||
return;
|
||||
|
||||
// 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.
|
||||
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
|
||||
if (cachedNumBlocks != newNumBlocks ||
|
||||
cachedReindexing != fReindex || cachedImporting != fImporting)
|
||||
cachedBlockDate != newBlockDate ||
|
||||
cachedReindexing != fReindex ||
|
||||
cachedImporting != fImporting)
|
||||
{
|
||||
cachedNumBlocks = newNumBlocks;
|
||||
cachedBlockDate = newBlockDate;
|
||||
cachedReindexing = fReindex;
|
||||
cachedImporting = fImporting;
|
||||
|
||||
emit numBlocksChanged(newNumBlocks);
|
||||
emit numBlocksChanged(newNumBlocks, newBlockDate);
|
||||
}
|
||||
|
||||
emit bytesChanged(getTotalBytesRecv(), getTotalBytesSent());
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#define BITCOIN_QT_CLIENTMODEL_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDateTime>
|
||||
|
||||
class AddressTableModel;
|
||||
class OptionsModel;
|
||||
|
@ -15,7 +16,6 @@ class TransactionTableModel;
|
|||
class CWallet;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QDateTime;
|
||||
class QTimer;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@ -48,7 +48,6 @@ public:
|
|||
//! Return number of connections, default is in- and outbound (total)
|
||||
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
|
||||
int getNumBlocks() const;
|
||||
int getNumBlocksAtStartup();
|
||||
|
||||
quint64 getTotalBytesRecv() const;
|
||||
quint64 getTotalBytesSent() const;
|
||||
|
@ -74,11 +73,10 @@ private:
|
|||
PeerTableModel *peerTableModel;
|
||||
|
||||
int cachedNumBlocks;
|
||||
QDateTime cachedBlockDate;
|
||||
bool cachedReindexing;
|
||||
bool cachedImporting;
|
||||
|
||||
int numBlocksAtStartup;
|
||||
|
||||
QTimer *pollTimer;
|
||||
|
||||
void subscribeToCoreSignals();
|
||||
|
@ -86,7 +84,7 @@ private:
|
|||
|
||||
signals:
|
||||
void numConnectionsChanged(int count);
|
||||
void numBlocksChanged(int count);
|
||||
void numBlocksChanged(int count, const QDateTime& blockDate);
|
||||
void alertsChanged(const QString &warnings);
|
||||
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "coincontrol.h"
|
||||
#include "main.h"
|
||||
#include "wallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
|||
using namespace std;
|
||||
QList<CAmount> CoinControlDialog::payAmounts;
|
||||
CCoinControl* CoinControlDialog::coinControl = new CCoinControl();
|
||||
bool CoinControlDialog::fSubtractFeeFromAmount = false;
|
||||
|
||||
CoinControlDialog::CoinControlDialog(QWidget *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)
|
||||
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
|
||||
nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
|
||||
|
||||
|
@ -556,7 +562,9 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
|||
|
||||
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.
|
||||
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));
|
||||
if (txout.IsDust(::minRelayTxFee))
|
||||
{
|
||||
nPayFee += nChange;
|
||||
nChange = 0;
|
||||
if (CoinControlDialog::fSubtractFeeFromAmount) // dust-change will be raised until no dust
|
||||
nChange = txout.GetDustThreshold(::minRelayTxFee);
|
||||
else
|
||||
{
|
||||
nPayFee += nChange;
|
||||
nChange = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nChange == 0)
|
||||
if (nChange == 0 && !CoinControlDialog::fSubtractFeeFromAmount)
|
||||
nBytes -= 34;
|
||||
}
|
||||
|
||||
|
@ -612,7 +625,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
|||
{
|
||||
l3->setText(ASYMP_UTF8 + l3->text());
|
||||
l4->setText(ASYMP_UTF8 + l4->text());
|
||||
if (nChange > 0)
|
||||
if (nChange > 0 && !CoinControlDialog::fSubtractFeeFromAmount)
|
||||
l8->setText(ASYMP_UTF8 + l8->text());
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
|
||||
static QList<CAmount> payAmounts;
|
||||
static CCoinControl *coinControl;
|
||||
static bool fSubtractFeeFromAmount;
|
||||
|
||||
private:
|
||||
Ui::CoinControlDialog *ui;
|
||||
|
|
|
@ -771,16 +771,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -811,6 +801,16 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</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>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -157,7 +157,21 @@
|
|||
</widget>
|
||||
</item>
|
||||
<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 row="3" column="0">
|
||||
<widget class="QLabel" name="messageLabel">
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#if BOOST_FILESYSTEM_VERSION >= 3
|
||||
#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
|
||||
#endif
|
||||
#include <boost/scoped_array.hpp>
|
||||
|
||||
#include <QAbstractItemView>
|
||||
#include <QApplication>
|
||||
|
@ -567,12 +568,17 @@ TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* t
|
|||
#ifdef WIN32
|
||||
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";
|
||||
}
|
||||
|
||||
bool GetStartOnSystemStartup()
|
||||
{
|
||||
// check for Bitcoin.lnk
|
||||
// check for Bitcoin*.lnk
|
||||
return boost::filesystem::exists(StartupShortcutPath());
|
||||
}
|
||||
|
||||
|
@ -588,8 +594,8 @@ bool SetStartOnSystemStartup(bool fAutoStart)
|
|||
// Get a pointer to the IShellLink interface.
|
||||
IShellLink* psl = NULL;
|
||||
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
|
||||
CLSCTX_INPROC_SERVER, IID_IShellLink,
|
||||
reinterpret_cast<void**>(&psl));
|
||||
CLSCTX_INPROC_SERVER, IID_IShellLink,
|
||||
reinterpret_cast<void**>(&psl));
|
||||
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
|
@ -597,20 +603,34 @@ bool SetStartOnSystemStartup(bool fAutoStart)
|
|||
TCHAR pszExePath[MAX_PATH];
|
||||
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
|
||||
psl->SetPath(pszExePath);
|
||||
PathRemoveFileSpec(pszExePath);
|
||||
psl->SetWorkingDirectory(pszExePath);
|
||||
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
|
||||
// saving the shortcut in persistent storage.
|
||||
IPersistFile* ppf = NULL;
|
||||
hres = psl->QueryInterface(IID_IPersistFile,
|
||||
reinterpret_cast<void**>(&ppf));
|
||||
hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&ppf));
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
WCHAR pwsz[MAX_PATH];
|
||||
|
@ -630,11 +650,10 @@ bool SetStartOnSystemStartup(bool fAutoStart)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#elif defined(Q_OS_LINUX)
|
||||
|
||||
// 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()
|
||||
{
|
||||
|
@ -690,8 +709,13 @@ bool SetStartOnSystemStartup(bool fAutoStart)
|
|||
// Write a bitcoin.desktop file to the autostart directory:
|
||||
optionFile << "[Desktop Entry]\n";
|
||||
optionFile << "Type=Application\n";
|
||||
optionFile << "Name=Bitcoin\n";
|
||||
optionFile << "Exec=" << pszExePath << " -min\n";
|
||||
if (GetBoolArg("-testnet", false))
|
||||
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 << "Hidden=false\n";
|
||||
optionFile.close();
|
||||
|
|
|
@ -14,12 +14,6 @@ class QMenu;
|
|||
class QWidget;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#ifdef __OBJC__
|
||||
@class DockIconClickEventHandler;
|
||||
#else
|
||||
class DockIconClickEventHandler;
|
||||
#endif
|
||||
|
||||
/** Macintosh-specific dock icon handler.
|
||||
*/
|
||||
class MacDockIconHandler : public QObject
|
||||
|
@ -33,7 +27,7 @@ public:
|
|||
void setIcon(const QIcon &icon);
|
||||
void setMainWindow(QMainWindow *window);
|
||||
static MacDockIconHandler *instance();
|
||||
|
||||
static void cleanup();
|
||||
void handleDockIconClickEvent();
|
||||
|
||||
signals:
|
||||
|
@ -42,7 +36,6 @@ signals:
|
|||
private:
|
||||
MacDockIconHandler();
|
||||
|
||||
DockIconClickEventHandler *m_dockIconClickEventHandler;
|
||||
QWidget *m_dummyWidget;
|
||||
QMenu *m_dockMenu;
|
||||
QMainWindow *mainWindow;
|
||||
|
|
|
@ -11,52 +11,46 @@
|
|||
|
||||
#undef slots
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <objc/objc.h>
|
||||
#include <objc/message.h>
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
extern void qt_mac_set_dock_menu(QMenu *);
|
||||
#endif
|
||||
|
||||
@interface DockIconClickEventHandler : NSObject
|
||||
{
|
||||
MacDockIconHandler* dockIconHandler;
|
||||
static MacDockIconHandler *s_instance = NULL;
|
||||
|
||||
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
|
||||
|
||||
@implementation DockIconClickEventHandler
|
||||
|
||||
- (id)initWithDockIconHandler:(MacDockIconHandler *)aDockIconHandler
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
dockIconHandler = aDockIconHandler;
|
||||
|
||||
[[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();
|
||||
void setupDockClickHandler() {
|
||||
Class cls = objc_getClass("NSApplication");
|
||||
id appInst = objc_msgSend((id)cls, sel_registerName("sharedApplication"));
|
||||
|
||||
if (appInst != NULL) {
|
||||
id delegate = objc_msgSend(appInst, sel_registerName("delegate"));
|
||||
Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class"));
|
||||
SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
|
||||
if (class_getInstanceMethod(delClass, shouldHandle))
|
||||
class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:");
|
||||
else
|
||||
class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler,"B@:");
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
MacDockIconHandler::MacDockIconHandler() : QObject()
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
this->m_dockIconClickEventHandler = [[DockIconClickEventHandler alloc] initWithDockIconHandler:this];
|
||||
setupDockClickHandler();
|
||||
this->m_dummyWidget = new QWidget();
|
||||
this->m_dockMenu = new QMenu(this->m_dummyWidget);
|
||||
this->setMainWindow(NULL);
|
||||
|
@ -74,7 +68,6 @@ void MacDockIconHandler::setMainWindow(QMainWindow *window) {
|
|||
|
||||
MacDockIconHandler::~MacDockIconHandler()
|
||||
{
|
||||
[this->m_dockIconClickEventHandler release];
|
||||
delete this->m_dummyWidget;
|
||||
this->setMainWindow(NULL);
|
||||
}
|
||||
|
@ -119,12 +112,16 @@ void MacDockIconHandler::setIcon(const QIcon &icon)
|
|||
|
||||
MacDockIconHandler *MacDockIconHandler::instance()
|
||||
{
|
||||
static MacDockIconHandler *s_instance = NULL;
|
||||
if (!s_instance)
|
||||
s_instance = new MacDockIconHandler();
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void MacDockIconHandler::cleanup()
|
||||
{
|
||||
delete s_instance;
|
||||
}
|
||||
|
||||
void MacDockIconHandler::handleDockIconClickEvent()
|
||||
{
|
||||
if (this->mainWindow)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "txdb.h" // for -dbcache defaults
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet.h" // for CWallet::minTxFee
|
||||
#include "wallet/wallet.h" // for CWallet::minTxFee
|
||||
#endif
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
@ -38,7 +38,6 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
|
|||
fProxyIpValid(true)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
GUIUtil::restoreWindowGeometry("nOptionsDialogWindow", this->size(), this);
|
||||
|
||||
/* Main elements init */
|
||||
ui->databaseCache->setMinimum(nMinDbCache);
|
||||
|
@ -117,7 +116,6 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
|
|||
|
||||
OptionsDialog::~OptionsDialog()
|
||||
{
|
||||
GUIUtil::saveWindowGeometry("nOptionsDialogWindow", this);
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#include "txdb.h" // for -dbcache defaults
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet.h"
|
||||
#include "walletdb.h"
|
||||
#include "wallet/wallet.h"
|
||||
#include "wallet/walletdb.h"
|
||||
#endif
|
||||
|
||||
#include <QNetworkProxy>
|
||||
|
|
|
@ -10,9 +10,10 @@
|
|||
|
||||
#include "base58.h"
|
||||
#include "chainparams.h"
|
||||
#include "main.h"
|
||||
#include "ui_interface.h"
|
||||
#include "util.h"
|
||||
#include "wallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
|
|
|
@ -293,8 +293,8 @@ void RPCConsole::setClientModel(ClientModel *model)
|
|||
setNumConnections(model->getNumConnections());
|
||||
connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
|
||||
|
||||
setNumBlocks(model->getNumBlocks());
|
||||
connect(model, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
|
||||
setNumBlocks(model->getNumBlocks(), model->getLastBlockDate());
|
||||
connect(model, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
|
||||
|
||||
updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent());
|
||||
connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64)));
|
||||
|
@ -404,11 +404,10 @@ void RPCConsole::setNumConnections(int count)
|
|||
ui->numberOfConnections->setText(connections);
|
||||
}
|
||||
|
||||
void RPCConsole::setNumBlocks(int count)
|
||||
void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate)
|
||||
{
|
||||
ui->numberOfBlocks->setText(QString::number(count));
|
||||
if(clientModel)
|
||||
ui->lastBlockTime->setText(clientModel->getLastBlockDate().toString());
|
||||
ui->lastBlockTime->setText(blockDate.toString());
|
||||
}
|
||||
|
||||
void RPCConsole::on_lineEdit_returnPressed()
|
||||
|
|
|
@ -63,8 +63,8 @@ public slots:
|
|||
void message(int category, const QString &message, bool html = false);
|
||||
/** Set number of connections shown in the UI */
|
||||
void setNumConnections(int count);
|
||||
/** Set number of blocks shown in the UI */
|
||||
void setNumBlocks(int count);
|
||||
/** Set number of blocks and last block date shown in the UI */
|
||||
void setNumBlocks(int count, const QDateTime& blockDate);
|
||||
/** Go forward or back in history */
|
||||
void browseHistory(int offset);
|
||||
/** Scroll console view to end */
|
||||
|
|
|
@ -17,8 +17,9 @@
|
|||
|
||||
#include "base58.h"
|
||||
#include "coincontrol.h"
|
||||
#include "main.h"
|
||||
#include "ui_interface.h"
|
||||
#include "wallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QScrollBar>
|
||||
|
@ -121,7 +122,7 @@ void SendCoinsDialog::setClientModel(ClientModel *clientModel)
|
|||
this->clientModel = 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;
|
||||
}
|
||||
|
||||
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
|
||||
QStringList formatted;
|
||||
foreach(const SendCoinsRecipient &rcp, recipients)
|
||||
foreach(const SendCoinsRecipient &rcp, currentTransaction.getRecipients())
|
||||
{
|
||||
// generate bold amount string
|
||||
QString amount = "<b>" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
|
||||
|
@ -257,35 +286,6 @@ void SendCoinsDialog::on_sendButton_clicked()
|
|||
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?");
|
||||
questionString.append("<br /><br />%1");
|
||||
|
||||
|
@ -368,6 +368,7 @@ SendCoinsEntry *SendCoinsDialog::addEntry()
|
|||
ui->entries->addWidget(entry);
|
||||
connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*)));
|
||||
connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels()));
|
||||
connect(entry, SIGNAL(subtractFeeFromAmountChanged()), this, SLOT(coinControlUpdateLabels()));
|
||||
|
||||
updateTabsAndLabels();
|
||||
|
||||
|
@ -783,11 +784,17 @@ void SendCoinsDialog::coinControlUpdateLabels()
|
|||
|
||||
// set pay amounts
|
||||
CoinControlDialog::payAmounts.clear();
|
||||
CoinControlDialog::fSubtractFeeFromAmount = false;
|
||||
for(int i = 0; i < ui->entries->count(); ++i)
|
||||
{
|
||||
SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
|
||||
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())
|
||||
|
|
|
@ -44,6 +44,7 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
|
|||
|
||||
// Connect signals
|
||||
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_is, 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->addAsLabel->clear();
|
||||
ui->payAmount->clear();
|
||||
ui->checkboxSubtractFeeFromAmount->setCheckState(Qt::Unchecked);
|
||||
ui->messageTextLabel->clear();
|
||||
ui->messageTextLabel->hide();
|
||||
ui->messageLabel->hide();
|
||||
|
@ -165,6 +167,7 @@ SendCoinsRecipient SendCoinsEntry::getValue()
|
|||
recipient.label = ui->addAsLabel->text();
|
||||
recipient.amount = ui->payAmount->value();
|
||||
recipient.message = ui->messageTextLabel->text();
|
||||
recipient.fSubtractFeeFromAmount = (ui->checkboxSubtractFeeFromAmount->checkState() == Qt::Checked);
|
||||
|
||||
return recipient;
|
||||
}
|
||||
|
@ -174,7 +177,8 @@ QWidget *SendCoinsEntry::setupTabChain(QWidget *prev)
|
|||
QWidget::setTabOrder(prev, ui->payTo);
|
||||
QWidget::setTabOrder(ui->payTo, 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->pasteButton, ui->deleteButton);
|
||||
return ui->deleteButton;
|
||||
|
|
|
@ -51,6 +51,7 @@ public slots:
|
|||
signals:
|
||||
void removeEntry(SendCoinsEntry *entry);
|
||||
void payAmountChanged();
|
||||
void subtractFeeFromAmountChanged();
|
||||
|
||||
private slots:
|
||||
void deleteClicked();
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
|
||||
#include "base58.h"
|
||||
#include "init.h"
|
||||
#include "wallet.h"
|
||||
#include "main.h" // For strMessageMagic
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "version.h"
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
|
|
|
@ -10,13 +10,13 @@
|
|||
#include "transactionrecord.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "db.h"
|
||||
#include "wallet/db.h"
|
||||
#include "main.h"
|
||||
#include "script/script.h"
|
||||
#include "timedata.h"
|
||||
#include "ui_interface.h"
|
||||
#include "util.h"
|
||||
#include "wallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
|
|
@ -5,11 +5,14 @@
|
|||
#include "transactionrecord.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "main.h"
|
||||
#include "timedata.h"
|
||||
#include "wallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
/* Return positive answer if transaction should be shown in list.
|
||||
*/
|
||||
bool TransactionRecord::showTransaction(const CWalletTx &wtx)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "sync.h"
|
||||
#include "uint256.h"
|
||||
#include "util.h"
|
||||
#include "wallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QDateTime>
|
||||
|
|
|
@ -29,7 +29,6 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
|
|||
ui(new Ui::HelpMessageDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
GUIUtil::restoreWindowGeometry("nHelpMessageDialogWindow", this->size(), this);
|
||||
|
||||
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
|
||||
|
@ -63,13 +62,17 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
|
|||
ui->helpMessage->setVisible(false);
|
||||
} else {
|
||||
setWindowTitle(tr("Command-line options"));
|
||||
QString header = tr("Usage:") + "\n" +
|
||||
" bitcoin-qt [" + tr("command-line options") + "] " + "\n";
|
||||
QTextCursor cursor(ui->helpMessage->document());
|
||||
cursor.insertText(version);
|
||||
cursor.insertBlock();
|
||||
cursor.insertText(tr("Usage:") + '\n' +
|
||||
" bitcoin-qt [" + tr("command-line options") + "]\n");
|
||||
|
||||
cursor.insertText(header);
|
||||
cursor.insertBlock();
|
||||
|
||||
QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT));
|
||||
text = version + "\n" + header + "\n" + coreOptions;
|
||||
|
||||
QTextTableFormat tf;
|
||||
tf.setBorderStyle(QTextFrameFormat::BorderStyle_None);
|
||||
tf.setCellPadding(2);
|
||||
|
@ -77,64 +80,30 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
|
|||
widths << QTextLength(QTextLength::PercentageLength, 35);
|
||||
widths << QTextLength(QTextLength::PercentageLength, 65);
|
||||
tf.setColumnWidthConstraints(widths);
|
||||
QTextTable *table = cursor.insertTable(2, 2, tf);
|
||||
|
||||
QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT));
|
||||
bool first = true;
|
||||
QTextCharFormat bold;
|
||||
bold.setFontWeight(QFont::Bold);
|
||||
// note that coreOptions is not translated.
|
||||
foreach (const QString &line, coreOptions.split('\n')) {
|
||||
if (!first) {
|
||||
table->appendRows(1);
|
||||
|
||||
foreach (const QString &line, coreOptions.split("\n")) {
|
||||
if (line.startsWith(" -"))
|
||||
{
|
||||
cursor.currentTable()->appendRows(1);
|
||||
cursor.movePosition(QTextCursor::PreviousCell);
|
||||
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->scrollArea->setVisible(false);
|
||||
ui->aboutLogo->setVisible(false);
|
||||
|
@ -143,7 +112,6 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
|
|||
|
||||
HelpMessageDialog::~HelpMessageDialog()
|
||||
{
|
||||
GUIUtil::saveWindowGeometry("nHelpMessageDialogWindow", this);
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,18 +6,19 @@
|
|||
|
||||
#include "addresstablemodel.h"
|
||||
#include "guiconstants.h"
|
||||
#include "guiutil.h"
|
||||
#include "paymentserver.h"
|
||||
#include "recentrequeststablemodel.h"
|
||||
#include "transactiontablemodel.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "db.h"
|
||||
#include "wallet/db.h"
|
||||
#include "keystore.h"
|
||||
#include "main.h"
|
||||
#include "sync.h"
|
||||
#include "ui_interface.h"
|
||||
#include "wallet.h"
|
||||
#include "walletdb.h" // for BackupWallet
|
||||
#include "wallet/wallet.h"
|
||||
#include "wallet/walletdb.h" // for BackupWallet
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -192,8 +193,9 @@ bool WalletModel::validateAddress(const QString &address)
|
|||
WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl)
|
||||
{
|
||||
CAmount total = 0;
|
||||
bool fSubtractFeeFromAmount = false;
|
||||
QList<SendCoinsRecipient> recipients = transaction.getRecipients();
|
||||
std::vector<std::pair<CScript, CAmount> > vecSend;
|
||||
std::vector<CRecipient> vecSend;
|
||||
|
||||
if(recipients.empty())
|
||||
{
|
||||
|
@ -206,6 +208,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
|||
// Pre-check input data for validity
|
||||
foreach(const SendCoinsRecipient &rcp, recipients)
|
||||
{
|
||||
if (rcp.fSubtractFeeFromAmount)
|
||||
fSubtractFeeFromAmount = true;
|
||||
|
||||
if (rcp.paymentRequest.IsInitialized())
|
||||
{ // PaymentRequest...
|
||||
CAmount subtotal = 0;
|
||||
|
@ -217,7 +222,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
|||
subtotal += out.amount();
|
||||
const unsigned char* scriptStr = (const unsigned char*)out.script().data();
|
||||
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)
|
||||
{
|
||||
|
@ -239,7 +246,8 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
|||
++nAddresses;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -260,17 +268,21 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
|||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
|
||||
transaction.newPossibleKeyChange(wallet);
|
||||
|
||||
CAmount nFeeRequired = 0;
|
||||
int nChangePosRet = -1;
|
||||
std::string strFailReason;
|
||||
|
||||
CWalletTx *newTx = transaction.getTransaction();
|
||||
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);
|
||||
if (fSubtractFeeFromAmount && fCreated)
|
||||
transaction.reassignAmounts(nChangePosRet);
|
||||
|
||||
if(!fCreated)
|
||||
{
|
||||
if((total + nFeeRequired) > nBalance)
|
||||
if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance)
|
||||
{
|
||||
return SendCoinsReturn(AmountWithFeeExceedsBalance);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "paymentrequestplus.h"
|
||||
#include "walletmodeltransaction.h"
|
||||
|
||||
#include "allocators.h" /* for SecureString */
|
||||
#include "support/allocators/secure.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
@ -36,9 +36,9 @@ QT_END_NAMESPACE
|
|||
class SendCoinsRecipient
|
||||
{
|
||||
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):
|
||||
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
|
||||
// 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.
|
||||
QString authenticatedMerchant;
|
||||
|
||||
bool fSubtractFeeFromAmount; // memory only
|
||||
|
||||
static const int CURRENT_VERSION = 1;
|
||||
int nVersion;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "walletmodeltransaction.h"
|
||||
|
||||
#include "wallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
|
||||
WalletModelTransaction::WalletModelTransaction(const QList<SendCoinsRecipient> &recipients) :
|
||||
recipients(recipients),
|
||||
|
@ -46,6 +46,38 @@ void WalletModelTransaction::setTransactionFee(const CAmount& 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 totalTransactionAmount = 0;
|
||||
|
|
|
@ -35,8 +35,10 @@ public:
|
|||
void newPossibleKeyChange(CWallet *wallet);
|
||||
CReserveKey *getPossibleKeyChange();
|
||||
|
||||
void reassignAmounts(int nChangePosRet); // needed for the subtract-fee-from-amount feature
|
||||
|
||||
private:
|
||||
const QList<SendCoinsRecipient> recipients;
|
||||
QList<SendCoinsRecipient> recipients;
|
||||
CWalletTx *walletTransaction;
|
||||
CReserveKey *keyChange;
|
||||
CAmount fee;
|
||||
|
|
|
@ -47,15 +47,16 @@ void RandAddSeedPerfmon()
|
|||
{
|
||||
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
|
||||
static int64_t nLastPerfmon;
|
||||
if (GetTime() < nLastPerfmon + 10 * 60)
|
||||
return;
|
||||
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);
|
||||
long ret = 0;
|
||||
unsigned long nSize = 0;
|
||||
|
|
|
@ -32,6 +32,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
|||
{ "getnetworkhashps", 0 },
|
||||
{ "getnetworkhashps", 1 },
|
||||
{ "sendtoaddress", 1 },
|
||||
{ "sendtoaddress", 4 },
|
||||
{ "settxfee", 0 },
|
||||
{ "getreceivedbyaddress", 1 },
|
||||
{ "getreceivedbyaccount", 1 },
|
||||
|
@ -59,6 +60,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
|||
{ "listsinceblock", 2 },
|
||||
{ "sendmany", 1 },
|
||||
{ "sendmany", 2 },
|
||||
{ "sendmany", 4 },
|
||||
{ "addmultisigaddress", 0 },
|
||||
{ "addmultisigaddress", 1 },
|
||||
{ "createmultisig", 0 },
|
||||
|
|
|
@ -13,9 +13,10 @@
|
|||
#include "pow.h"
|
||||
#include "rpcserver.h"
|
||||
#include "util.h"
|
||||
#include "validationinterface.h"
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "db.h"
|
||||
#include "wallet.h"
|
||||
#include "wallet/db.h"
|
||||
#include "wallet/wallet.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
#include "timedata.h"
|
||||
#include "util.h"
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet.h"
|
||||
#include "walletdb.h"
|
||||
#include "wallet/wallet.h"
|
||||
#include "wallet/walletdb.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "script/standard.h"
|
||||
#include "uint256.h"
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "util.h"
|
||||
#include "utilstrencodings.h"
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet.h"
|
||||
#include "wallet/wallet.h"
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "crypto/common.h"
|
||||
|
||||
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
|
||||
|
||||
|
@ -417,14 +418,16 @@ public:
|
|||
else if (b.size() <= 0xffff)
|
||||
{
|
||||
insert(end(), OP_PUSHDATA2);
|
||||
unsigned short nSize = b.size();
|
||||
insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
|
||||
uint8_t data[2];
|
||||
WriteLE16(data, b.size());
|
||||
insert(end(), data, data + sizeof(data));
|
||||
}
|
||||
else
|
||||
{
|
||||
insert(end(), OP_PUSHDATA4);
|
||||
unsigned int nSize = b.size();
|
||||
insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
|
||||
uint8_t data[4];
|
||||
WriteLE32(data, b.size());
|
||||
insert(end(), data, data + sizeof(data));
|
||||
}
|
||||
insert(end(), b.begin(), b.end());
|
||||
return *this;
|
||||
|
@ -497,15 +500,14 @@ public:
|
|||
{
|
||||
if (end() - pc < 2)
|
||||
return false;
|
||||
nSize = 0;
|
||||
memcpy(&nSize, &pc[0], 2);
|
||||
nSize = ReadLE16(&pc[0]);
|
||||
pc += 2;
|
||||
}
|
||||
else if (opcode == OP_PUSHDATA4)
|
||||
{
|
||||
if (end() - pc < 4)
|
||||
return false;
|
||||
memcpy(&nSize, &pc[0], 4);
|
||||
nSize = ReadLE32(&pc[0]);
|
||||
pc += 4;
|
||||
}
|
||||
if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize)
|
||||
|
|
|
@ -17,22 +17,31 @@ using namespace std;
|
|||
|
||||
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;
|
||||
if (!keystore.GetKey(address, key))
|
||||
if (!keystore->GetKey(address, key))
|
||||
return false;
|
||||
|
||||
vector<unsigned char> vchSig;
|
||||
uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType);
|
||||
if (!key.Sign(hash, vchSig))
|
||||
return false;
|
||||
vchSig.push_back((unsigned char)nHashType);
|
||||
scriptSigRet << vchSig;
|
||||
|
||||
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 nRequired = multisigdata.front()[0];
|
||||
|
@ -40,20 +49,20 @@ bool SignN(const vector<valtype>& multisigdata, const CKeyStore& keystore, uint2
|
|||
{
|
||||
const valtype& pubkey = multisigdata[i];
|
||||
CKeyID keyID = CPubKey(pubkey).GetID();
|
||||
if (Sign1(keyID, keystore, hash, nHashType, scriptSigRet))
|
||||
if (Sign1(keyID, creator, scriptCode, scriptSigRet))
|
||||
++nSigned;
|
||||
}
|
||||
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),
|
||||
* unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
|
||||
* Returns false if scriptPubKey could not be completely satisfied.
|
||||
*/
|
||||
bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash, int nHashType,
|
||||
CScript& scriptSigRet, txnouttype& whichTypeRet)
|
||||
static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey,
|
||||
CScript& scriptSigRet, txnouttype& whichTypeRet)
|
||||
{
|
||||
scriptSigRet.clear();
|
||||
|
||||
|
@ -71,39 +80,32 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
|
|||
return false;
|
||||
case TX_PUBKEY:
|
||||
keyID = CPubKey(vSolutions[0]).GetID();
|
||||
return Sign1(keyID, keystore, hash, nHashType, scriptSigRet);
|
||||
return Sign1(keyID, creator, scriptPubKey, scriptSigRet);
|
||||
case TX_PUBKEYHASH:
|
||||
keyID = CKeyID(uint160(vSolutions[0]));
|
||||
if (!Sign1(keyID, keystore, hash, nHashType, scriptSigRet))
|
||||
if (!Sign1(keyID, creator, scriptPubKey, scriptSigRet))
|
||||
return false;
|
||||
else
|
||||
{
|
||||
CPubKey vch;
|
||||
keystore.GetPubKey(keyID, vch);
|
||||
creator.KeyStore().GetPubKey(keyID, vch);
|
||||
scriptSigRet << ToByteVector(vch);
|
||||
}
|
||||
return true;
|
||||
case TX_SCRIPTHASH:
|
||||
return keystore.GetCScript(uint160(vSolutions[0]), scriptSigRet);
|
||||
return creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptSigRet);
|
||||
|
||||
case TX_MULTISIG:
|
||||
scriptSigRet << OP_0; // workaround CHECKMULTISIG bug
|
||||
return (SignN(vSolutions, keystore, hash, nHashType, scriptSigRet));
|
||||
return (SignN(vSolutions, creator, scriptPubKey, scriptSigRet));
|
||||
}
|
||||
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;
|
||||
if (!Solver(keystore, fromPubKey, hash, nHashType, txin.scriptSig, whichType))
|
||||
if (!SignStep(creator, fromPubKey, scriptSig, whichType))
|
||||
return false;
|
||||
|
||||
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;
|
||||
// the final scriptSig is the signatures from that
|
||||
// and then the serialized subscript:
|
||||
CScript subscript = txin.scriptSig;
|
||||
|
||||
// Recompute txn hash using subscript in place of scriptPubKey:
|
||||
uint256 hash2 = SignatureHash(subscript, txTo, nIn, nHashType);
|
||||
CScript subscript = scriptSig;
|
||||
|
||||
txnouttype subType;
|
||||
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:
|
||||
txin.scriptSig << static_cast<valtype>(subscript);
|
||||
scriptSig << static_cast<valtype>(subscript);
|
||||
if (!fSolved) return false;
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
@ -146,7 +156,7 @@ static CScript PushAll(const vector<valtype>& values)
|
|||
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>& sigs1, const vector<valtype>& sigs2)
|
||||
{
|
||||
|
@ -176,7 +186,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction&
|
|||
if (sigs.count(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;
|
||||
break;
|
||||
|
@ -201,7 +211,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction&
|
|||
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,
|
||||
vector<valtype>& sigs1, vector<valtype>& sigs2)
|
||||
{
|
||||
|
@ -235,12 +245,12 @@ static CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction
|
|||
Solver(pubKey2, txType2, vSolutions2);
|
||||
sigs1.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;
|
||||
return result;
|
||||
}
|
||||
case TX_MULTISIG:
|
||||
return CombineMultisig(scriptPubKey, txTo, nIn, vSolutions, sigs1, sigs2);
|
||||
return CombineMultisig(scriptPubKey, checker, vSolutions, sigs1, sigs2);
|
||||
}
|
||||
|
||||
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,
|
||||
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;
|
||||
vector<vector<unsigned char> > vSolutions;
|
||||
|
@ -258,5 +275,5 @@ CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo,
|
|||
vector<valtype> stack2;
|
||||
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