diff --git a/.travis.yml b/.travis.yml index cedd8bdf9..54ae74fd3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ # - A travis bug causes caches to trample eachother when using the same # compiler key (which we don't use anyway). This is worked around for now by # replacing the "compilers" with a build name prefixed by the no-op ":" -# command. See: https://github.com/travis-ci/casher/issues/6 +# command. See: https://github.com/travis-ci/travis-ci/issues/4393 os: linux language: cpp @@ -64,6 +64,7 @@ script: - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh - ./configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make distdir PACKAGE=bitcoin VERSION=$HOST + - if [ "$RUN_TESTS" = "true" ]; then contrib/devtools/check-doc.py; fi - cd bitcoin-$HOST - ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false ) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d42dea84..53d6527d4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -95,6 +95,8 @@ Anyone may participate in peer review which is expressed by comments in the pull - Concept ACK means "I agree in the general principle of this pull request"; - Nit refers to trivial, often non-blocking issues. +Reviewers should include the commit hash which they reviewed in their comments. + Project maintainers reserve the right to weigh the opinions of peer reviewers using common sense judgement and also may weight based on meritocracy: Those that have demonstrated a deeper commitment and understanding towards the project (over time) or have clear domain expertise may naturally have more weight, as one would expect in all walks of life. Where a patch set affects consensus critical code, the bar will be set much higher in terms of discussion and peer review requirements, keeping in mind that mistakes could be very costly to the wider community. This includes refactoring of consensus critical code. diff --git a/COPYING b/COPYING index 314d2e2ff..c6be8e547 100644 --- a/COPYING +++ b/COPYING @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2009-2015 The Bitcoin Core developers +Copyright (c) 2009-2016 The Bitcoin Core developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile.am b/Makefile.am index e293e4fc3..d6cbd7cb1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,6 +33,9 @@ OSX_QT_TRANSLATIONS = da,de,es,hu,ru,uk,zh_CN,zh_TW DIST_DOCS = $(wildcard doc/*.md) $(wildcard doc/release-notes/*.md) +BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \ + $(top_srcdir)/contrib/devtools/security-check.py + WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \ $(top_srcdir)/share/pixmaps/nsis-header.bmp \ $(top_srcdir)/share/pixmaps/nsis-wizard.bmp \ @@ -227,7 +230,7 @@ endif dist_noinst_SCRIPTS = autogen.sh -EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) +EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS) CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) diff --git a/README.md b/README.md index b40ad0e39..b568978f0 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Bitcoin Core integration/staging tree [![Build Status](https://travis-ci.org/bitcoin/bitcoin.svg?branch=master)](https://travis-ci.org/bitcoin/bitcoin) -https://www.bitcoin.org +https://bitcoincore.org What is Bitcoin? ---------------- @@ -15,13 +15,14 @@ out collectively by the network. Bitcoin Core is the name of open source software which enables the use of this currency. For more information, as well as an immediately useable, binary version of -the Bitcoin Core software, see https://www.bitcoin.org/en/download. +the Bitcoin Core software, see https://www.bitcoin.org/en/download, or read the +[original whitepaper](https://bitcoincore.org/bitcoin.pdf). License ------- Bitcoin Core is released under the terms of the MIT license. See [COPYING](COPYING) for more -information or see http://opensource.org/licenses/MIT. +information or see https://opensource.org/licenses/MIT. Development Process ------------------- @@ -48,7 +49,7 @@ lots of money. ### Automated Testing -Developers are strongly encouraged to write unit tests for new code, and to +Developers are strongly encouraged to write [unit tests](/doc/unit-tests.md) for new code, and to submit new unit tests for old code. Unit tests can be compiled and run (assuming they weren't disabled in configure) with: `make check` diff --git a/configure.ac b/configure.ac index 1ddb1f4a8..15350b197 100644 --- a/configure.ac +++ b/configure.ac @@ -1,14 +1,14 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) -define(_CLIENT_VERSION_MINOR, 11) +define(_CLIENT_VERSION_MINOR, 12) define(_CLIENT_VERSION_REVISION, 99) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, false) -define(_COPYRIGHT_YEAR, 2015) +define(_COPYRIGHT_YEAR, 2016) define(_COPYRIGHT_HOLDERS,[The %s developers]) define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[Bitcoin Core]) -AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/bitcoin/bitcoin/issues],[bitcoin],[http://bitcoin.org/]) +AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/bitcoin/bitcoin/issues],[bitcoin],[https://bitcoincore.org/]) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADERS([src/config/bitcoin-config.h]) AC_CONFIG_AUX_DIR([build-aux]) @@ -66,6 +66,8 @@ AC_PATH_PROG([GIT], [git]) AC_PATH_PROG(CCACHE,ccache) AC_PATH_PROG(XGETTEXT,xgettext) AC_PATH_PROG(HEXDUMP,hexdump) +AC_PATH_TOOL(READELF, readelf) +AC_PATH_TOOL(CPPFILT, c++filt) AC_ARG_VAR(PYTHONPATH, Augments the default search path for python module files) @@ -416,6 +418,10 @@ AX_GCC_FUNC_ATTRIBUTE([dllimport]) if test x$use_glibc_compat != xno; then + #glibc absorbed clock_gettime in 2.17. librt (its previous location) is safe to link + #in anyway for back-compat. + AC_CHECK_LIB([rt],[clock_gettime],, AC_MSG_ERROR(lib missing)) + #__fdelt_chk's params and return type have changed from long unsigned int to long int. # See which one is present here. AC_MSG_CHECKING(__fdelt_chk type) @@ -429,7 +435,8 @@ if test x$use_glibc_compat != xno; then [ fdelt_type="long int"]) AC_MSG_RESULT($fdelt_type) AC_DEFINE_UNQUOTED(FDELT_TYPE, $fdelt_type,[parameter and return value type for __fdelt_chk]) - +else + AC_SEARCH_LIBS([clock_gettime],[rt]) fi if test x$TARGET_OS != xwindows; then @@ -496,8 +503,6 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [ AC_MSG_RESULT(no)] ) -AC_SEARCH_LIBS([clock_gettime],[rt]) - AC_MSG_CHECKING([for visibility attribute]) AC_LINK_IFELSE([AC_LANG_SOURCE([ int foo_def( void ) __attribute__((visibility("default"))); @@ -626,6 +631,42 @@ if test x$use_boost = xyes; then BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" + +dnl If boost (prior to 1.57) was built without c++11, it emulated scoped enums +dnl using c++98 constructs. Unfortunately, this implementation detail leaked into +dnl the abi. This was fixed in 1.57. + +dnl When building against that installed version using c++11, the headers pick up +dnl on the native c++11 scoped enum support and enable it, however it will fail to +dnl link. This can be worked around by disabling c++11 scoped enums if linking will +dnl fail. +dnl BOOST_NO_SCOPED_ENUMS was changed to BOOST_NO_CXX11_SCOPED_ENUMS in 1.51. + +TEMP_LIBS="$LIBS" +LIBS="$BOOST_LIBS $LIBS" +TEMP_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" +AC_MSG_CHECKING([for mismatched boost c++11 scoped enums]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include "boost/config.hpp" + #include "boost/version.hpp" + #if !defined(BOOST_NO_SCOPED_ENUMS) && !defined(BOOST_NO_CXX11_SCOPED_ENUMS) && BOOST_VERSION < 105700 + #define BOOST_NO_SCOPED_ENUMS + #define BOOST_NO_CXX11_SCOPED_ENUMS + #define CHECK + #endif + #include "boost/filesystem.hpp" + ]],[[ + #if defined(CHECK) + boost::filesystem::copy_file("foo", "bar"); + #else + choke; + #endif + ]])], + [AC_MSG_RESULT(mismatched); BOOST_CPPFLAGS="$BOOST_CPPFLAGS -DBOOST_NO_SCOPED_ENUMS -DBOOST_NO_CXX11_SCOPED_ENUMS"], [AC_MSG_RESULT(ok)]) +LIBS="$TEMP_LIBS" +CPPFLAGS="$TEMP_CPPFLAGS" + dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however dnl it was broken from 1.50 to 1.52 when backed by nanosleep. Use sleep_for if dnl a working version is available, else fall back to sleep. sleep was removed @@ -907,6 +948,7 @@ 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([HARDEN],[test x$use_hardening = xyes]) AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version]) AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version]) diff --git a/contrib/README.md b/contrib/README.md index 125594312..b6e572102 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -11,10 +11,10 @@ Repository Tools ### [Developer tools](/contrib/devtools) ### Specific tools for developers working on this repository. -Contains the script `github-merge.sh` for merging github pull requests securely and signing them using GPG. +Contains the script `github-merge.py` 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. +Tool to verify that every merge commit was signed by a developer using the above `github-merge.py` script. ### [Linearize](/contrib/linearize) ### Construct a linear, no-fork, best version of the blockchain. diff --git a/contrib/debian/control b/contrib/debian/control index 490b2571c..fce6bc011 100644 --- a/contrib/debian/control +++ b/contrib/debian/control @@ -23,7 +23,7 @@ Build-Depends: debhelper, libprotobuf-dev, protobuf-compiler, python Standards-Version: 3.9.2 -Homepage: https://www.bitcoin.org/ +Homepage: https://bitcoincore.org/ Vcs-Git: git://github.com/bitcoin/bitcoin.git Vcs-Browser: https://github.com/bitcoin/bitcoin diff --git a/contrib/debian/copyright b/contrib/debian/copyright index 83ce560a7..c039a7bae 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -5,7 +5,7 @@ Upstream-Contact: Satoshi Nakamoto Source: https://github.com/bitcoin/bitcoin Files: * -Copyright: 2009-2015, Bitcoin Core Developers +Copyright: 2009-2016, Bitcoin Core Developers License: Expat Comment: The Bitcoin Core Developers encompasses the current developers listed on bitcoin.org, as well as the numerous contributors to the project. @@ -21,6 +21,7 @@ License: GPL-3+ Files: src/qt/res/icons/add.png src/qt/res/icons/address-book.png + src/qt/res/icons/chevron.png src/qt/res/icons/configure.png src/qt/res/icons/debugwindow.png src/qt/res/icons/edit.png @@ -56,6 +57,8 @@ Comment: Inspired by Stephan Hutchings Typicons Files: src/qt/res/icons/tx_mined.png src/qt/res/src/mine.svg + src/qt/res/icons/fontbigger.png + src/qt/res/icons/fontsmaller.png Copyright: Jonas Schnelli License: Expat Comment: diff --git a/contrib/debian/manpages/bitcoin-cli.1 b/contrib/debian/manpages/bitcoin-cli.1 index 154b45873..16c338dd3 100644 --- a/contrib/debian/manpages/bitcoin-cli.1 +++ b/contrib/debian/manpages/bitcoin-cli.1 @@ -1,4 +1,4 @@ -.TH BITCOIN-CLI "1" "February 2015" "bitcoin-cli 0.10" +.TH BITCOIN-CLI "1" "February 2016" "bitcoin-cli 0.12" .SH NAME bitcoin-cli \- a remote procedure call client for Bitcoin Core. .SH SYNOPSIS @@ -11,31 +11,7 @@ This manual page documents the bitcoin-cli program. bitcoin-cli is an RPC client .SH OPTIONS .TP \fB\-?\fR -Show the help message. -.TP -\fB\-conf=\fR -Specify configuration file (default: bitcoin.conf). -.TP -\fB\-datadir=\fR -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 -Username for JSON\-RPC connections. -.TP -\fB\-rpcpassword=\fR -Password for JSON\-RPC connections. -.TP -\fB\-rpcport=\fR -Listen for JSON\-RPC connections on (default: 8332 or testnet: 18332). -.TP -\fB\-rpcconnect=\fR -Send commands to node running on (default: 127.0.0.1). +Show possible options. .SH "SEE ALSO" \fBbitcoind\fP, \fBbitcoin.conf\fP diff --git a/contrib/debian/manpages/bitcoin-qt.1 b/contrib/debian/manpages/bitcoin-qt.1 index 05eadc94c..685a28208 100644 --- a/contrib/debian/manpages/bitcoin-qt.1 +++ b/contrib/debian/manpages/bitcoin-qt.1 @@ -1,4 +1,4 @@ -.TH BITCOIN-QT "1" "April 2013" "bitcoin-qt 1" +.TH BITCOIN-QT "1" "February 2016" "bitcoin-qt 0.12" .SH NAME bitcoin-qt \- peer-to-peer network based digital currency .SH DESCRIPTION @@ -8,184 +8,6 @@ bitcoin\-qt [command\-line options] .SH OPTIONS .TP \-? -This help message -.TP -\fB\-conf=\fR -Specify configuration file (default: bitcoin.conf) -.TP -\fB\-pid=\fR -Specify pid file (default: bitcoind.pid) -.TP -\fB\-gen\fR -Generate coins -.TP -\fB\-gen\fR=\fI0\fR -Don't generate coins -.TP -\fB\-datadir=\fR -Specify data directory -.TP -\fB\-dbcache=\fR -Set database cache size in megabytes (default: 25) -.TP -\fB\-timeout=\fR -Specify connection timeout in milliseconds (default: 5000) -.TP -\fB\-proxy=\fR -Connect through SOCKS5 proxy -.TP -\fB\-tor=\fR -Use proxy to reach tor hidden services (default: same as \fB\-proxy\fR) -.TP -\fB\-dns\fR -Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR -.TP -\fB\-port=\fR -Listen for connections on (default: 8333 or testnet: 18333) -.TP -\fB\-maxconnections=\fR -Maintain at most connections to peers (default: 125) -.TP -\fB\-addnode=\fR -Add a node to connect to and attempt to keep the connection open -.TP -\fB\-connect=\fR -Connect only to the specified node(s) -.TP -\fB\-seednode=\fR -Connect to a node to retrieve peer addresses, and disconnect -.TP -\fB\-externalip=\fR -Specify your own public address -.TP -\fB\-onlynet=\fR -Only connect to nodes in network (IPv4, IPv6 or Tor) -.TP -\fB\-discover\fR -Discover own IP address (default: 1 when listening and no \fB\-externalip\fR) -.TP -\fB\-checkpoints\fR -Only accept block chain matching built\-in checkpoints (default: 1) -.TP -\fB\-listen\fR -Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR) -.TP -\fB\-bind=\fR -Bind to given address and always listen on it. Use [host]:port notation for IPv6 -.TP -\fB\-dnsseed\fR -Find peers using DNS lookup (default: 1 unless \fB\-connect\fR) -.TP -\fB\-banscore=\fR -Threshold for disconnecting misbehaving peers (default: 100) -.TP -\fB\-bantime=\fR -Number of seconds to keep misbehaving peers from reconnecting (default: 86400) -.TP -\fB\-maxreceivebuffer=\fR -Maximum per\-connection receive buffer, *1000 bytes (default: 5000) -.TP -\fB\-maxsendbuffer=\fR -Maximum per\-connection send buffer, *1000 bytes (default: 1000) -.TP -\fB\-upnp\fR -Use UPnP to map the listening port (default: 1 when listening) -.TP -\fB\-paytxfee=\fR -Fee per KB to add to transactions you send -.TP -\fB\-server\fR -Accept command line and JSON\-RPC commands -.TP -\fB\-testnet\fR -Use the test network -.TP -\fB\-debug\fR -Output extra debugging information. Implies all other \fB\-debug\fR* options -.TP -\fB\-debugnet\fR -Output extra network debugging information -.TP -\fB\-logtimestamps\fR -Prepend debug output with timestamp -.TP -\fB\-shrinkdebugfile\fR -Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR) -.TP -\fB\-printtoconsole\fR -Send trace/debug info to console instead of debug.log file -.TP -\fB\-rpcuser=\fR -Username for JSON\-RPC connections -.TP -\fB\-rpcpassword=\fR -Password for JSON\-RPC connections -.TP -\fB\-rpcport=\fR -Listen for JSON\-RPC connections on (default: 8332 or testnet: 18332) -.TP -\fB\-rpcallowip=\fR -Allow JSON\-RPC connections from specified IP address -.TP -\fB\-rpcthreads=\fR -Set the number of threads to service RPC calls (default: 4) -.TP -\fB\-blocknotify=\fR -Execute command when the best block changes (%s in cmd is replaced by block hash) -.TP -\fB\-walletnotify=\fR -Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) -.TP -\fB\-alertnotify=\fR -Execute command when a relevant alert is received (%s in cmd is replaced by message) -.TP -\fB\-upgradewallet\fR -Upgrade wallet to latest format -.TP -\fB\-keypool=\fR -Set key pool size to (default: 100) -.TP -\fB\-rescan\fR -Rescan the block chain for missing wallet transactions -.TP -\fB\-salvagewallet\fR -Attempt to recover private keys from a corrupt wallet.dat -.TP -\fB\-checkblocks=\fR -How many blocks to check at startup (default: 288, 0 = all) -.TP -\fB\-checklevel=\fR -How thorough the block verification is (0\-4, default: 3) -.TP -\fB\-txindex\fR -Maintain a full transaction index (default: 0) -.TP -\fB\-loadblock=\fR -Imports blocks from external blk000??.dat file -.TP -\fB\-reindex\fR -Rebuild block chain index from current blk000??.dat files -.TP -\fB\-par=\fR -Set the number of script verification threads (1\-16, 0=auto, default: 0) -.SS "Block creation options:" -.TP -\fB\-blockminsize=\fR -Set minimum block size in bytes (default: 0) -.TP -\fB\-blockmaxsize=\fR -Set maximum block size in bytes (default: 250000) -.HP -\fB\-blockprioritysize=\fR Set maximum size of high\-priority/low\-fee transactions in bytes (default: 27000) -.PP -Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) -.SS "UI options:" -.TP -\fB\-lang=\fR -Set language, for example "de_DE" (default: system locale) -.TP -\fB\-min\fR -Start minimized -.TP -\fB\-splash\fR -Show splash screen on startup (default: 1) +List options. +.SH "SEE ALSO" +bitcoind(1) diff --git a/contrib/debian/manpages/bitcoin.conf.5 b/contrib/debian/manpages/bitcoin.conf.5 index 0cf4d991e..839dc26c1 100644 --- a/contrib/debian/manpages/bitcoin.conf.5 +++ b/contrib/debian/manpages/bitcoin.conf.5 @@ -1,75 +1,15 @@ -.TH BITCOIN.CONF "5" "January 2011" "bitcoin.conf 3.19" +.TH BITCOIN.CONF "5" "February 2016" "bitcoin.conf 0.12" .SH NAME bitcoin.conf \- bitcoin configuration file .SH SYNOPSIS All command-line options (except for '\-conf') may be specified in a configuration file, and all configuration file options may also be specified on the command line. Command-line options override values set in the configuration file. .TP -The configuration file is a list of 'setting=value' pairs, one per line, with optional comments starting with the '#' character. +The configuration file is a list of 'setting=value' pairs, one per line, with optional comments starting with the '#' character. Please refer to bitcoind(1) for a up to date list of valid options. .TP The configuration file is not automatically created; you can create it using your favorite plain-text editor. By default, bitcoind(1) will look for a file named bitcoin.conf(5) in the bitcoin data directory, but both the data directory and the configuration file path may be changed using the '\-datadir' and '\-conf' command-line arguments. .SH LOCATION bitcoin.conf should be located in $HOME/.bitcoin -.SH NETWORK-RELATED SETTINGS -.TP -.TP -\fBtestnet=\fR[\fI'1'\fR|\fI'0'\fR] -Enable or disable run on the test network instead of the real *bitcoin* network. -.TP -\fBproxy=\fR\fI'127.0.0.1:9050'\fR -Connect via a socks4 proxy. -.TP -\fBaddnode=\fR\fI'10.0.0.2:8333'\fR -Use as many *addnode=* settings as you like to connect to specific peers. -.TP -\fBconnect=\fR\fI'10.0.0.1:8333'\fR -Use as many *connect=* settings as you like to connect ONLY to specific peers. -.TP -\fRmaxconnections=\fR\fI'value'\fR -Maximum number of inbound+outbound connections. -.SH JSON-RPC OPTIONS -.TP -\fBserver=\fR[\fI'1'\fR|\fI'0'\fR] -Tells *bitcoin* to accept or not accept JSON-RPC commands. -.TP -\fBrpcuser=\fR\fI'username'\fR -You must set *rpcuser* to secure the JSON-RPC api. -.TP -\fBrpcpassword=\fR\fI'password'\fR -You must set *rpcpassword* to secure the JSON-RPC api. -.TP -\fBrpcallowip=\fR\fI'192.168.1.*'\fR -By default, only RPC connections from localhost are allowed. Specify as many *rpcallowip=* settings as you like to allow connections from other hosts (and you may use * as a wildcard character). -.TP -\fBrpcport=\fR\fI'8332'\fR -Listen for RPC connections on this TCP port. -.TP -\fBrpcconnect=\fR\fI'127.0.0.1'\fR -You can use *bitcoin* or *bitcoind(1)* to send commands to *bitcoin*/*bitcoind(1)* running on another host using this option. -.TP -.SH MISCELLANEOUS OPTIONS -.TP -\fBgen=\fR[\fI'0'\fR|\fI'1'\fR] -Enable or disable attempt to generate bitcoins. -.TP -\fB4way=\fR[\fI'0'\fR|\fI'1'\fR] -Enable or disable use SSE instructions to try to generate bitcoins faster. -.TP -\fBkeypool=\fR\fI'100'\fR -Pre-generate this many public/private key pairs, so wallet backups will be valid for both prior transactions and several dozen future transactions. -.TP -\fBpaytxfee=\fR\fI'0.00'\fR -Pay an optional transaction fee every time you send bitcoins. Transactions with fees are more likely than free transactions to be included in generated blocks, so may be validated sooner. -.TP -\fBallowreceivebyip=\fR\fI'1'\fR -Allow direct connections for the 'pay via IP address' feature. -.TP -.SH USER INTERFACE OPTIONS -.TP -\fBmin=\fR[\fI'0'\fR|\fI'1'\fR] -Enable or disable start bitcoind minimized. -.TP -\fBminimizetotray=\fR[\fI'0'\fR|\fI'1'\fR] -Enable or disable minimize to the system tray. + .SH "SEE ALSO" bitcoind(1) .SH AUTHOR diff --git a/contrib/debian/manpages/bitcoind.1 b/contrib/debian/manpages/bitcoind.1 index 5b0f2921a..5c3e52f44 100644 --- a/contrib/debian/manpages/bitcoind.1 +++ b/contrib/debian/manpages/bitcoind.1 @@ -1,4 +1,4 @@ -.TH BITCOIND "1" "January 2011" "bitcoind 3.19" +.TH BITCOIND "1" "February 2016" "bitcoind 0.12" .SH NAME bitcoind \- peer-to-peer network based digital currency .SH SYNOPSIS @@ -6,185 +6,20 @@ bitcoin [options] [params] .TP bitcoin [options] help \- Get help for a command .SH DESCRIPTION -This manual page documents the bitcoind program. Bitcoin is a peer-to-peer digital currency. Peer-to-peer (P2P) means that there is no central authority to issue new money or keep track of transactions. Instead, these tasks are managed collectively by the nodes of the network. Advantages: - -Bitcoins can be sent easily through the Internet, without having to trust middlemen. Transactions are designed to be irreversible. Be safe from instability caused by fractional reserve banking and central banks. The limited inflation of the Bitcoin system’s money supply is distributed evenly (by CPU power) throughout the network, not monopolized by banks. +This manual page documents the bitcoind program. Bitcoin is an experimental new digital currency that enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate with no central authority: managing transactions and issuing money are carried out collectively by the network. Bitcoin Core is the name of open source software which enables the use of this currency. .SH OPTIONS .TP -\fB\-conf=\fR -Specify configuration file (default: bitcoin.conf) -.TP -\fB\-gen\fR -Generate coins -.TP -\fB\-gen\fR=\fI0\fR -Don't generate coins -.TP -\fB\-min\fR -Start minimized -.TP -\fB\-datadir=\fR -Specify data directory -.TP -\fB\-proxy=\fR -Connect through SOCKS5 proxy -.TP -\fB\-addnode=\fR -Add a node to connect to -.TP -\fB\-connect=\fR -Connect only to the specified node -.TP -\fB\-paytxfee=\fR -Fee per KB to add to transactions you send -.TP -\fB\-server\fR -Accept command line and JSON\-RPC commands -.TP -\fB\-daemon\fR -Run in the background as a daemon and accept commands -.TP -\fB\-testnet\fR -Use the test network -.TP -\fB\-rpcuser=\fR -Username for JSON\-RPC connections -.TP -\fB\-rpcpassword=\fR -Password for JSON\-RPC connections -.TP -\fB\-rpcport=\fR -Listen for JSON\-RPC connections on -.TP -\fB\-rpcallowip=\fR -Allow JSON\-RPC connections from specified IP address -.TP -\fB\-rpcconnect=\fR -Send commands to node running on -.TP \-? -This help message +List of possible options. .SH COMMANDS .TP -\fBbackupwallet 'destination'\fR -Safely copies *wallet.dat* to 'destination', which can be a directory or a path with filename. -.TP -\fBgetaccount 'bitcoinaddress'\fR -DEPRECATED. Returns the account associated with the given address. -.TP -\fBsetaccount 'bitcoinaddress' ['account']\fR -DEPRECATED. Sets the ['account'] associated with the given address. ['account'] may be omitted to remove an address from ['account']. -.TP -\fBgetaccountaddress 'account'\fR -DEPRECATED. Returns a new bitcoin address for 'account'. -.TP -\fBgetaddressesbyaccount 'account'\fR -DEPRECATED. Returns the list of addresses associated with the given 'account'. -.TP -\fBgetbalance 'account'\fR -Returns the server's available balance, or the balance for 'account' (accounts are deprecated). -.TP -\fBgetblockcount\fR -Returns the number of blocks in the longest block chain. -.TP -\fBgetblocknumber\fR -Returns the block number of the latest block in the longest block chain. -.TP -\fBgetconnectioncount\fR -Returns the number of connections to other nodes. -.TP -\fBgetdifficulty\fR -Returns the proof-of-work difficulty as a multiple of the minimum difficulty. -.TP -\fBgetgenerate\fR -Returns boolean true if server is trying to generate bitcoins, false otherwise. -.TP -\fBsetgenerate 'generate' ['genproclimit']\fR -Generation is limited to ['genproclimit'] processors, \-1 is unlimited. -.TP -\fBgethashespersec\fR -Returns a recent hashes per second performance measurement while generating. -.TP -\fBgetinfo\fR -Returns an object containing server information. -.TP -\fBgetnewaddress 'account'\fR -Returns a new bitcoin address for receiving payments. If 'account' is specified (deprecated), it is added to the address book so payments received with the address will be credited to 'account'. -.TP -\fBgetreceivedbyaccount 'account' ['minconf=1']\fR -DEPRECATED. Returns the total amount received by addresses associated with 'account' in transactions with at least ['minconf'] confirmations. -.TP -\fBgetreceivedbyaddress 'bitcoinaddress' ['minconf=1']\fR -Returns the total amount received by 'bitcoinaddress' in transactions with at least ['minconf'] confirmations. -.TP -\fBgettransaction 'txid'\fR -Returns information about a specific transaction, given hexadecimal transaction ID. -.TP -\fBgetwork 'data'\fR -If 'data' is specified, tries to solve the block and returns true if it was successful. If 'data' is not specified, returns formatted hash 'data' to work on: +\fBhelp\fR +List commands. - "midstate" : precomputed hash state after hashing the first half of the data. - "data" : block data. - "hash1" : formatted hash buffer for second hash. - "target" : little endian hash target. .TP \fBhelp 'command'\fR -List commands, or get help for a command. -.TP -\fBlistaccounts ['minconf=1']\fR -DEPRECATED. List accounts and their current balances. - *note: requires bitcoin 0.3.20 or later. -.TP -\fBlistreceivedbyaccount ['minconf=1'] ['includeempty=false']\fR -['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing: - - "account" : DEPRECATED. the account of the receiving address. - "amount" : total amount received by the address. - "confirmations" : number of confirmations of the most recent transaction included. -.TP -\fBlistreceivedbyaddress ['minconf=1'] ['includeempty=false']\fR -['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing: - - "address" : receiving address. - "account" : DEPRECATED. the account of the receiving address. - "amount" : total amount received by the address. - "confirmations" : number of confirmations of the most recent transaction included. -.TP -\fBlisttransactions 'account' ['count=10']\fR -Returns a list of the last ['count'] transactions for 'account' \- for all accounts if 'account' is not specified or is "*". Each entry in the list may contain: - - "category" : will be generate, send, receive, or move. - "amount" : amount of transaction. - "fee" : Fee (if any) paid (only for send transactions). - "confirmations" : number of confirmations (only for generate/send/receive). - "txid" : transaction ID (only for generate/send/receive). - "otheraccount" : account funds were moved to or from (only for move). - "message" : message associated with transaction (only for send). - "to" : message-to associated with transaction (only for send). - - *note: requires bitcoin 0.3.20 or later. -.TP -\fBmove <'fromaccount'> <'toaccount'> <'amount'> ['minconf=1'] ['comment']\fR -DEPRECATED. Moves funds between accounts. -.TP -\fBsendfrom* <'account'> <'bitcoinaddress'> <'amount'> ['minconf=1'] ['comment'] ['comment-to']\fR -DEPRECATED. Sends amount from account's balance to 'bitcoinaddress'. This method will fail if there is less than amount bitcoins with ['minconf'] confirmations in the account's balance (unless account is the empty-string-named default account; it behaves like the *sendtoaddress* method). Returns transaction ID on success. -.TP -\fBsendtoaddress 'bitcoinaddress' 'amount' ['comment'] ['comment-to']\fR -Sends amount from the server's available balance to 'bitcoinaddress'. amount is a real and is rounded to the nearest 0.01. Returns transaction id on success. -.TP -\fBstop\fR -Stops the bitcoin server. -.TP -\fBvalidateaddress 'bitcoinaddress'\fR -Checks that 'bitcoinaddress' looks like a proper bitcoin address. Returns an object containing: - - "isvalid" : true or false. - "ismine" : true if the address is in the server's wallet. - "address" : bitcoinaddress. - - *note: ismine and address are only returned if the address is valid. +Get help for a command. .SH "SEE ALSO" bitcoin.conf(5) diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index 2e70c5adc..1103ca86c 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -2,19 +2,68 @@ Contents ======== This directory contains tools for developers working on this repository. +check-doc.py +============ + +Check if all command line args are documented. The return value indicates the +number of undocumented args. + clang-format.py =============== A script to format cpp source code according to [.clang-format](../../src/.clang-format). This should only be applied to new files or files which are currently not actively developed on. Also, git subtrees are not subject to formatting. -github-merge.sh +clang-format-diff.py +=================== + +A script to format unified git diffs according to [.clang-format](../../src/.clang-format). + +For instance, to format the last commit with 0 lines of context, +the script should be called from the git root folder as follows. + +``` +git diff -U0 HEAD~1.. | ./contrib/devtools/clang-format-diff.py -p1 -i -v +``` + +fix-copyright-headers.py +======================== + +Every year newly updated files need to have its copyright headers updated to reflect the current year. +If you run this script from the root folder it will automatically update the year on the copyright header for all +source files if these have a git commit from the current year. + +For example a file changed in 2015 (with 2015 being the current year): + +```// Copyright (c) 2009-2013 The Bitcoin Core developers``` + +would be changed to: + +```// Copyright (c) 2009-2015 The Bitcoin Core developers``` + +git-subtree-check.sh +==================== + +Run this script from the root of the repository to verify that a subtree matches the contents of +the commit it claims to have been updated to. + +To use, make sure that you have fetched the upstream repository branch in which the subtree is +maintained: +* for `src/secp256k1`: https://github.com/bitcoin/secp256k1.git (branch master) +* for `src/leveldb`: https://github.com/bitcoin/leveldb.git (branch bitcoin-fork) +* for `src/univalue`: https://github.com/bitcoin/univalue.git (branch master) + +Usage: `git-subtree-check.sh DIR COMMIT` + +`COMMIT` may be omitted, in which case `HEAD` is used. + +github-merge.py =============== A small script to automate merging pull-requests securely and sign them with GPG. For example: - ./github-merge.sh bitcoin/bitcoin 3077 + ./github-merge.py 3077 (in any git repository) will help you merge pull request #3077 for the bitcoin/bitcoin repository. @@ -41,21 +90,6 @@ Configuring the github-merge tool for the bitcoin repository is done in the foll git config githubmerge.testcmd "make -j4 check" (adapt to whatever you want to use for testing) git config --global user.signingkey mykeyid (if you want to GPG sign) -fix-copyright-headers.py -======================== - -Every year newly updated files need to have its copyright headers updated to reflect the current year. -If you run this script from src/ it will automatically update the year on the copyright header for all -.cpp and .h files if these have a git commit from the current year. - -For example a file changed in 2014 (with 2014 being the current year): - -```// Copyright (c) 2009-2013 The Bitcoin Core developers``` - -would be changed to: - -```// Copyright (c) 2009-2014 The Bitcoin Core developers``` - optimize-pngs.py ================ @@ -98,18 +132,3 @@ It will do the following automatically: - add missing translations to the build system (TODO) See doc/translation-process.md for more information. - -git-subtree-check.sh -==================== - -Run this script from the root of the repository to verify that a subtree matches the contents of -the commit it claims to have been updated to. - -To use, make sure that you have fetched the upstream repository branch in which the subtree is -maintained: -* for src/secp256k1: https://github.com/bitcoin/secp256k1.git (branch master) -* for sec/leveldb: https://github.com/bitcoin/leveldb.git (branch bitcoin-fork) - -Usage: git-subtree-check.sh DIR COMMIT - -COMMIT may be omitted, in which case HEAD is used. diff --git a/contrib/devtools/check-doc.py b/contrib/devtools/check-doc.py new file mode 100755 index 000000000..8c73cf1e8 --- /dev/null +++ b/contrib/devtools/check-doc.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +''' +This checks if all command line args are documented. +Return value is 0 to indicate no error. + +Author: @MarcoFalke +''' + +from subprocess import check_output +import re + +FOLDER_GREP = 'src' +FOLDER_TEST = 'src/test/' +CMD_ROOT_DIR = '`git rev-parse --show-toplevel`/%s' % FOLDER_GREP +CMD_GREP_ARGS = r"egrep -r -I '(map(Multi)?Args(\.count\(|\[)|Get(Bool)?Arg\()\"\-[^\"]+?\"' %s | grep -v '%s'" % (CMD_ROOT_DIR, FOLDER_TEST) +CMD_GREP_DOCS = r"egrep -r -I 'HelpMessageOpt\(\"\-[^\"=]+?(=|\")' %s" % (CMD_ROOT_DIR) +REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"') +REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")') +# list unsupported, deprecated and duplicate args as they need no documentation +SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay']) + +def main(): + used = check_output(CMD_GREP_ARGS, shell=True) + docd = check_output(CMD_GREP_DOCS, shell=True) + + args_used = set(re.findall(REGEX_ARG,used)) + args_docd = set(re.findall(REGEX_DOC,docd)).union(SET_DOC_OPTIONAL) + args_need_doc = args_used.difference(args_docd) + args_unknown = args_docd.difference(args_used) + + print "Args used : %s" % len(args_used) + print "Args documented : %s" % len(args_docd) + print "Args undocumented: %s" % len(args_need_doc) + print args_need_doc + print "Args unknown : %s" % len(args_unknown) + print args_unknown + + exit(len(args_need_doc)) + +if __name__ == "__main__": + main() diff --git a/contrib/devtools/clang-format-diff.py b/contrib/devtools/clang-format-diff.py new file mode 100755 index 000000000..13d2573b9 --- /dev/null +++ b/contrib/devtools/clang-format-diff.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python +# +#===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===# +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. +# +# ============================================================ +# +# University of Illinois/NCSA +# Open Source License +# +# Copyright (c) 2007-2015 University of Illinois at Urbana-Champaign. +# All rights reserved. +# +# Developed by: +# +# LLVM Team +# +# University of Illinois at Urbana-Champaign +# +# http://llvm.org +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal with +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimers. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimers in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the names of the LLVM Team, University of Illinois at +# Urbana-Champaign, nor the names of its contributors may be used to +# endorse or promote products derived from this Software without specific +# prior written permission. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +# SOFTWARE. +# +# ============================================================ +# +#===------------------------------------------------------------------------===# + +r""" +ClangFormat Diff Reformatter +============================ + +This script reads input from a unified diff and reformats all the changed +lines. This is useful to reformat all the lines touched by a specific patch. +Example usage for git/svn users: + + git diff -U0 HEAD^ | clang-format-diff.py -p1 -i + svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i + +""" + +import argparse +import difflib +import re +import string +import subprocess +import StringIO +import sys + + +# Change this to the full path if clang-format is not on the path. +binary = 'clang-format' + + +def main(): + parser = argparse.ArgumentParser(description= + 'Reformat changed lines in diff. Without -i ' + 'option just output the diff that would be ' + 'introduced.') + parser.add_argument('-i', action='store_true', default=False, + help='apply edits to files instead of displaying a diff') + parser.add_argument('-p', metavar='NUM', default=0, + help='strip the smallest prefix containing P slashes') + parser.add_argument('-regex', metavar='PATTERN', default=None, + help='custom pattern selecting file paths to reformat ' + '(case sensitive, overrides -iregex)') + parser.add_argument('-iregex', metavar='PATTERN', default= + r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc|js|ts|proto' + r'|protodevel|java)', + help='custom pattern selecting file paths to reformat ' + '(case insensitive, overridden by -regex)') + parser.add_argument('-sort-includes', action='store_true', default=False, + help='let clang-format sort include blocks') + parser.add_argument('-v', '--verbose', action='store_true', + help='be more verbose, ineffective without -i') + args = parser.parse_args() + + # Extract changed lines for each file. + filename = None + lines_by_file = {} + for line in sys.stdin: + match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line) + if match: + filename = match.group(2) + if filename == None: + continue + + if args.regex is not None: + if not re.match('^%s$' % args.regex, filename): + continue + else: + if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE): + continue + + match = re.search('^@@.*\+(\d+)(,(\d+))?', line) + if match: + start_line = int(match.group(1)) + line_count = 1 + if match.group(3): + line_count = int(match.group(3)) + if line_count == 0: + continue + end_line = start_line + line_count - 1; + lines_by_file.setdefault(filename, []).extend( + ['-lines', str(start_line) + ':' + str(end_line)]) + + # Reformat files containing changes in place. + for filename, lines in lines_by_file.iteritems(): + if args.i and args.verbose: + print 'Formatting', filename + command = [binary, filename] + if args.i: + command.append('-i') + if args.sort_includes: + command.append('-sort-includes') + command.extend(lines) + command.extend(['-style=file', '-fallback-style=none']) + p = subprocess.Popen(command, stdout=subprocess.PIPE, + stderr=None, stdin=subprocess.PIPE) + stdout, stderr = p.communicate() + if p.returncode != 0: + sys.exit(p.returncode); + + if not args.i: + with open(filename) as f: + code = f.readlines() + formatted_code = StringIO.StringIO(stdout).readlines() + diff = difflib.unified_diff(code, formatted_code, + filename, filename, + '(before formatting)', '(after formatting)') + diff_string = string.join(diff, '') + if len(diff_string) > 0: + sys.stdout.write(diff_string) + +if __name__ == '__main__': + main() diff --git a/contrib/devtools/fix-copyright-headers.py b/contrib/devtools/fix-copyright-headers.py index 5e8495254..b6414a551 100755 --- a/contrib/devtools/fix-copyright-headers.py +++ b/contrib/devtools/fix-copyright-headers.py @@ -1,53 +1,46 @@ #!/usr/bin/env python ''' -Run this script inside of src/ and it will look for all the files -that were changed this year that still have the last year in the -copyright headers, and it will fix the headers on that file using -a perl regex one liner. +Run this script to update all the copyright headers of files +that were changed this year. -For example: if it finds something like this and we're in 2014 +For example: -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2012 The Bitcoin Core developers it will change it to -// Copyright (c) 2009-2014 The Bitcoin Core developers - -It will do this for all the files in the folder and its children. - -Author: @gubatron +// Copyright (c) 2009-2015 The Bitcoin Core developers ''' import os import time +import re year = time.gmtime()[0] -last_year = year - 1 -command = "perl -pi -e 's/%s The Bitcoin/%s The Bitcoin/' %s" -listFilesCommand = "find . | grep %s" +CMD_GIT_DATE = 'git log --format=@%%at -1 %s | date +"%%Y" -u -f -' +CMD_REGEX= "perl -pi -e 's/(20\d\d)(?:-20\d\d)? The Bitcoin/$1-%s The Bitcoin/' %s" +REGEX_CURRENT= re.compile("%s The Bitcoin" % year) +CMD_LIST_FILES= "find %s | grep %s" -extensions = [".cpp",".h"] +FOLDERS = ["./qa", "./src"] +EXTENSIONS = [".cpp",".h", ".py"] -def getLastGitModifiedDate(filePath): - gitGetLastCommitDateCommand = "git log " + filePath +" | grep Date | head -n 1" - p = os.popen(gitGetLastCommitDateCommand) - result = "" - for l in p: - result = l - break - result = result.replace("\n","") - return result +def get_git_date(file_path): + r = os.popen(CMD_GIT_DATE % file_path) + for l in r: + # Result is one line, so just return + return l.replace("\n","") + return "" n=1 -for extension in extensions: - foundFiles = os.popen(listFilesCommand % extension) - for filePath in foundFiles: - filePath = filePath[1:-1] - if filePath.endswith(extension): - filePath = os.getcwd() + filePath - modifiedTime = getLastGitModifiedDate(filePath) - if len(modifiedTime) > 0 and str(year) in modifiedTime: - print n,"Last Git Modified: ", modifiedTime, " - ", filePath - os.popen(command % (last_year,year,filePath)) - n = n + 1 - - +for folder in FOLDERS: + for extension in EXTENSIONS: + for file_path in os.popen(CMD_LIST_FILES % (folder, extension)): + file_path = os.getcwd() + file_path[1:-1] + if file_path.endswith(extension): + git_date = get_git_date(file_path) + if str(year) == git_date: + # Only update if current year is not found + if REGEX_CURRENT.search(open(file_path, "r").read()) is None: + print n,"Last git edit", git_date, "-", file_path + os.popen(CMD_REGEX % (year,file_path)) + n = n + 1 diff --git a/contrib/devtools/github-merge.py b/contrib/devtools/github-merge.py new file mode 100755 index 000000000..c8dcaae26 --- /dev/null +++ b/contrib/devtools/github-merge.py @@ -0,0 +1,235 @@ +#!/usr/bin/env python2 +# Copyright (c) 2016 Bitcoin Core Developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# This script will locally construct a merge commit for a pull request on a +# github repository, inspect it, sign it and optionally push it. + +# The following temporary branches are created/overwritten and deleted: +# * pull/$PULL/base (the current master we're merging onto) +# * pull/$PULL/head (the current state of the remote pull request) +# * pull/$PULL/merge (github's merge) +# * pull/$PULL/local-merge (our merge) + +# In case of a clean merge that is accepted by the user, the local branch with +# name $BRANCH is overwritten with the merged result, and optionally pushed. +from __future__ import division,print_function,unicode_literals +import os,sys +from sys import stdin,stdout,stderr +import argparse +import subprocess + +# External tools (can be overridden using environment) +GIT = os.getenv('GIT','git') +BASH = os.getenv('BASH','bash') + +# OS specific configuration for terminal attributes +ATTR_RESET = '' +ATTR_PR = '' +COMMIT_FORMAT = '%h %s (%an)%d' +if os.name == 'posix': # if posix, assume we can use basic terminal escapes + ATTR_RESET = '\033[0m' + ATTR_PR = '\033[1;36m' + COMMIT_FORMAT = '%C(bold blue)%h%Creset %s %C(cyan)(%an)%Creset%C(green)%d%Creset' + +def git_config_get(option, default=None): + ''' + Get named configuration option from git repository. + ''' + try: + return subprocess.check_output([GIT,'config','--get',option]).rstrip() + except subprocess.CalledProcessError as e: + return default + +def retrieve_pr_title(repo,pull): + ''' + Retrieve pull request title from github. + Return None if no title can be found, or an error happens. + ''' + import urllib2,json + try: + req = urllib2.Request("https://api.github.com/repos/"+repo+"/pulls/"+pull) + result = urllib2.urlopen(req) + result = json.load(result) + return result['title'] + except Exception as e: + print('Warning: unable to retrieve pull title from github: %s' % e) + return None + +def ask_prompt(text): + print(text,end=" ",file=stderr) + reply = stdin.readline().rstrip() + print("",file=stderr) + return reply + +def parse_arguments(branch): + epilog = ''' + In addition, you can set the following git configuration variables: + githubmerge.repository (mandatory), + user.signingkey (mandatory), + githubmerge.host (default: git@github.com), + githubmerge.branch (default: master), + githubmerge.testcmd (default: none). + ''' + parser = argparse.ArgumentParser(description='Utility to merge, sign and push github pull requests', + epilog=epilog) + parser.add_argument('pull', metavar='PULL', type=int, nargs=1, + help='Pull request ID to merge') + parser.add_argument('branch', metavar='BRANCH', type=str, nargs='?', + default=branch, help='Branch to merge against (default: '+branch+')') + return parser.parse_args() + +def main(): + # Extract settings from git repo + repo = git_config_get('githubmerge.repository') + host = git_config_get('githubmerge.host','git@github.com') + branch = git_config_get('githubmerge.branch','master') + testcmd = git_config_get('githubmerge.testcmd') + signingkey = git_config_get('user.signingkey') + if repo is None: + print("ERROR: No repository configured. Use this command to set:", file=stderr) + print("git config githubmerge.repository /", file=stderr) + exit(1) + if signingkey is None: + print("ERROR: No GPG signing key set. Set one using:",file=stderr) + print("git config --global user.signingkey ",file=stderr) + exit(1) + + host_repo = host+":"+repo # shortcut for push/pull target + + # Extract settings from command line + args = parse_arguments(branch) + pull = str(args.pull[0]) + branch = args.branch + + # Initialize source branches + head_branch = 'pull/'+pull+'/head' + base_branch = 'pull/'+pull+'/base' + merge_branch = 'pull/'+pull+'/merge' + local_merge_branch = 'pull/'+pull+'/local-merge' + + devnull = open(os.devnull,'w') + try: + subprocess.check_call([GIT,'checkout','-q',branch]) + except subprocess.CalledProcessError as e: + print("ERROR: Cannot check out branch %s." % (branch), file=stderr) + exit(3) + try: + subprocess.check_call([GIT,'fetch','-q',host_repo,'+refs/pull/'+pull+'/*:refs/heads/pull/'+pull+'/*']) + except subprocess.CalledProcessError as e: + print("ERROR: Cannot find pull request #%s on %s." % (pull,host_repo), file=stderr) + exit(3) + try: + subprocess.check_call([GIT,'log','-q','-1','refs/heads/'+head_branch], stdout=devnull, stderr=stdout) + except subprocess.CalledProcessError as e: + print("ERROR: Cannot find head of pull request #%s on %s." % (pull,host_repo), file=stderr) + exit(3) + try: + subprocess.check_call([GIT,'log','-q','-1','refs/heads/'+merge_branch], stdout=devnull, stderr=stdout) + except subprocess.CalledProcessError as e: + print("ERROR: Cannot find merge of pull request #%s on %s." % (pull,host_repo), file=stderr) + exit(3) + try: + subprocess.check_call([GIT,'fetch','-q',host_repo,'+refs/heads/'+branch+':refs/heads/'+base_branch]) + except subprocess.CalledProcessError as e: + print("ERROR: Cannot find branch %s on %s." % (branch,host_repo), file=stderr) + exit(3) + subprocess.check_call([GIT,'checkout','-q',base_branch]) + subprocess.call([GIT,'branch','-q','-D',local_merge_branch], stderr=devnull) + subprocess.check_call([GIT,'checkout','-q','-b',local_merge_branch]) + + try: + # Create unsigned merge commit. + title = retrieve_pr_title(repo,pull) + if title: + firstline = 'Merge #%s: %s' % (pull,title) + else: + firstline = 'Merge #%s' % (pull,) + message = firstline + '\n\n' + message += subprocess.check_output([GIT,'log','--no-merges','--topo-order','--pretty=format:%h %s (%an)',base_branch+'..'+head_branch]).decode('utf-8') + try: + subprocess.check_call([GIT,'merge','-q','--commit','--no-edit','--no-ff','-m',message.encode('utf-8'),head_branch]) + except subprocess.CalledProcessError as e: + print("ERROR: Cannot be merged cleanly.",file=stderr) + subprocess.check_call([GIT,'merge','--abort']) + exit(4) + logmsg = subprocess.check_output([GIT,'log','--pretty=format:%s','-n','1']).decode('utf-8') + if logmsg.rstrip() != firstline.rstrip(): + print("ERROR: Creating merge failed (already merged?).",file=stderr) + exit(4) + + print('%s#%s%s %s' % (ATTR_RESET+ATTR_PR,pull,ATTR_RESET,title)) + subprocess.check_call([GIT,'log','--graph','--topo-order','--pretty=format:'+COMMIT_FORMAT,base_branch+'..'+head_branch]) + print() + # Run test command if configured. + if testcmd: + # Go up to the repository's root. + toplevel = subprocess.check_output([GIT,'rev-parse','--show-toplevel']).strip() + os.chdir(toplevel) + if subprocess.call(testcmd,shell=True): + print("ERROR: Running %s failed." % testcmd,file=stderr) + exit(5) + + # Show the created merge. + diff = subprocess.check_output([GIT,'diff',merge_branch+'..'+local_merge_branch]) + subprocess.check_call([GIT,'diff',base_branch+'..'+local_merge_branch]) + if diff: + print("WARNING: merge differs from github!",file=stderr) + reply = ask_prompt("Type 'ignore' to continue.") + if reply.lower() == 'ignore': + print("Difference with github ignored.",file=stderr) + else: + exit(6) + reply = ask_prompt("Press 'd' to accept the diff.") + if reply.lower() == 'd': + print("Diff accepted.",file=stderr) + else: + print("ERROR: Diff rejected.",file=stderr) + exit(6) + else: + # Verify the result manually. + print("Dropping you on a shell so you can try building/testing the merged source.",file=stderr) + print("Run 'git diff HEAD~' to show the changes being merged.",file=stderr) + print("Type 'exit' when done.",file=stderr) + if os.path.isfile('/etc/debian_version'): # Show pull number on Debian default prompt + os.putenv('debian_chroot',pull) + subprocess.call([BASH,'-i']) + reply = ask_prompt("Type 'm' to accept the merge.") + if reply.lower() == 'm': + print("Merge accepted.",file=stderr) + else: + print("ERROR: Merge rejected.",file=stderr) + exit(7) + + # Sign the merge commit. + reply = ask_prompt("Type 's' to sign off on the merge.") + if reply == 's': + try: + subprocess.check_call([GIT,'commit','-q','--gpg-sign','--amend','--no-edit']) + except subprocess.CalledProcessError as e: + print("Error signing, exiting.",file=stderr) + exit(1) + else: + print("Not signing off on merge, exiting.",file=stderr) + exit(1) + + # Put the result in branch. + subprocess.check_call([GIT,'checkout','-q',branch]) + subprocess.check_call([GIT,'reset','-q','--hard',local_merge_branch]) + finally: + # Clean up temporary branches. + subprocess.call([GIT,'checkout','-q',branch]) + subprocess.call([GIT,'branch','-q','-D',head_branch],stderr=devnull) + subprocess.call([GIT,'branch','-q','-D',base_branch],stderr=devnull) + subprocess.call([GIT,'branch','-q','-D',merge_branch],stderr=devnull) + subprocess.call([GIT,'branch','-q','-D',local_merge_branch],stderr=devnull) + + # Push the result. + reply = ask_prompt("Type 'push' to push the result to %s, branch %s." % (host_repo,branch)) + if reply.lower() == 'push': + subprocess.check_call([GIT,'push',host_repo,'refs/heads/'+branch]) + +if __name__ == '__main__': + main() + diff --git a/contrib/devtools/github-merge.sh b/contrib/devtools/github-merge.sh deleted file mode 100755 index afb53f039..000000000 --- a/contrib/devtools/github-merge.sh +++ /dev/null @@ -1,185 +0,0 @@ -#!/bin/bash - -# This script will locally construct a merge commit for a pull request on a -# github repository, inspect it, sign it and optionally push it. - -# The following temporary branches are created/overwritten and deleted: -# * pull/$PULL/base (the current master we're merging onto) -# * pull/$PULL/head (the current state of the remote pull request) -# * pull/$PULL/merge (github's merge) -# * pull/$PULL/local-merge (our merge) - -# In case of a clean merge that is accepted by the user, the local branch with -# name $BRANCH is overwritten with the merged result, and optionally pushed. - -REPO="$(git config --get githubmerge.repository)" -if [[ "d$REPO" == "d" ]]; then - echo "ERROR: No repository configured. Use this command to set:" >&2 - echo "git config githubmerge.repository /" >&2 - echo "In addition, you can set the following variables:" >&2 - echo "- githubmerge.host (default git@github.com)" >&2 - echo "- githubmerge.branch (default master)" >&2 - echo "- githubmerge.testcmd (default none)" >&2 - exit 1 -fi - -HOST="$(git config --get githubmerge.host)" -if [[ "d$HOST" == "d" ]]; then - HOST="git@github.com" -fi - -BRANCH="$(git config --get githubmerge.branch)" -if [[ "d$BRANCH" == "d" ]]; then - BRANCH="master" -fi - -TESTCMD="$(git config --get githubmerge.testcmd)" - -PULL="$1" - -if [[ "d$PULL" == "d" ]]; then - echo "Usage: $0 pullnumber [branch]" >&2 - exit 2 -fi - -if [[ "d$2" != "d" ]]; then - BRANCH="$2" -fi - -# Initialize source branches. -git checkout -q "$BRANCH" -if git fetch -q "$HOST":"$REPO" "+refs/pull/$PULL/*:refs/heads/pull/$PULL/*"; then - if ! git log -q -1 "refs/heads/pull/$PULL/head" >/dev/null 2>&1; then - echo "ERROR: Cannot find head of pull request #$PULL on $HOST:$REPO." >&2 - exit 3 - fi - if ! git log -q -1 "refs/heads/pull/$PULL/merge" >/dev/null 2>&1; then - echo "ERROR: Cannot find merge of pull request #$PULL on $HOST:$REPO." >&2 - exit 3 - fi -else - echo "ERROR: Cannot find pull request #$PULL on $HOST:$REPO." >&2 - exit 3 -fi -if git fetch -q "$HOST":"$REPO" +refs/heads/"$BRANCH":refs/heads/pull/"$PULL"/base; then - true -else - echo "ERROR: Cannot find branch $BRANCH on $HOST:$REPO." >&2 - exit 3 -fi -git checkout -q pull/"$PULL"/base -git branch -q -D pull/"$PULL"/local-merge 2>/dev/null -git checkout -q -b pull/"$PULL"/local-merge -TMPDIR="$(mktemp -d -t ghmXXXXX)" - -function cleanup() { - git checkout -q "$BRANCH" - git branch -q -D pull/"$PULL"/head 2>/dev/null - git branch -q -D pull/"$PULL"/base 2>/dev/null - git branch -q -D pull/"$PULL"/merge 2>/dev/null - git branch -q -D pull/"$PULL"/local-merge 2>/dev/null - rm -rf "$TMPDIR" -} - -# Create unsigned merge commit. -( - echo "Merge pull request #$PULL" - echo "" - git log --no-merges --topo-order --pretty='format:%h %s (%an)' pull/"$PULL"/base..pull/"$PULL"/head -)>"$TMPDIR/message" -if git merge -q --commit --no-edit --no-ff -m "$(<"$TMPDIR/message")" pull/"$PULL"/head; then - if [ "d$(git log --pretty='format:%s' -n 1)" != "dMerge pull request #$PULL" ]; then - echo "ERROR: Creating merge failed (already merged?)." >&2 - cleanup - exit 4 - fi -else - echo "ERROR: Cannot be merged cleanly." >&2 - git merge --abort - cleanup - exit 4 -fi - -# Run test command if configured. -if [[ "d$TESTCMD" != "d" ]]; then - # Go up to the repository's root. - while [ ! -d .git ]; do cd ..; done - if ! $TESTCMD; then - echo "ERROR: Running $TESTCMD failed." >&2 - cleanup - exit 5 - fi - # Show the created merge. - git diff pull/"$PULL"/merge..pull/"$PULL"/local-merge >"$TMPDIR"/diff - git diff pull/"$PULL"/base..pull/"$PULL"/local-merge - if [[ "$(<"$TMPDIR"/diff)" != "" ]]; then - echo "WARNING: merge differs from github!" >&2 - read -p "Type 'ignore' to continue. " -r >&2 - if [[ "d$REPLY" =~ ^d[iI][gG][nN][oO][rR][eE]$ ]]; then - echo "Difference with github ignored." >&2 - else - cleanup - exit 6 - fi - fi - read -p "Press 'd' to accept the diff. " -n 1 -r >&2 - echo - if [[ "d$REPLY" =~ ^d[dD]$ ]]; then - echo "Diff accepted." >&2 - else - echo "ERROR: Diff rejected." >&2 - cleanup - exit 6 - fi -else - # Verify the result. - echo "Dropping you on a shell so you can try building/testing the merged source." >&2 - echo "Run 'git diff HEAD~' to show the changes being merged." >&2 - echo "Type 'exit' when done." >&2 - if [[ -f /etc/debian_version ]]; then # Show pull number in prompt on Debian default prompt - export debian_chroot="$PULL" - fi - bash -i - read -p "Press 'm' to accept the merge. " -n 1 -r >&2 - echo - if [[ "d$REPLY" =~ ^d[Mm]$ ]]; then - echo "Merge accepted." >&2 - else - echo "ERROR: Merge rejected." >&2 - cleanup - exit 7 - fi -fi - -# Sign the merge commit. -read -p "Press 's' to sign off on the merge. " -n 1 -r >&2 -echo -if [[ "d$REPLY" =~ ^d[Ss]$ ]]; then - if [[ "$(git config --get user.signingkey)" == "" ]]; then - echo "ERROR: No GPG signing key set, not signing. Set one using:" >&2 - echo "git config --global user.signingkey " >&2 - cleanup - exit 1 - else - if ! git commit -q --gpg-sign --amend --no-edit; then - echo "Error signing, exiting." - cleanup - exit 1 - fi - fi -else - echo "Not signing off on merge, exiting." - cleanup - exit 1 -fi - -# Clean up temporary branches, and put the result in $BRANCH. -git checkout -q "$BRANCH" -git reset -q --hard pull/"$PULL"/local-merge -cleanup - -# Push the result. -read -p "Type 'push' to push the result to $HOST:$REPO, branch $BRANCH. " -r >&2 -if [[ "d$REPLY" =~ ^d[Pp][Uu][Ss][Hh]$ ]]; then - git push "$HOST":"$REPO" refs/heads/"$BRANCH" -fi diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index e96eaa9c3..0319f739c 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -1,7 +1,7 @@ #!/usr/bin/python2 ''' Perform basic ELF security checks on a series of executables. -Exit status will be 0 if succesful, and the program will be silent. +Exit status will be 0 if successful, and the program will be silent. Otherwise the exit status will be 1 and it will log which executables failed which checks. Needs `readelf` (for ELF) and `objdump` (for PE). ''' @@ -94,7 +94,7 @@ def check_ELF_RELRO(executable): raise IOError('Error opening file') for line in stdout.split('\n'): tokens = line.split() - if len(tokens)>1 and tokens[1] == '(BIND_NOW)': + if len(tokens)>1 and tokens[1] == '(BIND_NOW)' or (len(tokens)>2 and tokens[1] == '(FLAGS)' and 'BIND_NOW' in tokens[2]): have_bindnow = True return have_gnu_relro and have_bindnow diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index 93acfcdda..4ad5136f7 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -42,9 +42,12 @@ MAX_VERSIONS = { 'GLIBCXX': (3,4,13), 'GLIBC': (2,11) } +# See here for a description of _IO_stdin_used: +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109 + # Ignore symbols that are exported as part of every executable IGNORE_EXPORTS = { -'_edata', '_end', '_init', '__bss_start', '_fini' +'_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used' } READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt') diff --git a/contrib/devtools/update-translations.py b/contrib/devtools/update-translations.py index f955e4a1f..2b6e807b4 100755 --- a/contrib/devtools/update-translations.py +++ b/contrib/devtools/update-translations.py @@ -29,6 +29,8 @@ TX = 'tx' SOURCE_LANG = 'bitcoin_en.ts' # Directory with locale files LOCALE_DIR = 'src/qt/locale' +# Minimum number of messages for translation to be considered at all +MIN_NUM_MESSAGES = 10 def check_at_repository_root(): if not os.path.exists('.git'): @@ -37,7 +39,7 @@ def check_at_repository_root(): exit(1) def fetch_all_translations(): - if subprocess.call([TX, 'pull', '-f']): + if subprocess.call([TX, 'pull', '-f', '-a']): print('Error while fetching translations', file=sys.stderr) exit(1) @@ -70,7 +72,7 @@ def sanitize_string(s): '''Sanitize string for printing''' return s.replace('\n',' ') -def check_format_specifiers(source, translation, errors): +def check_format_specifiers(source, translation, errors, numerus): source_f = split_format_specifiers(find_format_specifiers(source)) # assert that no source messages contain both Qt and strprintf format specifiers # if this fails, go change the source as this is hacky and confusing! @@ -78,10 +80,13 @@ def check_format_specifiers(source, translation, errors): try: translation_f = split_format_specifiers(find_format_specifiers(translation)) except IndexError: - errors.append("Parse error in translation '%s'" % sanitize_string(translation)) + errors.append("Parse error in translation for '%s': '%s'" % (sanitize_string(source), sanitize_string(translation))) return False else: if source_f != translation_f: + if numerus and source_f == (set(), ['n']) and translation_f == (set(), []) and translation.find('%') == -1: + # Allow numerus translations to omit %n specifier (usually when it only has one possible value) + return True errors.append("Mismatch between '%s' and '%s'" % (sanitize_string(source), sanitize_string(translation))) return False return True @@ -148,7 +153,7 @@ def postprocess_translations(reduce_diff_hacks=False): if translation is None: continue errors = [] - valid = check_format_specifiers(source, translation, errors) + valid = check_format_specifiers(source, translation, errors, numerus) for error in errors: print('%s: %s' % (filename, error)) @@ -166,6 +171,15 @@ def postprocess_translations(reduce_diff_hacks=False): if translation_node.get('type') == 'unfinished': context.remove(message) + # check if document is (virtually) empty, and remove it if so + num_messages = 0 + for context in root.findall('context'): + for message in context.findall('message'): + num_messages += 1 + if num_messages < MIN_NUM_MESSAGES: + print('Removing %s, as it contains only %i messages' % (filepath, num_messages)) + continue + # write fixed-up tree # if diff reduction requested, replace some XML to 'sanitize' to qt formatting if reduce_diff_hacks: diff --git a/contrib/gitian-descriptors/README.md b/contrib/gitian-descriptors/README.md index 07c2ba98b..614970659 100644 --- a/contrib/gitian-descriptors/README.md +++ b/contrib/gitian-descriptors/README.md @@ -1,8 +1,7 @@ -### Gavin's notes on getting gitian builds up and running using KVM:### +### Gavin's notes on getting gitian builds up and running using KVM -These instructions distilled from: -[ https://help.ubuntu.com/community/KVM/Installation]( https://help.ubuntu.com/community/KVM/Installation) -... see there for complete details. +These instructions distilled from +[https://help.ubuntu.com/community/KVM/Installation](https://help.ubuntu.com/community/KVM/Installation). You need the right hardware: you need a 64-bit-capable CPU with hardware virtualization support (Intel VT-x or AMD-V). Not all modern CPUs support hardware virtualization. @@ -33,14 +32,14 @@ Once you've got the right hardware and software: # Get inputs (see doc/release-process.md for exact inputs needed and where to get them) ... - # For further build instructions see doc/release-notes.md + # For further build instructions see doc/release-process.md ... --------------------- `gitian-builder` now also supports building using LXC. See -[ https://help.ubuntu.com/12.04/serverguide/lxc.html]( https://help.ubuntu.com/12.04/serverguide/lxc.html) -... for how to get LXC up and running under Ubuntu. +[help.ubuntu.com](https://help.ubuntu.com/14.04/serverguide/lxc.html) +for how to get LXC up and running under Ubuntu. If your main machine is a 64-bit Mac or PC with a few gigabytes of memory and at least 10 gigabytes of free disk space, you can `gitian-build` using diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 0c3c439dd..b4b6ed290 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-linux-0.12" +name: "bitcoin-linux-0.13" enable_cache: true suites: - "trusty" @@ -15,7 +15,9 @@ packages: - "faketime" - "bsdmainutils" - "binutils-gold" -reference_datetime: "2015-06-01 00:00:00" +- "ca-certificates" +- "python" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" @@ -94,6 +96,8 @@ script: | ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} make ${MAKEOPTS} + make ${MAKEOPTS} -C src check-security + make ${MAKEOPTS} -C src check-symbols make install-strip cd installed find . -name "lib*.la" -delete diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml index d349a13dd..c4165470a 100644 --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -5,9 +5,8 @@ suites: architectures: - "amd64" packages: -- "libc6:i386" - "faketime" -reference_datetime: "2015-06-01 00:00:00" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git" "dir": "signature" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 0eb97d6a7..4a4592398 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -1,11 +1,12 @@ --- -name: "bitcoin-osx-0.12" +name: "bitcoin-osx-0.13" enable_cache: true suites: - "trusty" architectures: - "amd64" packages: +- "ca-certificates" - "g++" - "git-core" - "pkg-config" @@ -21,10 +22,11 @@ packages: - "libcap-dev" - "libz-dev" - "libbz2-dev" +- "python" - "python-dev" - "python-setuptools" - "fonts-tuffy" -reference_datetime: "2015-06-01 00:00:00" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" diff --git a/contrib/gitian-descriptors/gitian-win-signer.yml b/contrib/gitian-descriptors/gitian-win-signer.yml index a29d7ab47..27c4f01eb 100644 --- a/contrib/gitian-descriptors/gitian-win-signer.yml +++ b/contrib/gitian-descriptors/gitian-win-signer.yml @@ -7,7 +7,7 @@ architectures: packages: - "libssl-dev" - "autoconf" -reference_datetime: "2015-06-01 00:00:00" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git" "dir": "signature" diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 6bb482d45..233f5c549 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -1,5 +1,5 @@ --- -name: "bitcoin-win-0.12" +name: "bitcoin-win-0.13" enable_cache: true suites: - "trusty" @@ -18,7 +18,9 @@ packages: - "g++-mingw-w64" - "nsis" - "zip" -reference_datetime: "2015-06-01 00:00:00" +- "ca-certificates" +- "python" +reference_datetime: "2016-01-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" @@ -124,6 +126,7 @@ script: | ./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} make ${MAKEOPTS} + make ${MAKEOPTS} -C src check-security make deploy make install-strip cp -f bitcoin-*setup*.exe $OUTDIR/ diff --git a/contrib/gitian-downloader/achow101-key.pgp b/contrib/gitian-downloader/achow101-key.pgp new file mode 100644 index 000000000..030fd5cf3 --- /dev/null +++ b/contrib/gitian-downloader/achow101-key.pgp @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQINBFT4snkBEACx90Wf5XLo1Xv09p81eaOXc+8bbkSYzqx3ThDNUPRzjYpex9A9 +8FxfBenAykD3EgYuBTco4cbn7Dw11ppyXUw0VjWaagnnAVGxt3SDeY3ADwPss6xg +78FZXxT06xSHZXq1X6pOqhwTAnx3VGx+tR/A2DCsX0vHE6IVThZqyUq2Ei2C0Chc +od8y6JZ1CGNzlRkEgL9A0Zp0If6Uq4tXFxnLL6PtiS1b9V5rNfCSC7l99kIkG5oy ++SPsGRwVqTE2kqtuzkt9qVn6v8KKoZr0BY4IO3KMfJJ4eidOkB+OZK9REEQguDvv +tJfkF2HcMYa1efvQObyvVIfS5gxs7+kcSJxgDVZI5YxRV1OOfI7+w3EW3G+bPBQF +gSBwEaLbD+udr9lDZ4NZc7vTeoZtYVNZ+EQtG+6I9GzxJwEgO5LIwZ3//vh/R4iy +z9W91r7TrlkHUuOGg1hXMCI9sRa65NJtP4BWD0xO07zDKj0JHzeyKwgxB/ixZF2V +kc8EzJSKzRfr+638BMXONcf6NW8n6qIlJT2U2qIwiixjM8AUujGKb8DEgU1vIAn9 +7esOhceOtU/6iLuJrlK+TzMe97NoZCtt6ktmiAp8fu6l9uk3mr8JYLzIMtK+Asf4 +np5YLizABwbt9gEretnGpHrdKMN88mPYwsLjjCh9wiM0bHZNL52JQRkt3QARAQAB +tDNBbmRyZXcgQ2hvdyAoT2ZmaWNpYWwgTmV3IEtleSkgPGFjaG93MTAxQGdtYWls +LmNvbT6JAjYEEwEKACAFAlT4snkCGwMFCwkIBwMFFQoJCAsEFgIBAAIeAQIXgAAK +CRAXVlcy4I5eQfyGD/9idtVjybuXl+LXS4ph4M738PrZfQeLDmnwhVjfZiEOLLs2 +sAwGtL/CC0t9f7K7y+n5HtQoMX52jfVehnTDzeKCjRMs+5ssou+L9zadIAz68beU +7BZ0J1rR3n1kzwsFE3vx3IRno0VCTOgfL48AuuzMPxvEaLMxWQX8mL0PCV5/8Yxx +ftqg4kQ1JKMt5UTxE9/w0cBMphLTwV1Rx6lZILPJgOxYSQ0oOzQYSmucwzH1uOqH +wpgZ7SZIHfRWyi4TjQpU/5T2kMOlN/XdyWsj5+Eq+Y6zI6hq2se1vU3TOc8xN2S3 +7YOza1onUj4if0rWtkJZ2yDnR4lIASUD+/VP2NoWtoy7rB0vIfzbojfwxAp8WuHT +sUTxXd52c3OB+673OlOA+GAg2FfFjR8REojsTbeip35/KmFMpafazVRn+E0c3MfP +/iS43UTlcxewRcDrx/gRplmgO0+CLgLstZOon7Dz0msypeSArhX2xEj4tJb/ccKd +CR/IQl8q/ULQsHX1LwRj0u9doAlkqgIQdKXou4+EmD1jKF92oJMZ+20AJCqfwYQY +9HlCB9SQeCRUtU/fHkAZLPApze6C7a1r0LVIuM6iolWyha5KJ++mj84fAagwy/ag +8TU8kHTLSGPYeg5G/TAbr1XU5kbbqfWfQFMK1xtdZd1BaGP2cDC2QGkr2ot1SLkC +DQRU+LJ5ARAArDftuFPE+ZhgJRuJK163fsD15aHPfv5s+h8kPFv0AuwVs+D75w3y +YGfaRtlwSvK+8EucKOoHI1AQYjTG0dtKJuwEGhQ2qsTWUKe05tEAWu0eN62MOZ/r +Awjxqotj4TeFksfyKedVAYSizD0Xj16fizeWFrfUBNND4OgUgD8KM79oRchtzKBE +HRBP27JksU8tQWc4YcEJUHV66Pji5OCiXxHXJ+JpqKSKeCrVvrvro+pwsY1I3ARA +F4UmLxCcb4GnNq+s76cb2K7XJtWJu5FHeHOsef5ped43pYs35UXI+EvOYNs39XI4 +emMsI0KmuLME2LHO3CJNBirwRFxui27axZk/CSVE1lglnbb25n3QHvbs/31ASCCT +QKZ7+Gce89iow6yG4MkN5W4hLdkGAyNI74b6yAUfugSqPLNSj3YHvVFY3y1acge+ +H7xDO/owRN1kbz+9VMJZxsxB/oZEyEVAE0szHxXbMBhqOME0Y3O6UBrXr7z6R8NG +S20RPet4kxCCTLZOvM/X5FtvimgR2u5qRPHs+zf2VPXIRsJsM3zq9EvmePryGM3r +1rEAvYagukuyt68lOWgKP/2wB0/NIFAs69b1QSJS3U4CQVIs2h84Ucvbh9gX9Y0B +LbV5mxvDDfC/4Nhf4yMfH/CwZDLOUsaRAjCv/lQuN9mnMz9aYnsPha0AEQEAAYkC +HwQYAQoACQUCVPiyeQIbDAAKCRAXVlcy4I5eQec+EACi14L8Vp7tw3tDm/Lrb9fM +LHfoOnZiDCGaXhiXqckbTSogp7hU82m1fIy4VwY7DWbs1iIq7QdDJMBuNn174Qd3 +ZPxHeGwBbR04gEsHkbjXBAA5hMacLvmxYFiPlibz+AO4orUiYu/vlEXhXoFCjSlB +pw0kUG8W8yQ/RyE7ryLv5/bT4LkwUWF7/+gdDzLUy1VeaPDKmBupKVSbEACe4QRH +dUUqE3suKoJ/GylO2sGtFW8BM7+CffX+nvc8hJWzXdYW5InSh0omYJIypIgnQ1gM +MhUdu4gbtYwo44Tlax2mTSg8vSVboYO6pBZVX3IEUnjRHLOCZVZIBFXIFdRrHXO8 +TTkzx9ZoDmZ/DH+Md1NDnS4QsvFbRO/EeDRQAI4cgGhCc4CTrrJSQv8jtl7x8OTx +fnDUbE/n8pLV93j9t1Gd07h0VJSmYj3AR7PiefHS7s2yxS9oOqRayGBqrJFzd2gS ++oXvUBC6pUvM68NgNVCKH7HmIM9tFbqgy8kofTsVDkq9TEJRO+X4hn7UDNJhTjVE +AVRUdku6CJR6wj3RPCbERSNB8uabuv1lgo41baeepLn+tJNO/4hilJ0zvEoryVnJ +ldZ73mHRRRtXoPRXq7OKuDn10AvtYX8y3/q5z6XhLUePFKM91PO8GF0J6bNWrQSq +Khvd4+XHE/ecjLOPvLweAg== +=+hz7 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/gitian-downloader/linux-download-config b/contrib/gitian-downloader/linux-download-config deleted file mode 100644 index c0048d336..000000000 --- a/contrib/gitian-downloader/linux-download-config +++ /dev/null @@ -1,45 +0,0 @@ ---- -name: bitcoin -urls: -- http://bitcoin.org/bitcoin-latest-linux-gitian.zip -rss: -- url: - xpath: //item/link/text() - pattern: bitcoin-\d+.\d+.\d+-linux-gitian.zip -signers: - 0A82509767C7D4A5D14DA2301AE1D35043E08E54: - name: BlueMatt - key: bluematt - BF6273FAEF7CC0BA1F562E50989F6B3048A116B5: - name: Devrandom - key: devrandom - E463A93F5F3117EEDE6C7316BD02942421F4889F: - name: Luke-Jr - key: luke-jr - D762373D24904A3E42F33B08B9A408E71DAAC974: - name: "Pieter Wuille" - key: sipa - 77E72E69DA7EE0A148C06B21B34821D4944DE5F7: - name: tcatm - key: tcatm - 01CDF4627A3B88AAE4A571C87588242FBE38D3A8: - name: "Gavin Andresen" - key: gavinandresen - 71A3B16735405025D447E8F274810B012346C9A6: - name: "Wladimir J. van der Laan" - key: laanwj - AEC1884398647C47413C1C3FB1179EB7347DC10D: - name: "Warren Togami" - key: wtogami - 9692B91BBF0E8D34DFD33B1882C5C009628ECF0C: - name: michagogo - key: michagogo - E944AE667CF960B1004BC32FCA662BE18B877A60: - name: "Andreas Schildbach" - key: aschildbach - C060A6635913D98A3587D7DB1C2491FFEB0EF770: - name: "Cory Fields" - key: "cfields" - 37EC7D7B0A217CDB4B4E007E7FAB114267E4FA04: - name: "Peter Todd" - key: "petertodd" diff --git a/contrib/gitian-downloader/win32-download-config b/contrib/gitian-downloader/win32-download-config deleted file mode 100644 index 0ad3bdd4f..000000000 --- a/contrib/gitian-downloader/win32-download-config +++ /dev/null @@ -1,45 +0,0 @@ ---- -name: bitcoin -urls: -- http://bitcoin.org/bitcoin-latest-win32-gitian.zip -rss: -- url: - xpath: //item/link/text() - pattern: bitcoin-\d+.\d+.\d+-win32-gitian.zip -signers: - 0A82509767C7D4A5D14DA2301AE1D35043E08E54: - name: BlueMatt - key: bluematt - BF6273FAEF7CC0BA1F562E50989F6B3048A116B5: - name: Devrandom - key: devrandom - E463A93F5F3117EEDE6C7316BD02942421F4889F: - name: Luke-Jr - key: luke-jr - D762373D24904A3E42F33B08B9A408E71DAAC974: - name: "Pieter Wuille" - key: sipa - 77E72E69DA7EE0A148C06B21B34821D4944DE5F7: - name: tcatm - key: tcatm - 01CDF4627A3B88AAE4A571C87588242FBE38D3A8: - name: "Gavin Andresen" - key: gavinandresen - 71A3B16735405025D447E8F274810B012346C9A6: - name: "Wladimir J. van der Laan" - key: laanwj - AEC1884398647C47413C1C3FB1179EB7347DC10D: - name: "Warren Togami" - key: wtogami - 9692B91BBF0E8D34DFD33B1882C5C009628ECF0C: - name: michagogo - key: michagogo - E944AE667CF960B1004BC32FCA662BE18B877A60: - name: "Andreas Schildbach" - key: aschildbach - C060A6635913D98A3587D7DB1C2491FFEB0EF770: - name: "Cory Fields" - key: "cfields" - 37EC7D7B0A217CDB4B4E007E7FAB114267E4FA04: - name: "Peter Todd" - key: "petertodd" diff --git a/contrib/seeds/README.md b/contrib/seeds/README.md index 63647fa11..c595f83eb 100644 --- a/contrib/seeds/README.md +++ b/contrib/seeds/README.md @@ -3,6 +3,9 @@ Utility to generate the seeds.txt list that is compiled into the client (see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and other utilities in [contrib/seeds](/contrib/seeds)). -The 512 seeds compiled into the 0.10 release were created from sipa's DNS seed data, like this: +The seeds compiled into the release are created from sipa's DNS seed data, like this: + + curl -s http://bitcoin.sipa.be/seeds.txt > seeds_main.txt + python makeseeds.py < seeds_main.txt > nodes_main.txt + python generate-seeds.py . > ../../src/chainparamsseeds.h - curl -s http://bitcoin.sipa.be/seeds.txt | makeseeds.py diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py index 167c219c6..a3d035218 100755 --- a/contrib/seeds/generate-seeds.py +++ b/contrib/seeds/generate-seeds.py @@ -1,5 +1,5 @@ #!/usr/bin/python -# Copyright (c) 2014 Wladmir J. van der Laan +# Copyright (c) 2014 Wladimir J. van der Laan # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' diff --git a/contrib/seeds/nodes_main.txt b/contrib/seeds/nodes_main.txt index 17339d514..f1854b27f 100644 --- a/contrib/seeds/nodes_main.txt +++ b/contrib/seeds/nodes_main.txt @@ -1,879 +1,937 @@ -1.34.168.128:8333 -1.202.128.218:8333 -2.30.0.210:8333 -5.9.96.203:8333 -5.45.71.130:8333 -5.45.98.141:8333 -5.102.145.68:8333 -5.135.160.77:8333 -5.189.134.246:8333 -5.199.164.132:8333 -5.249.135.102:8333 -8.19.44.110:8333 -8.22.230.8:8333 -14.200.200.145:8333 -18.228.0.188:8333 -18.228.0.200:8333 -23.24.168.97:8333 -23.28.35.227:8333 -23.92.76.170:8333 -23.99.64.119:8333 -23.228.166.128:8333 -23.229.45.32:8333 -24.8.105.128:8333 -24.16.69.137:8333 -24.94.98.96:8333 -24.102.118.7:8333 -24.118.166.228:8333 -24.122.133.49:8333 -24.166.97.162:8333 -24.213.235.242:8333 -24.226.107.64:8333 -24.228.192.171:8333 -27.140.133.18:8333 -31.41.40.25:8333 -31.43.101.59:8333 -31.184.195.181:8333 -31.193.139.66:8333 -37.200.70.102:8333 -37.205.10.151:8333 -42.3.106.227:8333 -42.60.133.106:8333 -45.56.85.231:8333 -45.56.102.228:8333 -45.79.130.235:8333 -46.28.204.61:11101 -46.38.235.229:8333 -46.59.2.74:8333 -46.101.132.37:8333 -46.101.168.50:8333 -46.163.76.230:8333 +5.2.145.201:8333 +5.22.142.214:8333 +5.53.172.197:8333 +5.189.161.164:8333 +5.230.140.166:8333 +5.231.3.130:8333 +5.255.80.103:8333 +14.202.230.49:8333 +18.85.11.130:8333 +23.91.97.25:8333 +23.94.100.122:8333 +23.95.99.132:8333 +24.115.8.206:8333 +24.127.128.191:8333 +24.154.178.25:8333 +24.207.103.43:8333 +24.207.104.105:8333 +24.210.230.150:8333 +24.224.18.84:8333 +24.246.168.106:8333 +27.254.64.47:8333 +31.6.71.123:8333 +31.6.71.124:8333 +31.14.134.13:8333 +31.30.36.220:8333 +31.164.6.104:8333 +31.170.106.203:8333 +31.185.134.201:8333 +31.204.128.99:8333 +31.204.128.219:8333 +37.1.219.88:8333 +37.97.132.109:8333 +37.120.160.55:8333 +37.120.169.123:8333 +37.139.32.46:8333 +37.221.163.218:8333 +38.130.192.72:8333 +41.75.96.80:8333 +45.3.0.49:8333 +45.33.72.185:8333 +45.33.96.129:8333 +45.56.4.63:8333 +45.79.0.127:8333 +45.79.80.102:8333 +45.79.97.30:8333 +45.79.132.219:8333 +46.21.97.135:8333 +46.28.205.67:8333 +46.28.206.188:8333 +46.29.20.209:8333 +46.50.234.179:8333 +46.101.160.168:8333 +46.166.161.35:8333 46.166.161.103:8333 46.182.132.100:8333 -46.223.36.94:8333 +46.218.227.92:8333 +46.226.109.20:8333 46.227.66.132:8333 46.227.66.138:8333 +46.229.165.154:8333 +46.229.165.155:8333 +46.229.238.187:8333 +46.234.104.48:8333 46.239.107.74:8333 -46.249.39.100:8333 -46.250.98.108:8333 +46.244.0.138:8333 +46.254.72.195:8333 +50.5.13.44:8333 50.7.37.114:8333 -50.81.53.151:8333 -50.115.43.253:8333 -50.116.20.87:8333 -50.116.33.92:8333 -50.125.167.245:8333 -50.143.9.51:8333 -50.188.192.133:8333 -54.77.162.76:8333 -54.153.97.109:8333 -54.165.192.125:8333 -58.96.105.85:8333 -59.167.196.135:8333 -60.29.227.163:8333 +50.30.37.103:8333 +50.39.105.60:8333 +50.106.40.231:8333 +52.29.0.37:8333 +52.76.192.246:8333 +54.152.192.179:8333 +54.169.64.174:8333 +54.175.160.22:8333 +54.199.128.0:8333 +58.96.171.129:8333 +58.161.238.57:8333 +60.251.195.221:8333 61.35.225.19:8333 62.43.130.178:8333 -62.109.49.26:8333 -62.202.0.97:8333 -62.210.66.227:8333 -62.210.192.169:8333 -64.74.98.205:8333 -64.156.193.100:8333 +62.65.39.12:8333 +62.107.200.30:8333 +62.133.194.2:8333 +62.181.238.186:8333 +62.183.22.50:8333 +62.210.85.120:8333 +62.210.162.89:8333 +62.238.34.125:8333 +64.25.171.73:8333 +64.27.166.30:8333 +64.53.137.101:8333 +64.71.72.44:8333 +64.83.225.146:8333 +64.121.3.163:8333 64.203.102.86:8333 -64.229.142.48:8333 -65.96.193.165:8333 -66.30.3.7:8333 +65.94.131.59:8333 +65.188.136.233:8333 +66.11.162.218:8333 +66.23.228.133:8333 +66.90.137.89:8333 66.114.33.49:8333 -66.118.133.194:8333 -66.135.10.126:8333 +66.150.105.77:8333 66.172.10.4:8333 66.194.38.250:8333 66.194.38.253:8333 -66.215.192.104:8333 -67.60.98.115:8333 -67.164.35.36:8333 -67.191.162.244:8333 -67.207.195.77:8333 -67.219.233.140:8333 +66.194.38.254:8333 +66.231.97.172:8333 +66.240.237.155:8333 +67.159.13.34:8333 +67.205.74.206:8333 67.221.193.55:8333 -67.228.162.228:8333 -68.50.67.199:8333 -68.62.3.203:8333 +67.227.72.17:8333 +68.65.120.53:8333 68.65.205.226:9000 -68.106.42.191:8333 -68.150.181.198:8333 -68.196.196.106:8333 -68.224.194.81:8333 -69.46.5.194:8333 -69.50.171.238:8333 -69.64.43.152:8333 -69.65.41.13:8333 -69.90.132.200:8333 -69.143.1.243:8333 -69.146.98.216:8333 -69.165.246.38:8333 -69.207.6.135:8333 -69.251.208.26:8333 -70.38.1.101:8333 -70.38.9.66:8333 -70.90.2.18:8333 -71.58.228.226:8333 -71.199.11.189:8333 -71.199.193.202:8333 -71.205.232.181:8333 -71.236.200.162:8333 -72.24.73.186:8333 +68.144.4.34:8333 +69.39.49.199:8333 +69.50.171.205:8333 +69.65.41.21:8333 +69.113.98.61:8333 +69.119.97.39:8333 +69.146.70.124:8333 +69.193.71.2:8333 +70.46.10.237:8333 +70.80.200.187:8333 +70.185.97.117:8333 +71.254.160.25:8333 +72.28.203.5:8333 72.52.130.110:8333 -72.53.111.37:8333 +72.83.194.122:8333 +72.128.32.167:8333 +72.179.136.80:8333 72.235.38.70:8333 -73.31.171.149:8333 -73.32.137.72:8333 -73.137.133.238:8333 -73.181.192.103:8333 -73.190.2.60:8333 -73.195.192.137:8333 -73.222.35.117:8333 -74.57.199.180:8333 -74.82.233.205:8333 -74.85.66.82:8333 -74.101.224.127:8333 -74.113.69.16:8333 -74.122.235.68:8333 -74.193.68.141:8333 -74.208.164.219:8333 -75.100.37.122:8333 -75.145.149.169:8333 -75.168.34.20:8333 -76.20.44.240:8333 -76.100.70.17:8333 -76.168.3.239:8333 -76.186.140.103:8333 -77.92.68.221:8333 -77.109.101.142:8333 -77.110.11.86:8333 -77.242.108.18:8333 -78.46.96.150:9020 +74.50.44.193:8333 +74.72.60.83:8333 +74.80.234.116:8333 +74.207.233.193:8333 +75.112.233.128:8333 +75.118.166.197:8333 +75.140.0.241:8333 +75.159.240.66:8333 +75.174.5.26:8333 +76.72.160.252:8333 +76.72.160.254:8333 +76.74.170.112:8333 +76.79.201.54:8333 +76.175.166.164:8333 +76.179.105.27:8333 +77.68.37.200:8333 +77.234.49.196:8333 +77.247.229.93:8333 +78.24.72.78:8333 +78.47.32.147:8333 78.84.100.95:8333 +78.121.69.23:8333 +78.129.167.5:8333 +78.193.96.155:8333 +79.19.37.179:8333 79.132.230.144:8333 79.133.43.63:8333 -79.160.76.153:8333 -79.169.34.24:8333 -79.188.7.78:8333 -80.217.226.25:8333 -80.223.100.179:8333 -80.240.129.221:8333 -81.1.173.243:8333 +79.134.201.66:8333 +79.169.35.235:8333 +80.57.227.14:8333 +80.64.65.87:8333 +80.86.92.70:8333 +80.100.203.151:8333 +80.101.32.121:8333 +80.161.178.73:8333 +80.240.129.170:8333 81.7.11.50:8333 -81.7.16.17:8333 -81.66.111.3:8333 -81.80.9.71:8333 -81.140.43.138:8333 -81.171.34.37:8333 -81.174.247.50:8333 -81.181.155.53:8333 -81.184.5.253:8333 -81.187.69.130:8333 -81.230.3.84:8333 -82.42.128.51:8333 -82.74.226.21:8333 -82.142.75.50:8333 +81.7.11.55:8333 +81.17.17.40:9333 +81.30.39.83:8333 +81.90.36.7:9444 +81.136.224.77:8333 +81.162.231.211:8333 +81.184.0.143:8333 +81.198.128.86:8333 +82.11.33.229:8333 +82.79.128.134:8333 +82.118.233.111:8333 +82.135.139.30:8333 82.199.102.10:8333 -82.200.205.30:8333 +82.221.106.17:8333 82.221.108.21:8333 -82.221.128.35:8333 -82.238.124.41:8333 -82.242.0.245:8333 -83.76.123.110:8333 +82.221.108.27:8333 +83.137.41.3:8333 +83.142.197.168:8333 +83.143.130.19:8333 83.150.9.196:8333 -83.162.196.192:8333 -83.162.234.224:8333 -83.170.104.91:8333 +83.183.17.191:8333 +83.227.173.83:8333 +83.230.5.15:8333 +83.233.105.151:443 +83.246.75.8:8333 +83.250.133.158:8333 83.255.66.118:8334 -84.2.34.104:8333 -84.45.98.91:8333 -84.47.161.150:8333 -84.212.192.131:8333 -84.215.169.101:8333 -84.238.140.176:8333 -84.245.71.31:8333 -85.17.4.212:8333 +84.24.69.59:8333 +84.42.193.6:8333 +84.45.98.87:8333 +84.54.128.11:8333 +84.212.200.24:8333 +84.215.198.109:8333 +84.230.4.177:8333 +85.95.228.83:8333 +85.95.228.123:8333 85.114.128.134:8333 -85.159.237.191:8333 -85.166.130.189:8333 -85.199.4.228:8333 85.214.66.168:8333 -85.214.195.210:8333 -85.229.0.73:8333 -86.21.96.45:8333 -87.48.42.199:8333 -87.81.143.82:8333 -87.81.251.72:8333 -87.104.24.185:8333 -87.104.168.104:8333 -87.117.234.71:8333 -87.118.96.197:8333 -87.145.12.57:8333 -87.159.170.190:8333 -88.150.168.160:8333 -88.208.0.79:8333 -88.208.0.149:8333 +85.214.147.162:8333 +85.243.168.4:8333 +86.1.0.18:8333 +87.79.77.106:8333 +87.91.156.110:8333 +87.236.196.222:8333 +88.85.75.152:8333 +88.87.1.230:8333 +88.87.92.102:8333 +88.89.69.202:8333 +88.97.72.229:8333 +88.164.117.99:8333 +88.198.32.131:8333 +88.202.230.87:8333 +88.214.193.154:8343 88.214.194.226:8343 -89.1.11.32:8333 -89.36.235.108:8333 -89.67.96.2:15321 -89.98.16.41:8333 -89.108.72.195:8333 -89.156.35.157:8333 -89.163.227.28:8333 -89.212.33.237:8333 -89.212.160.165:8333 -89.231.96.83:8333 -89.248.164.64:8333 -90.149.193.199:8333 -91.77.239.245:8333 -91.106.194.97:8333 +89.10.155.88:8333 +89.46.101.44:8333 +89.163.224.212:8333 +89.174.248.20:8333 +89.202.231.198:8333 +89.212.75.6:8333 +90.149.38.172:8333 +90.169.106.139:8333 +91.64.101.150:8333 +91.65.196.179:8333 +91.121.80.17:8333 91.126.77.77:8333 -91.134.38.195:8333 -91.156.97.181:8333 +91.145.76.156:8333 +91.152.150.35:8333 +91.192.137.17:8333 +91.196.170.110:8333 +91.197.44.133:8333 91.207.68.144:8333 -91.209.77.101:8333 +91.210.105.28:8333 +91.211.102.101:8333 +91.211.106.34:8333 91.214.200.205:8333 -91.220.131.242:8333 -91.220.163.18:8333 -91.233.23.35:8333 -92.13.96.93:8333 -92.14.74.114:8333 +91.220.43.146:8333 +91.222.71.89:8333 +91.224.140.242:8333 +91.229.76.14:8333 92.27.7.209:8333 -92.221.228.13:8333 -92.255.207.73:8333 -93.72.167.148:8333 -93.74.163.234:8333 -93.123.174.66:8333 -93.152.166.29:8333 -93.181.45.188:8333 -94.19.12.244:8333 +92.51.167.88:8333 +92.247.229.163:8333 +93.84.114.106:8333 +93.113.36.172:8333 +93.188.224.253:8333 +94.75.239.69:8333 94.190.227.112:8333 -94.198.135.29:8333 +94.214.2.74:8333 94.224.162.65:8333 -94.226.107.86:8333 -94.242.198.161:8333 -95.31.10.209:8333 -95.65.72.244:8333 -95.84.162.95:8333 -95.90.139.46:8333 -95.183.49.27:8005 -95.215.47.133:8333 -96.23.67.85:8333 -96.44.166.190:8333 -97.93.225.74:8333 -98.26.0.34:8333 -98.27.225.102:8333 -98.229.117.229:8333 -98.249.68.125:8333 -98.255.5.155:8333 -99.101.240.114:8333 +94.236.198.253:8333 +94.242.229.158:8333 +95.84.138.99:8333 +95.95.168.87:8333 +95.110.234.93:8333 +95.130.9.200:8333 +95.165.168.168:8333 +95.170.235.254:8333 +95.211.130.154:8333 +96.46.68.104:8333 +96.127.202.148:8333 +97.76.171.35:8333 +98.160.160.67:8333 +99.126.197.187:8333 +99.198.173.1:8333 101.100.174.138:8333 -101.251.203.6:8333 -103.3.60.61:8333 -103.30.42.189:8333 +101.164.201.208:8333 103.224.165.48:8333 -104.36.83.233:8333 -104.37.129.22:8333 -104.54.192.251:8333 +104.128.225.223:8333 104.128.228.252:8333 -104.128.230.185:8334 -104.130.161.47:8333 -104.131.33.60:8333 -104.143.0.156:8333 -104.156.111.72:8333 -104.167.111.84:8333 -104.193.40.248:8333 -104.197.7.174:8333 -104.197.8.250:8333 -104.223.1.133:8333 -104.236.97.140:8333 +104.131.192.94:8333 +104.155.45.201:8334 +104.194.28.195:8663 +104.211.1.27:8333 +104.221.38.177:8333 +104.236.9.79:8333 +104.236.129.178:8333 +104.236.186.249:8333 +104.236.194.15:8333 104.238.128.214:8333 104.238.130.182:8333 106.38.234.84:8333 106.185.36.204:8333 +106.185.38.67:8333 107.6.4.145:8333 107.150.2.6:8333 107.150.40.234:8333 -107.155.108.130:8333 -107.161.182.115:8333 -107.170.66.231:8333 -107.190.128.226:8333 +107.170.13.184:8333 +107.181.250.216:8333 +107.191.101.111:8333 107.191.106.115:8333 -108.16.2.61:8333 -109.70.4.168:8333 -109.162.35.196:8333 -109.163.235.239:8333 -109.190.196.220:8333 -109.191.39.60:8333 +108.59.12.163:8333 +108.161.129.247:8333 +109.193.160.140:8333 +109.197.13.54:8333 +109.230.7.248:8333 109.234.106.191:8333 -109.238.81.82:8333 -114.76.147.27:8333 -115.28.224.127:8333 -115.68.110.82:18333 -118.97.79.218:8333 -118.189.207.197:8333 -119.228.96.233:8333 -120.147.178.81:8333 -121.41.123.5:8333 -121.67.5.230:8333 -122.107.143.110:8333 -123.2.170.98:8333 -123.110.65.94:8333 -123.193.139.19:8333 -125.239.160.41:8333 -128.101.162.193:8333 +109.236.137.80:8333 +109.251.161.121:8333 +112.65.231.226:8333 +115.70.166.57:8333 +115.159.42.80:8333 +117.18.73.34:8333 +118.67.201.40:8333 +118.100.86.246:8333 +118.110.104.152:8333 +119.224.64.141:8333 +120.55.193.136:8333 +122.106.169.178:8333 +123.203.174.15:8333 +123.255.232.94:8333 +124.148.165.165:8333 +124.232.141.31:8333 +128.30.92.69:8333 +128.39.141.182:8333 +128.84.167.20:8333 128.111.73.10:8333 -128.140.229.73:8333 -128.175.195.31:8333 -128.199.107.63:8333 -128.199.192.153:8333 +128.127.38.195:8333 +128.140.224.162:8333 +128.199.101.104:8333 +128.233.224.35:8333 128.253.3.193:20020 -129.123.7.7:8333 -130.89.160.234:8333 -131.72.139.164:8333 -131.191.112.98:8333 -133.1.134.162:8333 -134.19.132.53:8333 -137.226.34.42:8333 -141.41.2.172:8333 -141.255.128.204:8333 -142.217.12.106:8333 -143.215.129.126:8333 +130.180.228.138:8333 +130.185.144.213:8333 +130.255.73.207:8333 +133.218.233.11:8333 +134.249.128.23:8333 +136.159.234.234:8333 +137.116.160.176:8333 +139.162.2.145:8333 +139.162.23.117:8333 +141.134.69.253:8333 +141.255.162.215:8333 +144.122.163.187:8333 +145.131.3.54:8333 +145.255.4.94:8333 146.0.32.101:8337 -147.229.13.199:8333 -149.210.133.244:8333 -149.210.162.187:8333 +147.83.72.91:8333 +148.103.28.68:8333 +149.5.32.102:8333 +149.210.164.195:8333 150.101.163.241:8333 151.236.11.189:8333 -153.121.66.211:8333 -154.20.2.139:8333 -159.253.23.132:8333 +152.3.136.56:8333 +154.20.208.25:8333 +158.181.104.149:8333 +159.253.96.226:8333 +160.36.130.180:8333 +162.209.1.233:8333 +162.209.4.125:8333 162.209.106.123:8333 162.210.198.184:8333 -162.218.65.121:8333 -162.222.161.49:8333 -162.243.132.6:8333 -162.243.132.58:8333 162.248.99.164:53011 162.248.102.117:8333 -163.158.35.110:8333 -164.15.10.189:8333 -164.40.134.171:8333 +162.251.108.53:8333 +163.44.2.48:8333 +163.158.36.17:8333 166.230.71.67:8333 -167.160.161.199:8333 -168.103.195.250:8333 -168.144.27.112:8333 -168.158.129.29:8333 -170.75.162.86:8333 -172.90.99.174:8333 -172.245.5.156:8333 -173.23.166.47:8333 +167.160.36.62:8333 +167.160.169.92:8333 +168.93.129.220:8333 +169.55.99.84:8333 +169.228.66.43:8333 +172.9.169.242:8333 173.32.11.194:8333 -173.34.203.76:8333 -173.171.1.52:8333 -173.175.136.13:8333 -173.230.228.139:8333 -173.247.193.70:8333 -174.49.132.28:8333 -174.52.202.72:8333 -174.53.76.87:8333 -174.109.33.28:8333 -176.28.12.169:8333 -176.35.182.214:8333 -176.36.33.113:8333 -176.36.33.121:8333 -176.58.96.173:8333 -176.121.76.84:8333 +173.230.228.136:8333 +173.246.107.34:8333 +173.254.235.34:8333 +174.0.128.222:8333 +174.25.130.148:8333 +174.50.64.101:8333 +175.140.232.141:8333 +176.36.37.62:8333 +176.46.9.96:8333 +176.124.110.27:8333 +177.39.16.102:8333 +178.17.173.2:8333 +178.62.5.248:8333 178.62.70.16:8333 -178.62.111.26:8333 -178.76.169.59:8333 -178.79.131.32:8333 -178.162.199.216:8333 -178.175.134.35:8333 -178.248.111.4:8333 -178.254.1.170:8333 +178.62.203.185:8333 +178.79.160.118:8333 +178.169.206.244:8333 +178.193.234.62:8333 +178.199.96.108:8333 +178.254.18.96:8333 178.254.34.161:8333 -179.43.143.120:8333 -179.208.156.198:8333 -180.200.128.58:8333 -183.78.169.108:8333 -183.96.96.152:8333 -184.68.2.46:8333 -184.73.160.160:8333 -184.94.227.58:8333 -184.152.68.163:8333 -185.7.35.114:8333 -185.28.76.179:8333 -185.31.160.202:8333 -185.45.192.129:8333 -185.66.140.15:8333 -186.2.167.23:8333 -186.220.101.142:8333 -188.26.5.33:8333 -188.75.136.146:8333 -188.120.194.140:8333 -188.121.5.150:8333 -188.138.0.114:8333 +178.255.41.123:8333 +180.210.34.58:9801 +182.92.226.212:8333 +182.171.246.142:8333 +184.23.8.9:8333 +184.58.162.35:8333 +184.154.9.170:8333 +185.8.238.165:8333 +185.24.97.11:8333 +185.31.137.139:8333 +185.38.44.64:8333 +185.53.128.180:8333 +185.53.129.244:8333 +185.77.129.119:8333 +185.77.129.156:8333 +185.82.203.92:8333 +188.20.97.18:8333 +188.126.8.14:8333 188.138.33.239:8333 -188.166.0.82:8333 +188.155.136.70:8333 +188.166.229.112:8333 188.182.108.129:8333 -188.191.97.208:8333 -188.226.198.102:8001 -190.10.9.217:8333 -190.75.143.144:8333 -190.139.102.146:8333 -191.237.64.28:8333 -192.3.131.61:8333 -192.99.225.3:8333 -192.110.160.122:8333 +188.226.225.174:8010 +188.242.171.8:8333 +188.243.4.139:8333 +190.10.9.234:8333 +190.10.10.147:8333 +190.81.160.184:8333 +190.85.201.37:8333 +192.34.227.230:8333 +192.77.189.200:8333 +192.124.224.7:8333 192.146.137.1:8333 -192.183.198.204:8333 192.203.228.71:8333 +192.206.202.20:8333 193.0.109.3:8333 -193.12.238.204:8333 -193.91.200.85:8333 -193.234.225.156:8333 -194.6.233.38:8333 -194.63.143.136:8333 -194.126.100.246:8333 -195.134.99.195:8333 -195.159.111.98:8333 -195.159.226.139:8333 +193.41.229.130:8333 +193.41.229.156:8333 +193.49.43.219:8333 +193.147.71.120:8333 +193.179.65.233:8333 +193.183.99.46:8333 +193.192.37.135:8333 +193.234.224.195:8333 +194.58.108.213:8333 +194.187.96.2:8333 +194.255.31.59:8333 +195.36.6.101:8333 +195.58.238.243:8333 195.197.175.190:8333 -198.48.199.108:8333 -198.57.208.134:8333 +195.239.1.66:8333 +198.48.196.230:8333 +198.50.192.160:8333 198.57.210.27:8333 -198.62.109.223:8333 +198.84.195.179:8333 198.167.140.8:8333 -198.167.140.18:8333 -199.91.173.234:8333 +198.204.224.106:8333 199.127.226.245:8333 -199.180.134.116:8333 -200.7.96.99:8333 -201.160.106.86:8333 -202.55.87.45:8333 -202.60.68.242:8333 -202.60.69.232:8333 -202.124.109.103:8333 -203.30.197.77:8333 -203.88.160.43:8333 +199.201.110.8:8333 +199.233.234.90:8333 +200.116.98.185:8333 +202.60.70.18:8333 203.151.140.14:8333 -203.219.14.204:8333 -205.147.40.62:8333 -207.235.39.214:8333 -207.244.73.8:8333 -208.12.64.225:8333 +204.112.203.52:8333 +205.200.247.149:8333 +207.226.141.253:8333 +207.255.42.202:8333 +208.53.164.19:8333 +208.66.68.127:8333 +208.66.68.130:8333 +208.71.171.232:8341 208.76.200.200:8333 -209.40.96.121:8333 -209.126.107.176:8333 -209.141.40.149:8333 -209.190.75.59:8333 -209.208.111.142:8333 -210.54.34.164:8333 -211.72.66.229:8333 +208.82.98.189:8333 +208.85.193.31:8333 +208.111.48.41:8333 +208.111.48.45:8333 +209.34.232.72:8333 +209.81.9.223:8333 +209.90.224.2:8333 +209.90.224.4:8333 +209.126.98.174:8333 +209.136.72.69:8333 +209.195.4.74:8333 +209.197.13.62:8333 +211.72.227.8:8333 212.51.144.42:8333 -212.112.33.157:8333 -212.116.72.63:8333 +212.71.233.127:8333 212.126.14.122:8333 +212.159.44.50:8333 +213.5.36.58:8333 +213.57.33.10:8333 213.66.205.194:8333 -213.111.196.21:8333 -213.122.107.102:8333 -213.136.75.175:8333 +213.136.73.125:8333 +213.155.3.216:8333 213.155.7.24:8333 -213.163.64.31:8333 -213.163.64.208:8333 -213.165.86.136:8333 -213.184.8.22:8333 +213.167.17.6:8333 +213.223.138.13:8333 216.15.78.182:8333 -216.55.143.154:8333 -216.115.235.32:8333 -216.126.226.166:8333 -216.145.67.87:8333 +216.38.129.164:8333 +216.48.168.8:8333 216.169.141.169:8333 -216.249.92.230:8333 +216.245.206.181:8333 +216.249.204.161:8333 216.250.138.230:8333 +217.11.225.189:8333 +217.12.34.158:8333 +217.12.202.33:8333 217.20.171.43:8333 -217.23.2.71:8333 -217.23.2.242:8333 -217.25.9.76:8333 -217.40.226.169:8333 -217.123.98.9:8333 -217.155.36.62:8333 +217.23.1.126:8333 +217.23.11.138:8333 +217.111.66.79:8333 +217.155.202.191:8333 +217.158.9.102:8333 217.172.32.18:20993 -218.61.196.202:8333 -218.231.205.41:8333 -220.233.77.200:8333 -223.18.226.85:8333 -223.197.203.82:8333 -223.255.166.142:8333 +220.245.196.37:8333 [2001:1291:2bf:1::100]:8333 -[2001:1418:100:5c2::2]:8333 -[2001:16d8:dd24:0:86c9:681e:f931:256]:8333 -[2001:19f0:1624:e6::579d:9428]:8333 -[2001:19f0:300:1340:225:90ff:fec9:2b6d]:8333 -[2001:19f0:4009:1405::64]:8333 -[2001:1b40:5000:2e::3fb0:6571]:8333 +[2001:1620:f00:282::2]:8333 +[2001:1620:f00:8282::1]:8333 +[2001:19f0:5000:8de8:5400:ff:fe12:55e4]:8333 +[2001:19f0:6c00:9103:5400:ff:fe10:a8d3]:8333 +[2001:1b60:3:172:142b:6dff:fe7a:117]:8333 [2001:410:a000:4050:8463:90b0:fffb:4e58]:8333 -[2001:410:a002:cafe:8463:90b0:fffb:4e58]:8333 -[2001:41d0:1:541e::1]:8333 -[2001:41d0:1:6a34::3]:8333 +[2001:4128:6135:2010:21e:bff:fee8:a3c0]:8333 +[2001:41d0:1008:761::17c]:8333 +[2001:41d0:1:45d8::1]:8333 [2001:41d0:1:6cd3::]:8333 [2001:41d0:1:8b26::1]:8333 -[2001:41d0:1:a33d::1]:8333 -[2001:41d0:1:b855::1]:8333 +[2001:41d0:1:afda::]:8200 +[2001:41d0:1:b26b::1]:8333 [2001:41d0:1:c139::1]:8333 [2001:41d0:1:c8d7::1]:8333 -[2001:41d0:1:dd3f::1]:8333 -[2001:41d0:1:e29d::1]:8333 [2001:41d0:1:f59f::33]:8333 [2001:41d0:1:f7cc::1]:8333 -[2001:41d0:1:ff87::1]:8333 -[2001:41d0:2:2f05::1]:8333 +[2001:41d0:2:1021::1]:8333 [2001:41d0:2:37c3::]:8200 -[2001:41d0:2:3e13::1]:8333 -[2001:41d0:2:8619::]:8333 +[2001:41d0:2:4797:2323:2323:2323:2323]:8333 +[2001:41d0:2:53df::]:8333 [2001:41d0:2:9c94::1]:8333 +[2001:41d0:2:9d3e::1]:8333 [2001:41d0:2:a24f::]:8333 -[2001:41d0:2:adbf::]:8333 -[2001:41d0:2:b721::1]:8333 -[2001:41d0:2:ee52::1]:8333 +[2001:41d0:2:a35a::]:8333 +[2001:41d0:2:b2b8::]:8333 +[2001:41d0:2:c1d9::]:8333 +[2001:41d0:2:c6e::]:8333 +[2001:41d0:2:c9bf::]:8333 [2001:41d0:2:f1a5::]:8333 -[2001:41d0:2:fa54::1]:8333 -[2001:41d0:51:1::2036]:8333 -[2001:41d0:52:a00::1a1]:8333 +[2001:41d0:52:a00::105f]:8333 [2001:41d0:52:cff::6f5]:8333 -[2001:41d0:52:d00::2c0]:8333 -[2001:41d0:52:d00::cf2]:8333 -[2001:41d0:8:1087::1]:8333 -[2001:41d0:8:4a3c::b7c]:8333 +[2001:41d0:52:d00::6e2]:8333 +[2001:41d0:8:3e75::1]:8333 +[2001:41d0:8:62ab::1]:8333 [2001:41d0:8:6728::]:8333 -[2001:41d0:8:b779::1]:8333 -[2001:41d0:8:c30f::1]:8333 -[2001:41d0:8:d2b2::1]:8333 -[2001:41d0:8:d5c3::1]:8333 +[2001:41d0:8:b30a::1]:8333 +[2001:41d0:8:bc26::1]:8333 +[2001:41d0:8:be9a::1]:8333 +[2001:41d0:8:d984::]:8333 [2001:41d0:8:eb8b::]:8333 -[2001:41d0:a:16d0::1]:8333 +[2001:41d0:a:13a2::1]:8333 [2001:41d0:a:2b18::1]:8333 -[2001:41d0:a:3a9c::1]:8333 -[2001:41d0:a:4903::]:8333 -[2001:41d0:a:57b::1]:8333 -[2001:41d0:a:5c7a::]:8333 +[2001:41d0:a:2d14::]:8333 +[2001:41d0:a:4558::1df2:76d3]:8333 +[2001:41d0:a:4aaa::]:8333 +[2001:41d0:a:635b::1]:8333 +[2001:41d0:a:63d8::1]:8333 [2001:41d0:a:6c29::1]:8333 -[2001:41d0:a:f482::1]:8333 -[2001:41d0:b:854:b7c:b7c:b7c:b7c]:8333 -[2001:41d0:d:111c::]:8333 -[2001:44b8:4116:7801:4216:7eff:fe78:3fe4]:8333 -[2001:470:1f08:837::2]:8333 -[2001:470:1f08:c33::2]:8333 -[2001:470:1f09:bca:218:7dff:fe10:be33]:8333 -[2001:470:1f0f:22d::212:26]:8333 +[2001:41d0:a:f9cd::1]:8333 +[2001:41d0:d:20a4::]:8333 +[2001:41d0:e:26b::1]:8333 +[2001:41d0:fc8c:a200:7a24:afff:fe9d:c69b]:8333 +[2001:41f0:61::7]:8333 +[2001:41f0::2]:8333 +[2001:44b8:41bd:6101:148e:4022:4950:e861]:8333 +[2001:470:1:2f9:0:1:107a:a301]:8333 +[2001:470:1f0b:ad6::2]:8333 [2001:470:1f11:12d5::ae1:5611]:8333 -[2001:470:1f14:57a::2]:8333 [2001:470:1f14:7d::2]:8333 -[2001:470:1f15:57c::1]:8333 -[2001:470:1f15:dda:3d9a:3f11:9a56:ed64]:8333 -[2001:470:25:482::2]:8333 -[2001:470:25:e4::2]:8333 -[2001:470:4:26b::2]:8333 +[2001:470:27:ce::2]:8333 +[2001:470:41:6::2]:8333 +[2001:470:507d:0:6ab5:99ff:fe73:ac18]:8333 +[2001:470:583e::2a]:8333 [2001:470:5f:5f::232]:8333 [2001:470:66:119::2]:8333 -[2001:470:67:39d::71]:8333 [2001:470:6c4f::cafe]:8333 -[2001:470:8:2e1::43]:8333 -[2001:470:90a7:96::afe:6021]:8333 +[2001:470:6f:327:913b:7fe:8545:a4f5]:8333 +[2001:470:7dda:1::1]:8333 [2001:470:95c1::2]:8333 [2001:470:b1d0:ffff::1000]:8333 -[2001:470:c1f2:3::201]:8333 [2001:470:d00d:0:3664:a9ff:fe9a:5150]:8333 -[2001:470:e250:0:211:11ff:feb9:924c]:8333 -[2001:4800:7817:101:be76:4eff:fe04:dc52]:8333 -[2001:4800:7819:104:be76:4eff:fe04:7809]:8333 +[2001:470:fab7:1::1]:8333 [2001:4800:7819:104:be76:4eff:fe05:c828]:8333 +[2001:4800:7819:104:be76:4eff:fe05:c9a0]:8333 +[2001:4801:7819:74:b745:b9d5:ff10:a61a]:8333 +[2001:4801:7819:74:b745:b9d5:ff10:aaec]:8333 +[2001:4801:7828:104:be76:4eff:fe10:1325]:8333 +[2001:4802:7800:1:be76:4eff:fe20:f023]:8333 [2001:4802:7800:2:30d7:1775:ff20:1858]:8333 +[2001:4802:7800:2:be76:4eff:fe20:6c26]:8333 [2001:4802:7802:101:be76:4eff:fe20:256]:8333 [2001:4802:7802:103:be76:4eff:fe20:2de8]:8333 [2001:4830:1100:2e8::2]:8333 -[2001:4ba0:fff7:181:dead::1]:8333 +[2001:4b98:dc2:41:216:3eff:fe56:f659]:8333 [2001:4ba0:fffa:5d::93]:8333 -[2001:4ba0:ffff:1be:1:1005:0:1]:8335 -[2001:4c48:110:101:216:3eff:fe24:1162]:8333 -[2001:4dd0:f101::32]:8333 +[2001:4ba0:ffff:1be:1:1005:0:1]:8333 [2001:4dd0:ff00:867f::3]:8333 [2001:4dd0:ff00:9a67::9]:8333 -[2001:4dd0:ff00:9c55:c23f:d5ff:fe6c:7ee9]:8333 [2001:5c0:1400:b::3cc7]:8333 -[2001:5c0:1400:b::3d01]:8333 -[2001:5c0:1400:b::8df]:8333 -[2001:5c0:1501:300::3]:8333 [2001:610:1b19::3]:8333 -[2001:620:500:fff0:f21f:afff:fecf:91cc]:8333 -[2001:67c:1220:80c:ad:8de2:f7e2:c784]:8333 -[2001:67c:21ec:1000::b]:8333 -[2001:6f8:1296:0:76d4:35ff:feba:1d26]:8333 -[2001:840:f000:4250:3e4a:92ff:fe6d:145f]:8333 +[2001:610:600:a41::2]:8333 +[2001:67c:26b4::]:8333 [2001:8d8:840:500::39:1ae]:8333 -[2001:980:efd8:0:21:de4a:2709:912]:8333 -[2001:981:46:1::3]:8333 -[2001:981:9319:2:c0:a8:c8:8]:8333 -[2001:9d8:cafe:3::91]:8333 -[2001:ad0:1:1:26be:5ff:fe25:959d]:8333 +[2001:8d8:965:4a00::10:9343]:8333 +[2001:980:4650:1:2e0:53ff:fe13:2449]:8333 +[2001:981:46:1:ba27:ebff:fe5b:edee]:8333 +[2001:9c8:53e9:369a:226:2dff:fe1b:7472]:8333 +[2001:9d8:cafe:3::87]:8333 +[2001:b10:11:21:3e07:54ff:fe48:7248]:8333 [2001:ba8:1f1:f34c::2]:8333 -[2001:bc8:381c:100::1]:8333 -[2002:175c:4caa::175c:4caa]:8333 -[2002:4404:82f1:0:8d55:8fbb:15fa:f4e0]:8333 -[2002:4475:2233:0:21f:5bff:fe33:9f70]:8333 -[2002:596c:48c3::596c:48c3]:8333 +[2001:bc8:2310:100::1]:8333 +[2001:bc8:3427:101:7a4f:8be:2611:6e79]:8333 +[2001:bc8:3505:200::1]:8333 +[2001:cc0:a004::30:1d]:8333 +[2001:e42:102:1209:153:121:76:171]:8333 +[2002:17ea:14eb::17ea:14eb]:8333 +[2002:2f8:2bc5::2f8:2bc5]:8333 +[2002:4047:482c::4047:482c]:8333 +[2002:45c3:8cca::45c3:8cca]:8333 +[2002:46bb:8a41:0:226:b0ff:feed:5f12]:8888 +[2002:46bb:8c3c:0:8d55:8fbb:15fa:f4e0]:8765 +[2002:4c48:a0fe::4c48:a0fe]:8333 +[2002:4d44:25c8::4d44:25c8]:8333 +[2002:505f:aaa2::505f:aaa2]:8333 +[2002:5bc1:799d::5bc1:799d]:8333 +[2002:6dec:5472::6dec:5472]:8333 [2002:8c6d:6521:9617:12bf:48ff:fed8:1724]:8333 -[2002:a646:5e6a::1:2]:8333 +[2002:ac52:94e2::ac52:94e2]:8333 +[2002:af7e:3eca::af7e:3eca]:8333 [2002:b009:20c5::b009:20c5]:8333 +[2002:c06f:39a0::c06f:39a0]:8333 +[2002:c23a:738a::c23a:738a]:8333 +[2002:c70f:7442::c70f:7442]:8333 +[2002:cec5:be4f::cec5:be4f]:8333 +[2002:d149:9e3a::d149:9e3a]:8333 +[2002:d917:ca5::d917:ca5]:8333 +[2400:8900::f03c:91ff:fe50:153f]:8333 [2400:8900::f03c:91ff:fe6e:823e]:8333 -[2400:8900::f03c:91ff:fe70:d164]:8333 -[2400:8901::f03c:91ff:fe37:9761]:8333 -[2403:4200:403:2::ff]:8333 -[2403:b800:1000:64:40a:e9ff:fe5f:94c1]:8333 -[2403:b800:1000:64:9879:17ff:fe6a:a59f]:8333 +[2400:8900::f03c:91ff:fea8:1934]:8333 +[2400:8901::f03c:91ff:fe26:c4d6]:8333 +[2400:8901::f03c:91ff:fec8:4280]:8333 +[2400:8901::f03c:91ff:fec8:660f]:8333 +[2401:1800:7800:102:be76:4eff:fe1c:559]:8333 +[2401:1800:7800:102:be76:4eff:fe1c:a7d]:8333 +[2405:aa00:2::40]:8333 [2600:3c00::f03c:91ff:fe18:59b2]:8333 -[2600:3c00::f03c:91ff:fe37:a4b1]:8333 -[2600:3c00::f03c:91ff:fe56:2973]:8333 +[2600:3c00::f03c:91ff:fe26:bfb6]:8333 +[2600:3c00::f03c:91ff:fe33:88e3]:8333 [2600:3c00::f03c:91ff:fe6e:7297]:8333 [2600:3c00::f03c:91ff:fe84:8a6e]:8333 [2600:3c01::f03c:91ff:fe18:6adf]:8333 -[2600:3c01::f03c:91ff:fe18:e217]:8333 -[2600:3c01::f03c:91ff:fe33:1b31]:8333 -[2600:3c01::f03c:91ff:fe33:2fe1]:8333 -[2600:3c01::f03c:91ff:fe33:a03f]:8333 +[2600:3c01::f03c:91ff:fe26:c4b8]:8333 +[2600:3c01::f03c:91ff:fe3b:1f76]:8333 [2600:3c01::f03c:91ff:fe50:5e06]:8333 -[2600:3c01::f03c:91ff:fe56:d645]:8333 -[2600:3c01::f03c:91ff:fe6e:a3dc]:8333 -[2600:3c01::f03c:91ff:fe89:a659]:8333 -[2600:3c02::f03c:91ff:fe6e:6f0b]:8333 -[2600:3c03::f03c:91ff:fe33:f6fb]:8333 +[2600:3c01::f03c:91ff:fe61:289b]:8333 +[2600:3c01::f03c:91ff:fe69:89e9]:8333 +[2600:3c01::f03c:91ff:fe84:ac15]:8333 +[2600:3c01::f03c:91ff:fe98:68bb]:8333 +[2600:3c02::f03c:91ff:fe26:713]:8333 +[2600:3c02::f03c:91ff:fe26:c49e]:8333 +[2600:3c02::f03c:91ff:fe84:97d8]:8333 +[2600:3c02::f03c:91ff:fec8:8feb]:8333 +[2600:3c03::f03c:91ff:fe18:da80]:8333 +[2600:3c03::f03c:91ff:fe26:c49b]:8333 [2600:3c03::f03c:91ff:fe50:5fa7]:8333 +[2600:3c03::f03c:91ff:fe67:d2e]:8333 [2600:3c03::f03c:91ff:fe6e:1803]:8333 -[2600:3c03::f03c:91ff:fe6e:4ac0]:8333 -[2601:6:4800:47f:1e4e:1f4d:332c:3bf6]:8333 -[2601:d:5400:fed:8d54:c1e8:7ed7:d45e]:8333 -[2602:100:4b8f:6d2a:20c:29ff:feaf:c4c2]:8333 +[2600:3c03::f03c:91ff:fec8:4bbe]:8333 +[2600:3c03::f03c:91ff:fee4:4e16]:8333 +[2601:18d:8300:58a6::2e4]:8333 +[2601:240:4600:40c0:250:56ff:fea4:6305]:8333 +[2601:581:c200:a719:542c:9cd5:4852:f7d9]:8333 +[2601:647:4900:85f1:ca2a:14ff:fe51:bb35]:8333 +[2601:c2:c002:b300:54a0:15b5:19f7:530d]:8333 +[2602:306:ccff:ad7f:b116:52be:64ba:db3a]:8333 +[2602:ae:1982:9400:846:f78c:fec:4d57]:8333 [2602:ffc5:1f::1f:2d61]:8333 [2602:ffc5:1f::1f:9211]:8333 +[2602:ffc5::75d5:c1c3]:8333 [2602:ffc5::ffc5:b844]:8333 [2602:ffe8:100:2::457:936b]:8333 -[2602:ffea:1001:125::2ad4]:8333 -[2602:ffea:1001:6ff::837d]:8333 +[2602:ffe8:100:2::9d20:2e3c]:8333 [2602:ffea:1001:72b::578b]:8333 -[2602:ffea:1001:77a::9cae]:8333 -[2602:ffea:1:2fe::6bc8]:8333 -[2602:ffea:1:701::7968]:8333 -[2602:ffea:1:70d::82ec]:8333 -[2602:ffea:1:9ff::e957]:8333 -[2602:ffea:1:a5d::4acb]:8333 [2602:ffea:a::24c4:d9fd]:8333 -[2602:ffea:a::c06:ae32]:8333 [2604:0:c1:100:1ec1:deff:fe54:2235]:8333 [2604:180:1:1af::42a9]:8333 -[2604:180::b208:398]:8333 -[2604:2880::6072:aed]:8333 +[2604:180:3:702::c9de]:8333 [2604:4080:1114:0:3285:a9ff:fe93:850c]:8333 -[2604:7c00:17:3d0::5a4d]:8333 -[2604:9a00:2100:a009:2::]:8333 -[2604:a880:1:20::22a:4001]:8333 -[2604:a880:800:10::752:f001]:8333 -[2604:c00:88:32:216:3eff:fee4:fcca]:8333 -[2604:c00:88:32:216:3eff:fef5:bc21]:8333 -[2605:7980:1:2::1761:3d4e]:8333 -[2605:e000:1417:4068:223:32ff:fe96:e2d]:8333 +[2604:6000:ffc0:3c:64a3:94d0:4f1d:1da8]:8333 +[2605:6000:f380:9a01:ba09:8aff:fed4:3511]:8333 +[2605:6001:e00f:7b00:c587:6d91:6eff:eeba]:8333 +[2605:f700:c0:1::25c3:2a3e]:8333 [2606:6000:a441:9903:5054:ff:fe78:66ff]:8333 -[2606:df00:2::ae85:8fc6]:8333 -[2607:5300:100:200::e7f]:8333 +[2607:5300:100:200::1c83]:9334 [2607:5300:10::a1]:8333 -[2607:5300:60:116e::1]:8333 -[2607:5300:60:1535::]:8333 -[2607:5300:60:1b32::1]:8333 -[2607:5300:60:2337::1]:8333 +[2607:5300:60:1c2f::1]:8333 [2607:5300:60:2b90::1]:8333 -[2607:5300:60:2d99::1]:8333 -[2607:5300:60:3cb::1]:8333 +[2607:5300:60:3320::1]:8333 +[2607:5300:60:385::1]:8333 [2607:5300:60:4a85::]:8333 -[2607:5300:60:5112:0:2:4af5:63fe]:8333 -[2607:5300:60:6dd5::]:8333 -[2607:5300:60:a91::1]:8333 -[2607:f1c0:820:1500::7f:3f44]:8333 +[2607:5300:60:65e4::]:8333 +[2607:5300:60:6918::]:8333 +[2607:5300:60:711a:78::a7b5]:8333 +[2607:5300:60:714::1]:8333 +[2607:5300:60:870::1]:8333 +[2607:5300:60:952e:3733::1414]:8333 [2607:f1c0:848:1000::48:943c]:8333 +[2607:f2e0:f:5df::2]:8333 +[2607:f748:1200:f8:21e:67ff:fe99:8f07]:8333 [2607:f948:0:1::7]:8333 -[2607:fcd0:100:2300::4ad:e594]:8333 -[2607:fcd0:100:2300::659e:9cb3]:8333 -[2607:fcd0:100:2300::c74b:a8ae]:8333 -[2607:fcd0:100:2300::d82:d8c2]:8333 -[2607:fcd0:100:4300::8795:2fa8]:8333 -[2607:fcd0:daaa:901::9561:e043]:8333 +[2607:ff68:100:36::131]:8333 +[2803:6900:1::117]:8333 +[2a00:1098:0:80:1000:25:0:1]:8333 +[2a00:1178:2:43:5054:ff:fe84:f86f]:8333 [2a00:1178:2:43:5054:ff:fee7:2eb6]:8333 -[2a00:1328:e100:cc42:230:48ff:fe92:55d]:8333 +[2a00:1178:2:43:8983:cc27:d72:d97a]:8333 +[2a00:1328:e100:cc42:230:48ff:fe92:55c]:8333 [2a00:14f0:e000:80d2:cd1a::1]:8333 -[2a00:16d8:c::5b6a:c261]:8333 -[2a00:61e0:4083:6d01:6852:1376:e972:2091]:8333 -[2a00:c98:2030:a02f:2::2]:8333 +[2a00:1630:2:1802:188:122:91:11]:8333 +[2a00:18e0:0:1800::1]:8333 +[2a00:18e0:0:dcc5:109:234:106:191]:8333 +[2a00:1a28:1157:87::94c7]:8333 +[2a00:1ca8:37::a5fc:40d1]:8333 +[2a00:1ca8:37::ab6d:ce2c]:8333 +[2a00:7143:100:0:216:3eff:fe2e:74a3]:8333 +[2a00:7143:100:0:216:3eff:fed3:5c21]:8333 +[2a00:7c80:0:45::123]:8333 +[2a00:dcc0:eda:98:183:193:c382:6bdb]:8333 +[2a00:dcc0:eda:98:183:193:f72e:d943]:8333 +[2a00:f820:17::4af:1]:8333 +[2a00:f940:2:1:2::101d]:8333 +[2a00:f940:2:1:2::6ac]:8333 [2a01:1b0:7999:402::131]:8333 -[2a01:1e8:e100:811c:700f:65f0:f72a:1084]:8333 -[2a01:238:42da:c500:6546:1293:5422:ab40]:8333 -[2a01:348:6:473::2]:8333 -[2a01:368:e010:2::2]:8333 -[2a01:430:17:1::ffff:549]:8333 -[2a01:430:17:1::ffff:830]:8333 -[2a01:488:66:1000:53a9:d04:0:1]:8333 -[2a01:488:66:1000:57e6:578c:0:1]:8333 +[2a01:238:42dd:f900:7a6c:2bc6:4041:c43]:8333 +[2a01:238:4313:6300:2189:1c97:696b:5ea]:8333 +[2a01:488:66:1000:5c33:91f9:0:1]:8333 [2a01:488:66:1000:b01c:178d:0:1]:8333 -[2a01:488:67:1000:523:fdce:0:1]:8333 -[2a01:488:67:1000:b01c:30ab:0:1]:8333 -[2a01:4f8:100:24aa::2]:8333 +[2a01:4f8:100:34ce::2]:8333 +[2a01:4f8:100:34e4::2]:8333 [2a01:4f8:100:44e7::2]:8333 +[2a01:4f8:100:510e::2]:8333 [2a01:4f8:100:5128::2]:8333 -[2a01:4f8:100:84a7::1:1]:8333 +[2a01:4f8:110:5105::2]:8333 [2a01:4f8:110:516c::2]:8333 -[2a01:4f8:110:536e::2]:8333 +[2a01:4f8:120:43e4::2]:8333 [2a01:4f8:120:62e6::2]:8333 [2a01:4f8:120:702e::2]:8333 -[2a01:4f8:120:8005::2]:8333 [2a01:4f8:120:8203::2]:8333 -[2a01:4f8:120:8422::2]:8333 -[2a01:4f8:121:11eb::2]:8333 +[2a01:4f8:121:234d::2]:8333 [2a01:4f8:121:261::2]:8333 -[2a01:4f8:130:242b::10]:8333 -[2a01:4f8:130:242b::5]:8333 -[2a01:4f8:130:2468::3]:8333 +[2a01:4f8:130:11ea::2]:8333 +[2a01:4f8:130:3332::2]:8333 +[2a01:4f8:130:40ab::2]:8333 [2a01:4f8:130:632c::2]:8333 [2a01:4f8:130:6366::2]:8333 -[2a01:4f8:130:6426::2]:8333 [2a01:4f8:130:934f::2]:8333 -[2a01:4f8:131:2070::2]:8333 -[2a01:4f8:131:54a2::2]:8333 -[2a01:4f8:140:80ad::2]:8333 +[2a01:4f8:131:33ad:fea1::666]:8333 +[2a01:4f8:140:2195::2]:8333 +[2a01:4f8:140:6333::2]:8333 +[2a01:4f8:140:930d::2]:8333 +[2a01:4f8:140:93b0::2]:8333 +[2a01:4f8:141:1167::2]:8333 [2a01:4f8:141:186::2]:8333 -[2a01:4f8:150:210b::2]:8333 -[2a01:4f8:150:2263::5]:8333 -[2a01:4f8:150:2349::2]:8333 -[2a01:4f8:150:61ee::2]:8333 -[2a01:4f8:150:7088:5054:ff:fe45:bff2]:8333 +[2a01:4f8:141:53f0::2]:8333 +[2a01:4f8:150:336a::2]:8333 +[2a01:4f8:150:72ee::4202]:8333 [2a01:4f8:150:8324::2]:9001 -[2a01:4f8:151:1d8::2]:8333 +[2a01:4f8:151:21ca::2]:8333 +[2a01:4f8:151:41c2:0:5404:a67e:f250]:8333 [2a01:4f8:151:5128::2]:8333 +[2a01:4f8:151:52c6::154]:8333 [2a01:4f8:151:6347::2]:9001 -[2a01:4f8:161:526d::2]:8333 -[2a01:4f8:161:9349::2]:8333 -[2a01:4f8:162:23c6::2]:8333 -[2a01:4f8:162:4348::2]:8333 -[2a01:4f8:162:7345::2]:8333 -[2a01:4f8:162:7383::2]:8333 -[2a01:4f8:162:74e3::2]:8333 -[2a01:4f8:190:6065::2]:8333 -[2a01:4f8:190:6349::2]:8333 +[2a01:4f8:160:5136::2]:8333 +[2a01:4f8:160:72c5::2858:e1c5]:8333 +[2a01:4f8:160:72c5::593b:60d5]:8333 +[2a01:4f8:160:814f::2]:8333 +[2a01:4f8:161:13d0::2]:8333 +[2a01:4f8:161:228f::2]:8333 +[2a01:4f8:161:51c4::2]:8333 +[2a01:4f8:161:60a7::2]:8333 +[2a01:4f8:161:7026::2]:8333 +[2a01:4f8:161:9184::2]:8333 +[2a01:4f8:162:2108::2]:8333 +[2a01:4f8:162:218c::2]:8333 +[2a01:4f8:162:4443::2]:8333 +[2a01:4f8:162:51a3::2]:8333 +[2a01:4f8:171:b93::2]:8333 +[2a01:4f8:190:1483::1]:8333 +[2a01:4f8:190:4495::2]:8333 [2a01:4f8:190:64c9::2]:8333 [2a01:4f8:190:91ce::2]:8333 [2a01:4f8:191:2194::83]:8333 -[2a01:4f8:191:40a1::2]:8333 -[2a01:4f8:191:4a7::2]:8333 -[2a01:4f8:191:63b4:5000::1]:8333 -[2a01:4f8:191:7121::2]:8333 +[2a01:4f8:191:40e8::2]:8333 +[2a01:4f8:191:44b4::2]:8333 +[2a01:4f8:191:8242::2]:8333 [2a01:4f8:191:83a2::2]:8333 -[2a01:4f8:191:93c4::2]:8333 -[2a01:4f8:192:60a9:0:1:5:2]:8333 -[2a01:4f8:192:73b2::2]:8333 -[2a01:4f8:192:8098::2]:8333 +[2a01:4f8:192:11b2::2]:8333 +[2a01:4f8:192:216c::2]:8333 +[2a01:4f8:192:22b3::2]:8333 +[2a01:4f8:192:440b::2]:8333 [2a01:4f8:192:db::2]:8333 [2a01:4f8:200:1012::2]:8333 -[2a01:4f8:200:22e3::2]:8333 -[2a01:4f8:200:414e::2]:8333 -[2a01:4f8:200:63af::222]:8333 +[2a01:4f8:200:23d1::dead:beef]:8333 +[2a01:4f8:200:506d::2]:8333 +[2a01:4f8:200:51f0::2]:8333 +[2a01:4f8:200:5389::2]:8333 +[2a01:4f8:200:53e3::2]:8333 +[2a01:4f8:200:6344::2]:8333 +[2a01:4f8:200:6396::2]:8333 +[2a01:4f8:200:63af::119]:8333 [2a01:4f8:200:71e3:78b4:f3ff:fead:e8cf]:8333 -[2a01:4f8:201:5164::2]:8333 +[2a01:4f8:201:214c::2]:8333 +[2a01:4f8:201:233:1::3]:8333 +[2a01:4f8:201:3e3::2]:8333 [2a01:4f8:201:6011::4]:8333 [2a01:4f8:201:60d5::2]:8333 +[2a01:4f8:202:265::2]:8333 +[2a01:4f8:202:3115::2]:8333 +[2a01:4f8:202:31e3::2]:8333 +[2a01:4f8:202:31ef::2]:8333 +[2a01:4f8:202:3392::2]:8333 [2a01:4f8:202:53c3::2]:8333 +[2a01:4f8:202:63f4::2]:8333 +[2a01:4f8:202:7227::2]:8333 +[2a01:4f8:210:2227::2]:8333 [2a01:4f8:210:24aa::2]:8333 -[2a01:4f8:210:502f::2]:8333 [2a01:4f8:211:14cf::2]:8333 -[2a01:4f8:211:1a59::2]:8333 -[2a01:4f8:211:2ac1::2]:8333 -[2a01:4f8:211:cca::2]:8333 -[2a01:4f8:a0:22a5::2]:8333 -[2a01:4f8:a0:5023::2]:8333 +[2a01:4f8:211:181b::2]:8333 +[2a01:4f8:212:289e::2]:8333 +[2a01:4f8:212:33db::2]:18333 +[2a01:4f8:a0:112f::2]:8333 +[2a01:4f8:a0:3174::2]:8333 +[2a01:4f8:a0:328c::2]:8333 [2a01:4f8:a0:5243::2]:8333 -[2a01:4f8:a0:74c8::2]:8333 -[2a01:4f8:a0:8227::2]:8333 -[2a01:4f8:a0:822d::2]:8333 -[2a01:4f8:d13:2183::2]:8333 +[2a01:4f8:c17:19b9::2]:8333 +[2a01:4f8:c17:1a41::2]:8333 +[2a01:4f8:c17:1a92::2]:8333 +[2a01:4f8:c17:273::2]:8333 +[2a01:4f8:c17:435::2]:8333 +[2a01:4f8:c17:755::2]:8333 +[2a01:4f8:c17:b54::2]:8333 +[2a01:4f8:d16:9384::2]:8333 [2a01:608:ffff:a009:8bf5:879d:e51a:f837]:8333 -[2a01:79d:469e:ed94:c23f:d5ff:fe65:20c5]:8333 -[2a01:7c8:aab5:3e6:5054:ff:fed7:4e54]:8333 +[2a01:680:10:10:f2de:f1ff:fec9:dc0]:8333 +[2a01:7c8:aaac:1f6:5054:ff:fe30:e585]:8333 +[2a01:7c8:aaac:20b:5054:ff:fe24:435e]:8333 +[2a01:7c8:aaac:43d:5054:ff:fe4e:3dd4]:8333 +[2a01:7c8:aaad:256::1]:8333 +[2a01:7c8:aab6:ea:5054:ff:feff:eac3]:8333 +[2a01:7c8:aab9:5a:5054:ff:fe89:7b26]:8333 +[2a01:7c8:aabc:2c8:5054:ff:fe35:6581]:8333 [2a01:7e00::f03c:91ff:fe18:301e]:8333 -[2a01:7e00::f03c:91ff:fe18:7749]:8333 -[2a01:7e00::f03c:91ff:fe33:2d67]:8333 -[2a01:7e00::f03c:91ff:fe33:347c]:8333 -[2a01:7e00::f03c:91ff:fe33:ae50]:8333 -[2a01:7e00::f03c:91ff:fe56:6b5c]:8333 -[2a01:7e00::f03c:91ff:fe56:bee6]:8333 -[2a01:7e00::f03c:91ff:fe69:4895]:8333 -[2a01:7e00::f03c:91ff:fe69:9912]:8333 -[2a01:7e00::f03c:91ff:fe6e:26ee]:8333 -[2a01:7e00::f03c:91ff:fe73:42f1]:8333 +[2a01:7e00::f03c:91ff:fe18:3942]:8333 +[2a01:7e00::f03c:91ff:fe26:8c87]:8333 +[2a01:7e00::f03c:91ff:fe50:6206]:8333 +[2a01:7e00::f03c:91ff:fe67:559d]:8333 [2a01:7e00::f03c:91ff:fe84:434f]:8333 -[2a01:7e00::f03c:91ff:fe84:b36b]:8333 -[2a01:7e00::f03c:91ff:fe89:1faa]:8333 -[2a01:7e00::f03c:91ff:fe98:816]:8333 +[2a01:7e00::f03c:91ff:fe89:1143]:8333 +[2a01:7e00::f03c:91ff:fe98:2505]:8333 [2a01:7e00::f03c:91ff:fedb:352e]:8333 -[2a01:7e00::f03c:91ff:fedb:4a1d]:8333 -[2a01:e34:edbb:6750:224:1dff:fe89:3897]:8333 -[2a01:e35:2f1d:3fb0:7187:c7ba:bcfc:80ce]:8333 -[2a01:e35:8787:96f0:9032:9297:39ae:496d]:8333 +[2a01:7e01::f03c:91ff:fec8:d7b5]:8333 +[2a01:e34:ee33:1640:c504:f677:b28a:ba42]:8333 +[2a01:e35:2e7e:bc0:e079:f55e:cef3:b5d7]:8333 +[2a01:e35:2ee5:610:21f:d0ff:fe4e:7460]:8333 [2a01:e35:8a3f:47c0:c617:feff:fe3c:9fbd]:8333 -[2a01:e35:8b66:6a0:4900:9dfd:d841:d025]:8333 -[2a02:168:4a01::39]:8333 -[2a02:168:5404:2:c23f:d5ff:fe6a:512e]:8333 -[2a02:180:1:1::5b8f:538c]:8333 -[2a02:2028:1016::2]:8333 -[2a02:2528:503:2::14]:8333 +[2a01:e35:8aca:6a0:211:aff:fe5e:295e]:8333 +[2a02:180:a:18:81:7:11:50]:8333 +[2a02:1810:1d87:6a00:5604:a6ff:fe60:d87d]:8333 +[2a02:2168:1144:5c01:d63d:7eff:fedd:4f8e]:8333 +[2a02:2498:6d7b:7001:b508:b39d:2cea:5b7a]:8333 [2a02:2528:503:2::15]:8333 -[2a02:2528:ff00:81a6:21e:c5ff:fe8d:f9a5]:8333 -[2a02:2770:5:0:21a:4aff:fee4:c7db]:8333 -[2a02:2770:8:0:21a:4aff:fe7b:3dcd]:8333 -[2a02:348:5e:5a29::1]:8333 -[2a02:7aa0:1619::202f:c06a]:8333 -[2a02:8109:8e40:35fc:ba27:ebff:feae:cf16]:8333 -[2a02:af8:6:1500::1:130]:8333 -[2a02:c200:0:10:1:0:6314:2222]:8333 -[2a02:c200:0:10:2:3:3295:1]:8332 -[2a02:c200:0:10:3:0:5449:1]:8333 -[2a02:c200:1:10:2:3:5899:1]:8333 -[2a02:c200:1:10::2705:1]:8333 -[2a02:ce80:0:20::1]:8333 -[2a02:fe0:c321:27e0:6ef0:49ff:fe11:a61d]:8333 +[2a02:2528:fa:1a56:216:44ff:fe6a:d112]:8333 +[2a02:27f8:2012:0:e9f7:268f:c441:6129]:8333 +[2a02:348:86:3011::1]:8333 +[2a02:4780:1:1::1:8a01]:8333 +[2a02:578:5002:116::2]:8333 +[2a02:6080::1:190b:69e3]:8333 +[2a02:6080::1:e893:d9d6]:8333 +[2a02:770:4000::139]:8333 +[2a02:7aa0:1201::deb3:81a2]:8333 +[2a02:8010:b001::5860:59b5]:8333 +[2a02:810d:21c0:f00:a248:1cff:feb8:5348]:8333 +[2a02:a50::21b:24ff:fe93:4e39]:8333 +[2a02:a80:0:1200::2]:8333 +[2a02:c200:0:10:2:1:5830:1]:8333 +[2a02:c200:0:10:2:5:4692:1]:8333 +[2a02:c200:0:10:3:0:7158:1]:8333 +[2a02:c200:0:10::2244:1]:8333 +[2a02:c200:1:10:2:3:3339:1]:8333 +[2a02:c200:1:10:2:3:7844:1]:8333 +[2a02:c200:1:10:2:5:6288:1]:8333 +[2a02:c200:1:10:3:0:5912:1]:8333 [2a03:4000:2:496::8]:8333 -[2a03:b0c0:0:1010::62:f001]:8333 +[2a03:4000:6:8009::1]:8333 +[2a03:4000:6:8063::bcd0]:8333 +[2a03:4900:fffc:b::2]:8333 +[2a03:b0c0:1:d0::d:5001]:8333 +[2a03:f80:ed15:149:154:155:235:1]:8333 +[2a03:f80:ed15:149:154:155:241:1]:8333 [2a03:f80:ed16:ca7:ea75:b12d:2af:9e2a]:8333 +[2a04:1980:3100:1aab:290:faff:fe70:a3d8]:8333 +[2a04:1980:3100:1aab:e61d:2dff:fe29:f590]:8333 +[2a04:2f80:6:200::89]:8333 +[2a04:ac00:1:4a0b:5054:ff:fe00:5af5]:8333 +[2a04:ad80:0:68::35da]:8333 3ffk7iumtx3cegbi.onion:8333 -3hshaantu6ot4upz.onion:8333 -45c5lc77qgpikafy.onion:8333 +3nmbbakinewlgdln.onion:8333 +4j77gihpokxu2kj4.onion:8333 +546esc6botbjfbxb.onion:8333 +5at7sq5nm76xijkd.onion:8333 77mx2jsxaoyesz2p.onion:8333 7g7j54btiaxhtsiy.onion:8333 -b6fr7dlbu2kpiysf.onion:8333 -bitcoincfqcssig5.onion:8333 +a6obdgzn67l7exu3.onion:8333 +ab64h7olpl7qpxci.onion:8333 +am2a4rahltfuxz6l.onion:8333 +azuxls4ihrr2mep7.onion:8333 +bitcoin7bi4op7wb.onion:8333 bitcoinostk4e4re.onion:8333 +bk7yp6epnmcllq72.onion:8333 bmutjfrj5btseddb.onion:8333 -drp4pvejybx2ejdr.onion:8333 -gixnv56d63buypan.onion:8333 +ceeji4qpfs3ms3zc.onion:8333 +clexmzqio7yhdao4.onion:8333 +gb5ypqt63du3wfhn.onion:8333 h2vlpudzphzqxutd.onion:8333 -hhiv5pnxenvbf4am.onion:8333 -lzxpkn6ptp3ohh63.onion:8333 -msphsgfiqfq5stne.onion:8333 +n42h7r6oumcfsbrs.onion:4176 ncwk3lutemffcpc4.onion:8333 okdzjarwekbshnof.onion:8333 -sjdomi4yb2dwkjbc.onion:8333 -uvwozwxlihntigbb.onion:8333 -v6ylz45dn5ybpk4d.onion:8333 +pjghcivzkoersesd.onion:8333 +rw7ocjltix26mefn.onion:8333 +uws7itep7o3yinxo.onion:8333 vk3qjdehyy4dwcxw.onion:8333 vqpye2k5rcqvj5mq.onion:8333 -xudkoztdfrsuyyou.onion:8333 -z55v4ostefnwfy32.onion:8333 +wpi7rpvhnndl52ee.onion:8333 diff --git a/depends/config.guess b/depends/config.guess index b3f905370..fba6e87a0 100755 --- a/depends/config.guess +++ b/depends/config.guess @@ -2,7 +2,7 @@ # Attempt to guess a canonical system name. # Copyright 1992-2015 Free Software Foundation, Inc. -timestamp='2015-10-21' +timestamp='2015-11-19' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -1393,6 +1393,9 @@ EOF x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; esac cat >&2 <=70011` as of **v0.12.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579)). +* [`BIP 125`](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki): Opt-in full replace-by-fee signaling honoured in mempool and mining as of **v0.12.0** ([PR 6871](https://github.com/bitcoin/bitcoin/pull/6871)). +* [`BIP 130`](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki): direct headers announcement is negotiated with peer versions `>=70012` as of **v0.12.0** ([PR 6494](https://github.com/bitcoin/bitcoin/pull/6494)). diff --git a/doc/build-osx.md b/doc/build-osx.md index 02498e5c4..c3cb1b789 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -5,7 +5,7 @@ This guide will show you how to build bitcoind (headless client) for OS X. Notes ----- -* Tested on OS X 10.7 through 10.10 on 64-bit Intel processors only. +* Tested on OS X 10.7 through 10.11 on 64-bit Intel processors only. * All of the commands should be executed in a Terminal application. The built-in one is located in `/Applications/Utilities`. @@ -24,7 +24,7 @@ be re-done or updated every time Xcode is updated. You will also need to install [Homebrew](http://brew.sh) in order to install library dependencies. -The installation of the actual dependencies is covered in the Instructions +The installation of the actual dependencies is covered in the instructions sections below. Instructions: Homebrew @@ -36,17 +36,19 @@ Instructions: Homebrew NOTE: Building with Qt4 is still supported, however, could result in a broken UI. As such, building with Qt5 is recommended. -### Building `bitcoind` +### Building `bitcoin` 1. Clone the GitHub tree to get the source code and go into the directory. git clone https://github.com/bitcoin/bitcoin.git cd bitcoin -2. Build bitcoind: +2. Build bitcoin-core: + This will configure and build the headless bitcoin binaries as well as the gui (if Qt is found). + You can disable the gui build by passing `--without-gui` to configure. ./autogen.sh - ./configure --with-gui=qt5 + ./configure make 3. It is also a good idea to build and run the unit tests: @@ -60,10 +62,10 @@ NOTE: Building with Qt4 is still supported, however, could result in a broken UI Use Qt Creator as IDE ------------------------ You can use Qt Creator as IDE, for debugging and for manipulating forms, etc. -Download Qt Creator from http://www.qt.io/download/. Download the "community edition" and only install Qt Creator (uncheck the rest during the installation process). +Download Qt Creator from https://www.qt.io/download/. Download the "community edition" and only install Qt Creator (uncheck the rest during the installation process). 1. Make sure you installed everything through Homebrew mentioned above -2. Do a proper ./configure --with-gui=qt5 --enable-debug +2. Do a proper ./configure --enable-debug 3. In Qt Creator do "New Project" -> Import Project -> Import Existing Project 4. Enter "bitcoin-qt" as project name, enter src/qt as location 5. Leave the file selection as it is @@ -79,7 +81,7 @@ You can ignore this section if you are building `bitcoind` for your own use. bitcoind/bitcoin-cli binaries are not included in the Bitcoin-Qt.app bundle. -If you are building `bitcoind` or `Bitcoin-Qt` for others, your build machine should be set up +If you are building `bitcoind` or `Bitcoin Core` for others, your build machine should be set up as follows for maximum compatibility: All dependencies should be compiled with these flags: @@ -88,7 +90,7 @@ All dependencies should be compiled with these flags: -arch x86_64 -isysroot $(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk -Once dependencies are compiled, see [doc/release-process.md](release-process.md) for how the Bitcoin-Qt.app +Once dependencies are compiled, see [doc/release-process.md](release-process.md) for how the Bitcoin Core bundle is packaged and signed to create the .dmg disk image that is distributed. Running diff --git a/doc/build-unix.md b/doc/build-unix.md index 159a14060..60c9d57b0 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -50,18 +50,21 @@ Optional dependencies: For the versions used in the release, see [release-process.md](release-process.md) under *Fetch and build inputs*. -System requirements +Memory Requirements -------------------- -C++ compilers are memory-hungry. It is recommended to have at least 1 GB of -memory available when compiling Bitcoin Core. With 512MB of memory or less -compilation will take much longer due to swap thrashing. +C++ compilers are memory-hungry. It is recommended to have at least 1.5 GB of +memory available when compiling Bitcoin Core. On systems with less, gcc can be +tuned to conserve memory with additional CXXFLAGS: + + + ./configure CXXFLAGS="--param ggc-min-expand=1 --param ggc-min-heapsize=32768" Dependency Build Instructions: Ubuntu & Debian ---------------------------------------------- Build requirements: - sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev libevent-dev bsdmainutils + sudo apt-get install build-essential libtool autotools-dev automake pkg-config libssl-dev libevent-dev bsdmainutils On at least Ubuntu 14.04+ and Debian 7+ there are generic names for the individual boost development packages, so the following can be used to only @@ -236,3 +239,9 @@ In this case there is no dependency on Berkeley DB 4.8. Mining is also possible in disable-wallet mode, but only using the `getblocktemplate` RPC call not `getwork`. + +Additional Configure Flags +-------------------------- +A list of additional configure flags can be displayed with: + + ./configure --help diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 7fe292f1f..358792251 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -204,3 +204,172 @@ If a set of tools is used by the build system or scripts the repository (for example, lcov) it is perfectly acceptable to add its files to `.gitignore` and commit them. +Development guidelines +============================ + +A few non-style-related recommendations for developers, as well as points to +pay attention to for reviewers of Bitcoin Core code. + +General Bitcoin Core +---------------------- + +- New features should be exposed on RPC first, then can be made available in the GUI + + - *Rationale*: RPC allows for better automatic testing. The test suite for + the GUI is very limited + +- Make sure pull requests pass Travis CI before merging + + - *Rationale*: Makes sure that they pass thorough testing, and that the tester will keep passing + on the master branch. Otherwise all new pull requests will start failing the tests, resulting in + confusion and mayhem + + - *Explanation*: If the test suite is to be updated for a change, this has to + be done first + +Wallet +------- + +- Make sure that no crashes happen with run-time option `-disablewallet`. + + - *Rationale*: In RPC code that conditionally uses the wallet (such as + `validateaddress`) it is easy to forget that global pointer `pwalletMain` + can be NULL. See `qa/rpc-tests/disablewallet.py` for functional tests + exercising the API with `-disablewallet` + +- Include `db_cxx.h` (BerkeleyDB header) only when `ENABLE_WALLET` is set + + - *Rationale*: Otherwise compilation of the disable-wallet build will fail in environments without BerkeleyDB + +General C++ +------------- + +- Assertions should not have side-effects + + - *Rationale*: Even though the source code is set to to refuse to compile + with assertions disabled, having side-effects in assertions is unexpected and + makes the code harder to understand + +- If you use the `.h`, you must link the `.cpp` + + - *Rationale*: Include files define the interface for the code in implementation files. Including one but + not linking the other is confusing. Please avoid that. Moving functions from + the `.h` to the `.cpp` should not result in build errors + +- Use the RAII (Resource Acquisition Is Initialization) paradigm where possible. For example by using + `scoped_pointer` for allocations in a function. + + - *Rationale*: This avoids memory and resource leaks, and ensures exception safety + +C++ data structures +-------------------- + +- Never use the `std::map []` syntax when reading from a map, but instead use `.find()` + + - *Rationale*: `[]` does an insert (of the default element) if the item doesn't + exist in the map yet. This has resulted in memory leaks in the past, as well as + race conditions (expecting read-read behavior). Using `[]` is fine for *writing* to a map + +- Do not compare an iterator from one data structure with an iterator of + another data structure (even if of the same type) + + - *Rationale*: Behavior is undefined. In C++ parlor this means "may reformat + the universe", in practice this has resulted in at least one hard-to-debug crash bug + +- Watch out for vector out-of-bounds exceptions. `&vch[0]` is illegal for an + empty vector, `&vch[vch.size()]` is always illegal. Use `begin_ptr(vch)` and + `end_ptr(vch)` to get the begin and end pointer instead (defined in + `serialize.h`) + +- Vector bounds checking is only enabled in debug mode. Do not rely on it + +- Make sure that constructors initialize all fields. If this is skipped for a + good reason (i.e., optimization on the critical path), add an explicit + comment about this + + - *Rationale*: Ensure determinism by avoiding accidental use of uninitialized + values. Also, static analyzers balk about this. + +- Use explicitly signed or unsigned `char`s, or even better `uint8_t` and + `int8_t`. Do not use bare `char` unless it is to pass to a third-party API. + This type can be signed or unsigned depending on the architecture, which can + lead to interoperability problems or dangerous conditions such as + out-of-bounds array accesses + +- Prefer explicit constructions over implicit ones that rely on 'magical' C++ behavior + + - *Rationale*: Easier to understand what is happening, thus easier to spot mistakes, even for those + that are not language lawyers + +Strings and formatting +------------------------ + +- Be careful of `LogPrint` versus `LogPrintf`. `LogPrint` takes a `category` argument, `LogPrintf` does not. + + - *Rationale*: Confusion of these can result in runtime exceptions due to + formatting mismatch, and it is easy to get wrong because of subtly similar naming + +- Use `std::string`, avoid C string manipulation functions + + - *Rationale*: C++ string handling is marginally safer, less scope for + buffer overflows and surprises with `\0` characters. Also some C string manipulations + tend to act differently depending on platform, or even the user locale + +- Use `ParseInt32`, `ParseInt64`, `ParseDouble` from `utilstrencodings.h` for number parsing + + - *Rationale*: These functions do overflow checking, and avoid pesky locale issues + +- For `strprintf`, `LogPrint`, `LogPrintf` formatting characters don't need size specifiers + + - *Rationale*: Bitcoin Core uses tinyformat, which is type safe. Leave them out to avoid confusion + +Threads and synchronization +---------------------------- + +- Build and run tests with `-DDEBUG_LOCKORDER` to verify that no potential + deadlocks are introduced. As of 0.12, this is defined by default when + configuring with `--enable-debug` + +- When using `LOCK`/`TRY_LOCK` be aware that the lock exists in the context of + the current scope, so surround the statement and the code that needs the lock + with braces + + OK: + +```c++ +{ + TRY_LOCK(cs_vNodes, lockNodes); + ... +} +``` + + Wrong: + +```c++ +TRY_LOCK(cs_vNodes, lockNodes); +{ + ... +} +``` + +Source code organization +-------------------------- + +- Implementation code should go into the `.cpp` file and not the `.h`, unless necessary due to template usage or + when performance due to inlining is critical + + - *Rationale*: Shorter and simpler header files are easier to read, and reduce compile time + +- Don't import anything into the global namespace (`using namespace ...`). Use + fully specified types such as `std::string`. + + - *Rationale*: Avoids symbol conflicts + +GUI +----- + +- Do not display or manipulate dialogs in model code (classes `*Model`) + + - *Rationale*: Model classes pass through events and data from the core, they + should not interact with the user. That's where View classes come in. The converse also + holds: try to not directly access core data structures from Views. diff --git a/doc/gitian-building.md b/doc/gitian-building.md index 019e85169..5ca91505e 100644 --- a/doc/gitian-building.md +++ b/doc/gitian-building.md @@ -74,11 +74,11 @@ In the VirtualBox GUI click "Create" and choose the following parameters in the - File location and size: at least 40GB; as low as 20GB *may* be possible, but better to err on the safe side - Click `Create` -Get the [Debian 8.x net installer](http://cdimage.debian.org/debian-cd/8.2.0/amd64/iso-cd/debian-8.2.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). +Get the [Debian 8.x net installer](http://cdimage.debian.org/debian-cd/8.3.0/amd64/iso-cd/debian-8.3.0-amd64-netinst.iso) (a more recent minor version should also work, see also [Debian Network installation](https://www.debian.org/CD/netinst/)). This DVD image can be validated using a SHA256 hashing tool, for example on Unixy OSes by entering the following in a terminal: - echo "d393d17ac6b3113c81186e545c416a00f28ed6e05774284bb5e8f0df39fcbcb9 debian-8.2.0-amd64-netinst.iso" | sha256sum -c + echo "dd25bcdde3c6ea5703cc0f313cde621b13d42ff7d252e2538a11663c93bf8654 debian-8.3.0-amd64-netinst.iso" | sha256sum -c # (must return OK) After creating the VM, we need to configure it. @@ -259,15 +259,15 @@ adduser debian sudo Then set up LXC and the rest with the following, which is a complex jumble of settings and workarounds: ```bash -# the version of lxc-start in Debian 7.4 needs to run as root, so make sure +# the version of lxc-start in Debian needs to run as root, so make sure # that the build script can execute it without providing a password echo "%sudo ALL=NOPASSWD: /usr/bin/lxc-start" > /etc/sudoers.d/gitian-lxc -# add cgroup for LXC -echo "cgroup /sys/fs/cgroup cgroup defaults 0 0" >> /etc/fstab # make /etc/rc.local script that sets up bridge between guest and host echo '#!/bin/sh -e' > /etc/rc.local echo 'brctl addbr br0' >> /etc/rc.local echo 'ifconfig br0 10.0.3.2/24 up' >> /etc/rc.local +echo 'iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE' >> /etc/rc.local +echo 'echo 1 > /proc/sys/net/ipv4/ip_forward' >> /etc/rc.local echo 'exit 0' >> /etc/rc.local # make sure that USE_LXC is always set when logging in as debian, # and configure LXC IP addresses @@ -305,6 +305,7 @@ Clone the git repositories for bitcoin and Gitian. ```bash git clone https://github.com/devrandom/gitian-builder.git git clone https://github.com/bitcoin/bitcoin +git clone https://github.com/bitcoin/gitian.sigs.git ``` Setting up the Gitian image diff --git a/doc/release-notes.md b/doc/release-notes.md index 7db27f9fa..801b684e6 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -4,208 +4,11 @@ release-notes at release time) Notable changes =============== -SSL support for RPC dropped ----------------------------- +Example item +---------------- -SSL support for RPC, previously enabled by the option `rpcssl` has been dropped -from both the client and the server. This was done in preparation for removing -the dependency on OpenSSL for the daemon completely. -Trying to use `rpcssl` will result in an error: - - Error: SSL mode for RPC (-rpcssl) is no longer supported. - -If you are one of the few people that relies on this feature, a flexible -migration path is to use `stunnel`. This is an utility that can tunnel -arbitrary TCP connections inside SSL. On e.g. Ubuntu it can be installed with: - - sudo apt-get install stunnel4 - -Then, to tunnel a SSL connection on 28332 to a RPC server bound on localhost on port 18332 do: - - stunnel -d 28332 -r 127.0.0.1:18332 -p stunnel.pem -P '' - -It can also be set up system-wide in inetd style. - -Another way to re-attain SSL would be to setup a httpd reverse proxy. This solution -would allow the use of different authentication, loadbalancing, on-the-fly compression and -caching. A sample config for apache2 could look like: - - Listen 443 - - NameVirtualHost *:443 - - - SSLEngine On - SSLCertificateFile /etc/apache2/ssl/server.crt - SSLCertificateKeyFile /etc/apache2/ssl/server.key - - - ProxyPass http://127.0.0.1:8332/ - ProxyPassReverse http://127.0.0.1:8332/ - # optional enable digest auth - # AuthType Digest - # ... - - # optional bypass bitcoind rpc basic auth - # RequestHeader set Authorization "Basic " - # get the from the shell with: base64 <<< bitcoinrpc: - - - # Or, balance the load: - # ProxyPass / balancer://balancer_cluster_name - - - -Random-cookie RPC authentication ---------------------------------- - -When no `-rpcpassword` is specified, the daemon now uses a special 'cookie' -file for authentication. This file is generated with random content when the -daemon starts, and deleted when it exits. Its contents are used as -authentication token. Read access to this file controls who can access through -RPC. By default it is stored in the data directory but its location can be -overridden with the option `-rpccookiefile`. - -This is similar to Tor's CookieAuthentication: see -https://www.torproject.org/docs/tor-manual.html.en - -This allows running bitcoind without having to do any manual configuration. - -Low-level RPC API changes --------------------------- - -- Monetary amounts can be provided as strings. This means that for example the - argument to sendtoaddress can be "0.0001" instead of 0.0001. This can be an - advantage if a JSON library insists on using a lossy floating point type for - numbers, which would be dangerous for monetary amounts. - -Option parsing behavior ------------------------ - -Command line options are now parsed strictly in the order in which they are -specified. It used to be the case that `-X -noX` ends up, unintuitively, with X -set, as `-X` had precedence over `-noX`. This is no longer the case. Like for -other software, the last specified value for an option will hold. - -`NODE_BLOOM` service bit ------------------------- - -Support for the `NODE_BLOOM` service bit, as described in [BIP -111](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki), has been -added to the P2P protocol code. - -BIP 111 defines a service bit to allow peers to advertise that they support -bloom filters (such as used by SPV clients) explicitly. It also bumps the protocol -version to allow peers to identify old nodes which allow bloom filtering of the -connection despite lacking the new service bit. - -In this version, it is only enforced for peers that send protocol versions -`>=70011`. For the next major version it is planned that this restriction will be -removed. It is recommended to update SPV clients to check for the `NODE_BLOOM` -service bit for nodes that report versions newer than 70011. - -Any sequence of pushdatas in OP_RETURN outputs now allowed ----------------------------------------------------------- - -Previously OP_RETURN outputs with a payload were only relayed and mined if they -had a single pushdata. This restriction has been lifted to allow any -combination of data pushes and numeric constant opcodes (OP_1 to OP_16). The -limit on OP_RETURN output size is now applied to the entire serialized -scriptPubKey, 83 bytes by default. (the previous 80 byte default plus three -bytes overhead) - -Merkle branches removed from wallet ------------------------------------ - -Previously, every wallet transaction stored a Merkle branch to prove its -presence in blocks. This wasn't being used for more than an expensive -sanity check. Since 0.12, these are no longer stored. When loading a -0.12 wallet into an older version, it will automatically rescan to avoid -failed checks. - -BIP65 - CHECKLOCKTIMEVERIFY ---------------------------- - -Previously it was impossible to create a transaction output that was guaranteed -to be unspendable until a specific date in the future. CHECKLOCKTIMEVERIFY is a -new opcode that allows a script to check if a specific block height or time has -been reached, failing the script otherwise. This enables a wide variety of new -functionality such as time-locked escrows, secure payment channels, etc. - -BIP65 implements CHECKLOCKTIMEVERIFY by introducing block version 4, which adds -additional restrictions to the NOP2 opcode. The same miner-voting mechanism as -in BIP34 and BIP66 is used: when 751 out of a sequence of 1001 blocks have -version number 4 or higher, the new consensus rule becomes active for those -blocks. When 951 out of a sequence of 1001 blocks have version number 4 or -higher, it becomes mandatory for all blocks and blocks with versions less than -4 are rejected. - -Bitcoin Core's block templates are now for version 4 blocks only, and any -mining software relying on its `getblocktemplate` must be updated in parallel -to use either libblkmaker version 0.4.3 or any version from 0.5.2 onward. If -you are solo mining, this will affect you the moment you upgrade Bitcoin Core, -which must be done prior to BIP65 achieving its 951/1001 status. If you are -mining with the stratum mining protocol: this does not affect you. If you are -mining with the getblocktemplate protocol to a pool: this will affect you at -the pool operator's discretion, which must be no later than BIP65 achieving its -951/1001 status. - -Automatically listen on Tor ----------------------------- - -Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket -API, to create and destroy 'ephemeral' hidden services programmatically. -Bitcoin Core has been updated to make use of this. - -This means that if Tor is running (and proper authorization is available), -Bitcoin Core automatically creates a hidden service to listen on, without -manual configuration. This will positively affect the number of available -.onion nodes. - -This new feature is enabled by default if Bitcoin Core is listening, and -a connection to Tor can be made. It can be configured with the `-listenonion`, -`-torcontrol` and `-torpassword` settings. To show verbose debugging -information, pass `-debug=tor`. - -Reduce upload traffic ---------------------- - -A major part of the outbound traffic is caused by serving historic blocks to -other nodes in initial block download state. - -It is now possible to reduce the total upload traffic via the `-maxuploadtarget` -parameter. This is *not* a hard limit but a threshold to minimize the outbound -traffic. When the limit is about to be reached, the uploaded data is cut by not -serving historic blocks (blocks older than one week). -Moreover, any SPV peer is disconnected when they request a filtered block. - -This option can be specified in MiB per day and is turned off by default -(`-maxuploadtarget=0`). -The recommended minimum is 144 * MAX_BLOCK_SIZE (currently 144MB) per day. - -Whitelisted peers will never be disconnected, although their traffic counts for -calculating the target. - -A more detailed documentation about keeping traffic low can be found in -[/doc/reducetraffic.md](/doc/reducetraffic.md). - -Signature validation using libsecp256k1 ---------------------------------------- - -ECDSA signatures inside Bitcoin transactions now use validation using -[https://github.com/bitcoin/secp256k1](libsecp256k1) instead of OpenSSL. - -Depending on the platform, this means a significant speedup for raw signature -validation speed. The advantage is largest on x86_64, where validation is over -five times faster. In practice, this translates to a raw reindexing and new -block validation times that are less than half of what it was before. - -Libsecp256k1 has undergone very extensive testing and validation. - -A side effect of this change is that libconsensus no longer depends on OpenSSL. - -0.12.0 Change log +0.13.0 Change log ================= Detailed release notes follow. This overview includes changes that affect @@ -215,33 +18,20 @@ git merge commit are mentioned. ### RPC and REST -Asm representations of scriptSig signatures now contain SIGHASH type decodes ----------------------------------------------------------------------------- +Asm script outputs now contain OP_CHECKLOCKTIMEVERIFY in place of OP_NOP2 +------------------------------------------------------------------------- -The `asm` property of each scriptSig now contains the decoded signature hash -type for each signature that provides a valid defined hash type. +OP_NOP2 has been renamed to OP_CHECKLOCKTIMEVERIFY by [BIP +65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki) -The following items contain assembly representations of scriptSig signatures -and are affected by this change: - -- RPC `getrawtransaction` +The following outputs are affected by this change: +- RPC `getrawtransaction` (in verbose mode) - RPC `decoderawtransaction` +- RPC `decodescript` - REST `/rest/tx/` (JSON format) - REST `/rest/block/` (JSON format when including extended tx details) - `bitcoin-tx -json` -For example, the `scriptSig.asm` property of a transaction input that -previously showed an assembly representation of: - - 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001 - -now shows as: - - 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090[ALL] - -Note that the output of the RPC `decodescript` did not change because it is -configured specifically to process scriptPubKey and not scriptSig scripts. - ### Configuration and command-line options ### Block and transaction handling @@ -260,13 +50,3 @@ configured specifically to process scriptPubKey and not scriptSig scripts. ### Miscellaneous -- Removed bitrpc.py from contrib - -Addition of ZMQ-based Notifications -================================== - -Bitcoind can now (optionally) asynchronously notify clients through a -ZMQ-based PUB socket of the arrival of new transactions and blocks. -This feature requires installation of the ZMQ C API library 4.x and -configuring its use through the command line or configuration file. -Please see docs/zmq.md for details of operation. diff --git a/doc/release-notes/release-notes-0.6.3.md b/doc/release-notes/release-notes-0.6.3.md index 28bb20e10..c27f607b5 100644 --- a/doc/release-notes/release-notes-0.6.3.md +++ b/doc/release-notes/release-notes-0.6.3.md @@ -23,7 +23,7 @@ hundreds of blocks long. Bitcoin-Qt no longer automatically selects the first address in the address book (Issue #1384). -Fixed minimize-to-dock behavior of Bitcon-Qt on the Mac. +Fixed minimize-to-dock behavior of Bitcoin-Qt on the Mac. Added a block checkpoint at block 185,333 to speed up initial blockchain download. diff --git a/doc/release-process.md b/doc/release-process.md index 9a2362cb8..39e3032a6 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -41,6 +41,7 @@ Check out the source code in the following directory hierarchy. pushd ./bitcoin export SIGNER=(your Gitian key, ie bluematt, sipa, etc) export VERSION=(new version, e.g. 0.8.0) + git fetch git checkout v${VERSION} popd @@ -83,25 +84,16 @@ NOTE: Offline builds must use the --url flag to ensure Gitian fetches only from ``` The gbuild invocations below DO NOT DO THIS by default. -###Build (and optionally verify) Bitcoin Core for Linux, Windows, and OS X: +###Build and Sign Bitcoin Core for Linux, Windows, and OS X: ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-linux ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml - mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-win.yml - mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz - mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../ ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml ./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml - ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml - mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz - mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../ - popd Build output expected: @@ -111,6 +103,27 @@ The gbuild invocations below DO NOT DO THIS by default. 4. OS X unsigned installer and dist tarball (bitcoin-${VERSION}-osx-unsigned.dmg, bitcoin-${VERSION}-osx64.tar.gz) 5. Gitian signatures (in gitian.sigs/${VERSION}-/(your Gitian key)/ +###Verify other gitian builders signatures to your own. (Optional) + + Add other gitian builders keys to your gpg keyring + + gpg --import ../bitcoin/contrib/gitian-downloader/*.pgp + + Verify the signatures + + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-linux ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-win.yml + ./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml + +###Move the outputs to the correct directory + + mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../ + mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz + mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../ + mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz + mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../ + popd + ###Next steps: Commit your signature to gitian.sigs: diff --git a/doc/translation_process.md b/doc/translation_process.md index 6389c5ace..310d560b3 100644 --- a/doc/translation_process.md +++ b/doc/translation_process.md @@ -74,10 +74,10 @@ The Transifex Bitcoin project config file is included as part of the repo. It ca To assist in updating translations, we have created a script to help. 1. `python contrib/devtools/update-translations.py` -2. Update `src/qt/bitcoin.qrc` manually or via +2. Update `src/qt/bitcoin_locale.qrc` manually or via `ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/locale\/\1.qm<\/file>/'` -3. Update `src/qt/Makefile.am` manually or via - `ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/ locale\/\1.ts \\/'` +3. Update `src/Makefile.qt.include` manually or via + `ls src/qt/locale/*ts|xargs -n1 basename|sed 's/\(bitcoin_\(.*\)\).ts/ qt\/locale\/\1.ts \\/'` 4. `git add` new translations from `src/qt/locale/` **Do not directly download translations** one by one from the Transifex website, as we do a few post-processing steps before committing the translations. diff --git a/doc/unit-tests.md b/doc/unit-tests.md index 72613054b..afaece829 100644 --- a/doc/unit-tests.md +++ b/doc/unit-tests.md @@ -1,18 +1,18 @@ Compiling/running unit tests ------------------------------------ -Unit tests will be automatically compiled if dependencies were met in configure +Unit tests will be automatically compiled if dependencies were met in `./configure` and tests weren't explicitly disabled. -After configuring, they can be run with 'make check'. +After configuring, they can be run with `make check`. -To run the bitcoind tests manually, launch src/test/test_bitcoin . +To run the bitcoind tests manually, launch `src/test/test_bitcoin`. To add more bitcoind tests, add `BOOST_AUTO_TEST_CASE` functions to the existing -.cpp files in the test/ directory or add new .cpp files that +.cpp files in the `test/` directory or add new .cpp files that implement new BOOST_AUTO_TEST_SUITE sections. -To run the bitcoin-qt tests manually, launch src/qt/test/test_bitcoin-qt +To run the bitcoin-qt tests manually, launch `src/qt/test/test_bitcoin-qt` To add more bitcoin-qt tests, add them to the `src/qt/test/` directory and the `src/qt/test/test_main.cpp` file. diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 7a30db68d..e7173fda0 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -22,6 +22,7 @@ For a description of arguments recognized by test scripts, see """ import os +import time import shutil import sys import subprocess @@ -47,6 +48,10 @@ opts = set() passOn = "" p = re.compile("^--") +bold = ("","") +if (os.name == 'posix'): + bold = ('\033[0m', '\033[1m') + for arg in sys.argv[1:]: if arg == '--coverage': ENABLE_COVERAGE = 1 @@ -57,8 +62,10 @@ for arg in sys.argv[1:]: #Set env vars buildDir = BUILDDIR -os.environ["BITCOIND"] = buildDir + '/src/bitcoind' + EXEEXT -os.environ["BITCOINCLI"] = buildDir + '/src/bitcoin-cli' + EXEEXT +if "BITCOIND" not in os.environ: + os.environ["BITCOIND"] = buildDir + '/src/bitcoind' + EXEEXT +if "BITCOINCLI" not in os.environ: + os.environ["BITCOINCLI"] = buildDir + '/src/bitcoin-cli' + EXEEXT #Disable Windows tests by default if EXEEXT == ".exe" and "-win" not in opts: @@ -77,8 +84,10 @@ testScripts = [ 'rawtransactions.py', 'rest.py', 'mempool_spendcoinbase.py', - 'mempool_coinbase_spends.py', + 'mempool_reorg.py', + 'mempool_limit.py', 'httpbasics.py', + 'multi_rpc.py', 'zapwallettxes.py', 'proxy_test.py', 'merkle_blocks.py', @@ -91,6 +100,12 @@ testScripts = [ 'p2p-fullblocktest.py', 'blockchain.py', 'disablewallet.py', + 'sendheaders.py', + 'keypool.py', + 'prioritise_transaction.py', + 'invalidblockrequest.py', + 'invalidtxrequest.py', + 'abandonconflict.py', ] testScriptsExt = [ 'bip65-cltv.py', @@ -104,14 +119,13 @@ testScriptsExt = [ 'pruning.py', 'forknotify.py', 'invalidateblock.py', - 'keypool.py', # 'rpcbind_test.py', #temporary, bug in libevent, see #6655 'smartfees.py', 'maxblocksinflight.py', - 'invalidblockrequest.py', 'p2p-acceptblock.py', 'mempool_packages.py', 'maxuploadtarget.py', + 'replace-by-fee.py', ] #Enable ZMQ tests @@ -124,7 +138,7 @@ def runtests(): if ENABLE_COVERAGE: coverage = RPCCoverage() - print("Initializing coverage directory at %s" % coverage.dir) + print("Initializing coverage directory at %s\n" % coverage.dir) if(ENABLE_WALLET == 1 and ENABLE_UTILS == 1 and ENABLE_BITCOIND == 1): rpcTestDir = buildDir + '/qa/rpc-tests/' @@ -139,10 +153,12 @@ def runtests(): or run_extended or testScripts[i] in opts or re.sub(".py$", "", testScripts[i]) in opts ): - print("Running testscript " + testScripts[i] + "...") + print("Running testscript %s%s%s ..." % (bold[1], testScripts[i], bold[0])) + time0 = time.time() subprocess.check_call( rpcTestDir + testScripts[i] + flags, shell=True) + print("Duration: %s s\n" % (int(time.time() - time0))) # exit if help is called so we print just one set of # instructions @@ -154,12 +170,14 @@ def runtests(): for i in range(len(testScriptsExt)): if (run_extended or testScriptsExt[i] in opts or re.sub(".py$", "", testScriptsExt[i]) in opts): + print( "Running 2nd level testscript " - + testScriptsExt[i] + "...") - + + "%s%s%s ..." % (bold[1], testScriptsExt[i], bold[0])) + time0 = time.time() subprocess.check_call( rpcTestDir + testScriptsExt[i] + flags, shell=True) + print("Duration: %s s\n" % (int(time.time() - time0))) if coverage: coverage.report_rpc_coverage() diff --git a/qa/rpc-tests/README.md b/qa/rpc-tests/README.md index 898931936..651b01f18 100644 --- a/qa/rpc-tests/README.md +++ b/qa/rpc-tests/README.md @@ -47,10 +47,7 @@ implements the test logic. * ```NodeConn``` is the class used to connect to a bitcoind. If you implement a callback class that derives from ```NodeConnCB``` and pass that to the ```NodeConn``` object, your code will receive the appropriate callbacks when -events of interest arrive. NOTE: be sure to call -```self.create_callback_map()``` in your derived classes' ```__init__``` -function, so that the correct mappings are set up between p2p messages and your -callback functions. +events of interest arrive. * You can pass the same handler to multiple ```NodeConn```'s if you like, or pass different ones to each -- whatever makes the most sense for your test. diff --git a/qa/rpc-tests/abandonconflict.py b/qa/rpc-tests/abandonconflict.py new file mode 100755 index 000000000..38028df07 --- /dev/null +++ b/qa/rpc-tests/abandonconflict.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +try: + import urllib.parse as urlparse +except ImportError: + import urlparse + +class AbandonConflictTest(BitcoinTestFramework): + + def setup_network(self): + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.00001"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug","-logtimemicros"])) + connect_nodes(self.nodes[0], 1) + + def run_test(self): + self.nodes[1].generate(100) + sync_blocks(self.nodes) + balance = self.nodes[0].getbalance() + txA = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10")) + txB = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10")) + txC = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10")) + sync_mempools(self.nodes) + self.nodes[1].generate(1) + + sync_blocks(self.nodes) + newbalance = self.nodes[0].getbalance() + assert(balance - newbalance < Decimal("0.001")) #no more than fees lost + balance = newbalance + + url = urlparse.urlparse(self.nodes[1].url) + self.nodes[0].disconnectnode(url.hostname+":"+str(p2p_port(1))) + + # Identify the 10btc outputs + nA = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txA, 1)["vout"]) if vout["value"] == Decimal("10")) + nB = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txB, 1)["vout"]) if vout["value"] == Decimal("10")) + nC = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txC, 1)["vout"]) if vout["value"] == Decimal("10")) + + inputs =[] + # spend 10btc outputs from txA and txB + inputs.append({"txid":txA, "vout":nA}) + inputs.append({"txid":txB, "vout":nB}) + outputs = {} + + outputs[self.nodes[0].getnewaddress()] = Decimal("14.99998") + outputs[self.nodes[1].getnewaddress()] = Decimal("5") + signed = self.nodes[0].signrawtransaction(self.nodes[0].createrawtransaction(inputs, outputs)) + txAB1 = self.nodes[0].sendrawtransaction(signed["hex"]) + + # Identify the 14.99998btc output + nAB = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txAB1, 1)["vout"]) if vout["value"] == Decimal("14.99998")) + + #Create a child tx spending AB1 and C + inputs = [] + inputs.append({"txid":txAB1, "vout":nAB}) + inputs.append({"txid":txC, "vout":nC}) + outputs = {} + outputs[self.nodes[0].getnewaddress()] = Decimal("24.9996") + signed2 = self.nodes[0].signrawtransaction(self.nodes[0].createrawtransaction(inputs, outputs)) + txABC2 = self.nodes[0].sendrawtransaction(signed2["hex"]) + + # In mempool txs from self should increase balance from change + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance - Decimal("30") + Decimal("24.9996")) + balance = newbalance + + # Restart the node with a higher min relay fee so the parent tx is no longer in mempool + # TODO: redo with eviction + # Note had to make sure tx did not have AllowFree priority + stop_node(self.nodes[0],0) + self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.0001"]) + + # Verify txs no longer in mempool + assert(len(self.nodes[0].getrawmempool()) == 0) + + # Not in mempool txs from self should only reduce balance + # inputs are still spent, but change not received + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance - Decimal("24.9996")) + balance = newbalance + + # Abandon original transaction and verify inputs are available again + # including that the child tx was also abandoned + self.nodes[0].abandontransaction(txAB1) + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance + Decimal("30")) + balance = newbalance + + # Verify that even with a low min relay fee, the tx is not reaccepted from wallet on startup once abandoned + stop_node(self.nodes[0],0) + self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.00001"]) + assert(len(self.nodes[0].getrawmempool()) == 0) + assert(self.nodes[0].getbalance() == balance) + + # But if its received again then it is unabandoned + # And since now in mempool, the change is available + # But its child tx remains abandoned + self.nodes[0].sendrawtransaction(signed["hex"]) + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance - Decimal("20") + Decimal("14.99998")) + balance = newbalance + + # Send child tx again so its unabandoned + self.nodes[0].sendrawtransaction(signed2["hex"]) + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance - Decimal("10") - Decimal("14.99998") + Decimal("24.9996")) + balance = newbalance + + # Remove using high relay fee again + stop_node(self.nodes[0],0) + self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.0001"]) + assert(len(self.nodes[0].getrawmempool()) == 0) + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance - Decimal("24.9996")) + balance = newbalance + + # Create a double spend of AB1 by spending again from only A's 10 output + # Mine double spend from node 1 + inputs =[] + inputs.append({"txid":txA, "vout":nA}) + outputs = {} + outputs[self.nodes[1].getnewaddress()] = Decimal("9.9999") + tx = self.nodes[0].createrawtransaction(inputs, outputs) + signed = self.nodes[0].signrawtransaction(tx) + self.nodes[1].sendrawtransaction(signed["hex"]) + self.nodes[1].generate(1) + + connect_nodes(self.nodes[0], 1) + sync_blocks(self.nodes) + + # Verify that B and C's 10 BTC outputs are available for spending again because AB1 is now conflicted + newbalance = self.nodes[0].getbalance() + assert(newbalance == balance + Decimal("20")) + balance = newbalance + + # There is currently a minor bug around this and so this test doesn't work. See Issue #7315 + # Invalidate the block with the double spend and B's 10 BTC output should no longer be available + # Don't think C's should either + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + newbalance = self.nodes[0].getbalance() + #assert(newbalance == balance - Decimal("10")) + print "If balance has not declined after invalidateblock then out of mempool wallet tx which is no longer" + print "conflicted has not resumed causing its inputs to be seen as spent. See Issue #7315" + print balance , " -> " , newbalance , " ?" + +if __name__ == '__main__': + AbandonConflictTest().main() diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py index 9ca5c69f1..bbd518cf5 100755 --- a/qa/rpc-tests/bip65-cltv-p2p.py +++ b/qa/rpc-tests/bip65-cltv-p2p.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # @@ -9,8 +9,8 @@ from test_framework.util import * from test_framework.mininode import CTransaction, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager -from test_framework.script import CScript, OP_1NEGATE, OP_NOP2, OP_DROP -from binascii import hexlify, unhexlify +from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP +from binascii import unhexlify import cStringIO import time @@ -19,7 +19,7 @@ def cltv_invalidate(tx): Prepends -1 CLTV DROP in the scriptSig itself. ''' - tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_NOP2, OP_DROP] + + tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP] + list(CScript(tx.vin[0].scriptSig))) ''' diff --git a/qa/rpc-tests/bip65-cltv.py b/qa/rpc-tests/bip65-cltv.py index e90e11e6a..f666a07c9 100755 --- a/qa/rpc-tests/bip65-cltv.py +++ b/qa/rpc-tests/bip65-cltv.py @@ -9,8 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil class BIP65Test(BitcoinTestFramework): @@ -46,7 +44,7 @@ class BIP65Test(BitcoinTestFramework): self.nodes[2].generate(1) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 851): - raise AssertionFailure("Failed to mine a version=4 blocks") + raise AssertionError("Failed to mine a version=4 blocks") # TODO: check that new CHECKLOCKTIMEVERIFY rules are enforced diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py index ec1678cc2..544e4a967 100755 --- a/qa/rpc-tests/bipdersig-p2p.py +++ b/qa/rpc-tests/bipdersig-p2p.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # @@ -10,7 +10,7 @@ from test_framework.mininode import CTransaction, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import CScript -from binascii import hexlify, unhexlify +from binascii import unhexlify import cStringIO import time diff --git a/qa/rpc-tests/bipdersig.py b/qa/rpc-tests/bipdersig.py index 243f816f6..be9121c45 100755 --- a/qa/rpc-tests/bipdersig.py +++ b/qa/rpc-tests/bipdersig.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,8 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil class BIP66Test(BitcoinTestFramework): @@ -46,7 +44,7 @@ class BIP66Test(BitcoinTestFramework): self.nodes[2].generate(1) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 851): - raise AssertionFailure("Failed to mine a version=3 blocks") + raise AssertionError("Failed to mine a version=3 blocks") # TODO: check that new DERSIG rules are enforced diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py index b7bfe3628..7045ae435 100755 --- a/qa/rpc-tests/blockchain.py +++ b/qa/rpc-tests/blockchain.py @@ -1,22 +1,28 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # -# Test RPC calls related to blockchain state. +# Test RPC calls related to blockchain state. Tests correspond to code in +# rpc/blockchain.cpp. # -import decimal +from decimal import Decimal from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException from test_framework.util import ( initialize_chain, assert_equal, + assert_raises, + assert_is_hex_string, + assert_is_hash_string, start_nodes, connect_nodes_bi, ) + class BlockchainTest(BitcoinTestFramework): """ Test blockchain-related RPC calls: @@ -36,10 +42,14 @@ class BlockchainTest(BitcoinTestFramework): self.sync_all() def run_test(self): + self._test_gettxoutsetinfo() + self._test_getblockheader() + + def _test_gettxoutsetinfo(self): node = self.nodes[0] res = node.gettxoutsetinfo() - assert_equal(res[u'total_amount'], decimal.Decimal('8725.00000000')) + assert_equal(res[u'total_amount'], Decimal('8725.00000000')) assert_equal(res[u'transactions'], 200) assert_equal(res[u'height'], 200) assert_equal(res[u'txouts'], 200) @@ -47,6 +57,30 @@ class BlockchainTest(BitcoinTestFramework): assert_equal(len(res[u'bestblock']), 64) assert_equal(len(res[u'hash_serialized']), 64) + def _test_getblockheader(self): + node = self.nodes[0] + + assert_raises( + JSONRPCException, lambda: node.getblockheader('nonsense')) + + besthash = node.getbestblockhash() + secondbesthash = node.getblockhash(199) + header = node.getblockheader(besthash) + + assert_equal(header['hash'], besthash) + assert_equal(header['height'], 200) + assert_equal(header['confirmations'], 1) + assert_equal(header['previousblockhash'], secondbesthash) + assert_is_hex_string(header['chainwork']) + assert_is_hash_string(header['hash']) + assert_is_hash_string(header['previousblockhash']) + assert_is_hash_string(header['merkleroot']) + assert_is_hash_string(header['bits'], length=None) + assert isinstance(header['time'], int) + assert isinstance(header['mediantime'], int) + assert isinstance(header['nonce'], int) + assert isinstance(header['version'], int) + assert isinstance(header['difficulty'], Decimal) if __name__ == '__main__': BlockchainTest().main() diff --git a/qa/rpc-tests/decodescript.py b/qa/rpc-tests/decodescript.py index 4bca62338..490808d49 100755 --- a/qa/rpc-tests/decodescript.py +++ b/qa/rpc-tests/decodescript.py @@ -102,13 +102,13 @@ class DecodeScriptTest(BitcoinTestFramework): # OP_IF # OP_CHECKSIGVERIFY # OP_ELSE - # OP_NOP2 OP_DROP + # OP_CHECKLOCKTIMEVERIFY OP_DROP # OP_ENDIF # OP_CHECKSIG # # lock until block 500,000 rpc_result = self.nodes[0].decodescript('63' + push_public_key + 'ad670320a107b17568' + push_public_key + 'ac') - assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_NOP2 OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm']) + assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm']) def decoderawtransaction_asm_sighashtype(self): """Tests decoding scripts via RPC command "decoderawtransaction". diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py index 4cb01575e..6964348d5 100755 --- a/qa/rpc-tests/disablewallet.py +++ b/qa/rpc-tests/disablewallet.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,6 +10,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * + class DisableWalletTest (BitcoinTestFramework): def setup_chain(self): diff --git a/qa/rpc-tests/forknotify.py b/qa/rpc-tests/forknotify.py index 0acef8e30..20e6ce961 100755 --- a/qa/rpc-tests/forknotify.py +++ b/qa/rpc-tests/forknotify.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,8 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil class ForkNotifyTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 93d13faa0..0287965b9 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -1,12 +1,10 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from pprint import pprint -from time import sleep # Create one-input, one-output, no-fee transaction: class RawTransactionsTest(BitcoinTestFramework): @@ -30,6 +28,11 @@ class RawTransactionsTest(BitcoinTestFramework): print "Mining blocks..." min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee'] + # This test is not meant to test fee estimation and we'd like + # to be sure all txs are sent at a consistent desired feerate + for node in self.nodes: + node.settxfee(min_relay_tx_fee) + # if the fee's positive delta is higher than this value tests will fail, # neg. delta always fail the tests. # The size of the signature of every input may be at most 2 bytes larger @@ -48,11 +51,11 @@ class RawTransactionsTest(BitcoinTestFramework): watchonly_amount = 200 self.nodes[3].importpubkey(watchonly_pubkey, "", True) watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount) - self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10); + self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10) - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5); - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0); - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0); + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.5) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 5.0) self.sync_all() self.nodes[0].generate(1) @@ -125,7 +128,7 @@ class RawTransactionsTest(BitcoinTestFramework): for aUtx in listunspent: if aUtx['amount'] == 5.0: utx = aUtx - break; + break assert_equal(utx!=False, True) @@ -154,7 +157,7 @@ class RawTransactionsTest(BitcoinTestFramework): for aUtx in listunspent: if aUtx['amount'] == 5.0: utx = aUtx - break; + break assert_equal(utx!=False, True) @@ -184,7 +187,7 @@ class RawTransactionsTest(BitcoinTestFramework): for aUtx in listunspent: if aUtx['amount'] == 1.0: utx = aUtx - break; + break assert_equal(utx!=False, True) @@ -309,7 +312,7 @@ class RawTransactionsTest(BitcoinTestFramework): except JSONRPCException,e: errorString = e.error['message'] - assert_equal("Insufficient" in errorString, True); + assert("Insufficient" in errorString) @@ -321,11 +324,11 @@ class RawTransactionsTest(BitcoinTestFramework): fundedTx = self.nodes[0].fundrawtransaction(rawTx) #create same transaction over sendtoaddress - txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1); + txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1) signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] #compare fee - feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee); + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance) ############################################################ @@ -336,11 +339,11 @@ class RawTransactionsTest(BitcoinTestFramework): rawTx = self.nodes[0].createrawtransaction(inputs, outputs) fundedTx = self.nodes[0].fundrawtransaction(rawTx) #create same transaction over sendtoaddress - txId = self.nodes[0].sendmany("", outputs); + txId = self.nodes[0].sendmany("", outputs) signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] #compare fee - feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee); + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance) ############################################################ @@ -363,11 +366,11 @@ class RawTransactionsTest(BitcoinTestFramework): fundedTx = self.nodes[0].fundrawtransaction(rawTx) #create same transaction over sendtoaddress - txId = self.nodes[0].sendtoaddress(mSigObj, 1.1); + txId = self.nodes[0].sendtoaddress(mSigObj, 1.1) signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] #compare fee - feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee); + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance) ############################################################ @@ -396,11 +399,11 @@ class RawTransactionsTest(BitcoinTestFramework): fundedTx = self.nodes[0].fundrawtransaction(rawTx) #create same transaction over sendtoaddress - txId = self.nodes[0].sendtoaddress(mSigObj, 1.1); + txId = self.nodes[0].sendtoaddress(mSigObj, 1.1) signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] #compare fee - feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee); + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance) ############################################################ @@ -419,7 +422,7 @@ class RawTransactionsTest(BitcoinTestFramework): # send 1.2 BTC to msig addr - txId = self.nodes[0].sendtoaddress(mSigObj, 1.2); + txId = self.nodes[0].sendtoaddress(mSigObj, 1.2) self.sync_all() self.nodes[1].generate(1) self.sync_all() @@ -447,6 +450,10 @@ class RawTransactionsTest(BitcoinTestFramework): wait_bitcoinds() self.nodes = start_nodes(4, self.options.tmpdir) + # This test is not meant to test fee estimation and we'd like + # to be sure all txs are sent at a consistent desired feerate + for node in self.nodes: + node.settxfee(min_relay_tx_fee) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) @@ -457,7 +464,7 @@ class RawTransactionsTest(BitcoinTestFramework): error = False try: - self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2); + self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2) except: error = True assert(error) @@ -487,13 +494,13 @@ class RawTransactionsTest(BitcoinTestFramework): ############################################### #empty node1, send some small coins from node0 to node1 - self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True); + self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True) self.sync_all() self.nodes[0].generate(1) self.sync_all() for i in range(0,20): - self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01); + self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01) self.sync_all() self.nodes[0].generate(1) self.sync_all() @@ -505,11 +512,11 @@ class RawTransactionsTest(BitcoinTestFramework): fundedTx = self.nodes[1].fundrawtransaction(rawTx) #create same transaction over sendtoaddress - txId = self.nodes[1].sendmany("", outputs); + txId = self.nodes[1].sendmany("", outputs) signedFee = self.nodes[1].getrawmempool(True)[txId]['fee'] #compare fee - feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee); + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) assert(feeDelta >= 0 and feeDelta <= feeTolerance*19) #~19 inputs @@ -518,13 +525,13 @@ class RawTransactionsTest(BitcoinTestFramework): ############################################# #again, empty node1, send some small coins from node0 to node1 - self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True); + self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True) self.sync_all() self.nodes[0].generate(1) self.sync_all() for i in range(0,20): - self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01); + self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01) self.sync_all() self.nodes[0].generate(1) self.sync_all() diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/qa/rpc-tests/getblocktemplate_longpoll.py index 1ddff8a29..3e85957ae 100755 --- a/qa/rpc-tests/getblocktemplate_longpoll.py +++ b/qa/rpc-tests/getblocktemplate_longpoll.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py index aca0cd749..f83b5f140 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/getchaintips.py b/qa/rpc-tests/getchaintips.py index 6a2bcb296..dd260836b 100755 --- a/qa/rpc-tests/getchaintips.py +++ b/qa/rpc-tests/getchaintips.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -23,8 +23,8 @@ class GetChainTipsTest (BitcoinTestFramework): # Split the network and build two chains of different lengths. self.split_network () - self.nodes[0].generate(10); - self.nodes[2].generate(20); + self.nodes[0].generate(10) + self.nodes[2].generate(20) self.sync_all () tips = self.nodes[1].getchaintips () diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index 7888114c5..eb548aee9 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -36,13 +36,13 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! #send 2nd request without closing connection conn.request('POST', '/', '{"method": "getchaintips"}', headers) - out2 = conn.getresponse().read(); + out2 = conn.getresponse().read() assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! conn.close() @@ -53,13 +53,13 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! #send 2nd request without closing connection conn.request('POST', '/', '{"method": "getchaintips"}', headers) - out2 = conn.getresponse().read(); + out2 = conn.getresponse().read() assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! conn.close() @@ -70,7 +70,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) assert_equal(conn.sock!=None, False) #now the connection must be closed after the response @@ -82,7 +82,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) #node2 (third node) is running with standard keep-alive parameters which means keep-alive is on @@ -93,7 +93,7 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) assert_equal(conn.sock!=None, True) #connection must be closed because bitcoind should use keep-alive by default diff --git a/qa/rpc-tests/invalidateblock.py b/qa/rpc-tests/invalidateblock.py index 2b9c8154e..0e78a3c80 100755 --- a/qa/rpc-tests/invalidateblock.py +++ b/qa/rpc-tests/invalidateblock.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/invalidblockrequest.py b/qa/rpc-tests/invalidblockrequest.py index 6a7980cd4..f91a8da01 100755 --- a/qa/rpc-tests/invalidblockrequest.py +++ b/qa/rpc-tests/invalidblockrequest.py @@ -1,15 +1,13 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * -from test_framework.comptool import TestManager, TestInstance -from test_framework.mininode import * +from test_framework.comptool import TestManager, TestInstance, RejectResult from test_framework.blocktools import * -import logging import copy import time @@ -97,7 +95,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework): assert(block2_orig.vtx != block2.vtx) self.tip = block2.sha256 - yield TestInstance([[block2, False], [block2_orig, True]]) + yield TestInstance([[block2, RejectResult(16,'bad-txns-duplicate')], [block2_orig, True]]) height += 1 ''' @@ -112,7 +110,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework): block3.rehash() block3.solve() - yield TestInstance([[block3, False]]) + yield TestInstance([[block3, RejectResult(16,'bad-cb-amount')]]) if __name__ == '__main__': diff --git a/qa/rpc-tests/invalidtxrequest.py b/qa/rpc-tests/invalidtxrequest.py new file mode 100755 index 000000000..c2fe4f1df --- /dev/null +++ b/qa/rpc-tests/invalidtxrequest.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python2 +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# + +from test_framework.test_framework import ComparisonTestFramework +from test_framework.comptool import TestManager, TestInstance, RejectResult +from test_framework.blocktools import * +import time + + +''' +In this test we connect to one node over p2p, and test tx requests. +''' + +# Use the ComparisonTestFramework with 1 node: only use --testbinary. +class InvalidTxRequestTest(ComparisonTestFramework): + + ''' Can either run this test as 1 node with expected answers, or two and compare them. + Change the "outcome" variable from each TestInstance object to only do the comparison. ''' + def __init__(self): + self.num_nodes = 1 + + def run_test(self): + test = TestManager(self, self.options.tmpdir) + test.add_all_connections(self.nodes) + self.tip = None + self.block_time = None + NetworkThread().start() # Start up network handling in another thread + test.run() + + def get_tests(self): + if self.tip is None: + self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) + self.block_time = int(time.time())+1 + + ''' + Create a new block with an anyone-can-spend coinbase + ''' + height = 1 + block = create_block(self.tip, create_coinbase(height), self.block_time) + self.block_time += 1 + block.solve() + # Save the coinbase for later + self.block1 = block + self.tip = block.sha256 + height += 1 + yield TestInstance([[block, True]]) + + ''' + Now we need that block to mature so we can spend the coinbase. + ''' + test = TestInstance(sync_every_block=False) + for i in xrange(100): + block = create_block(self.tip, create_coinbase(height), self.block_time) + block.solve() + self.tip = block.sha256 + self.block_time += 1 + test.blocks_and_transactions.append([block, True]) + height += 1 + yield test + + # chr(100) is OP_NOTIF + # Transaction will be rejected with code 16 (REJECT_INVALID) + tx1 = create_transaction(self.block1.vtx[0], 0, chr(100), 50*100000000 - 12000) + yield TestInstance([[tx1, RejectResult(16, 'mandatory-script-verify-flag-failed')]]) + + # TODO: test further transactions... + +if __name__ == '__main__': + InvalidTxRequestTest().main() diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index 5a6722002..95d0d6832 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -1,20 +1,13 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # Exercise the wallet keypool, and interaction with wallet encryption/locking # Add python-bitcoinrpc to module search path: -import os -import sys - -import json -import shutil -import subprocess -import tempfile -import traceback +from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * @@ -39,107 +32,67 @@ def check_array_result(object_array, to_match, expected): if num_matched == 0: raise AssertionError("No objects matched %s"%(str(to_match))) -def run_test(nodes, tmpdir): - # Encrypt wallet and wait to terminate - nodes[0].encryptwallet('test') - bitcoind_processes[0].wait() - # Restart node 0 - nodes[0] = start_node(0, tmpdir) - # Keep creating keys - addr = nodes[0].getnewaddress() - try: +class KeyPoolTest(BitcoinTestFramework): + + def run_test(self): + nodes = self.nodes + # Encrypt wallet and wait to terminate + nodes[0].encryptwallet('test') + bitcoind_processes[0].wait() + # Restart node 0 + nodes[0] = start_node(0, self.options.tmpdir) + # Keep creating keys addr = nodes[0].getnewaddress() - raise AssertionError('Keypool should be exhausted after one address') - except JSONRPCException,e: - assert(e.error['code']==-12) + try: + addr = nodes[0].getnewaddress() + raise AssertionError('Keypool should be exhausted after one address') + except JSONRPCException,e: + assert(e.error['code']==-12) - # put three new keys in the keypool - nodes[0].walletpassphrase('test', 12000) - nodes[0].keypoolrefill(3) - nodes[0].walletlock() + # put three new keys in the keypool + nodes[0].walletpassphrase('test', 12000) + nodes[0].keypoolrefill(3) + nodes[0].walletlock() - # drain the keys - addr = set() - addr.add(nodes[0].getrawchangeaddress()) - addr.add(nodes[0].getrawchangeaddress()) - addr.add(nodes[0].getrawchangeaddress()) - addr.add(nodes[0].getrawchangeaddress()) - # assert that four unique addresses were returned - assert(len(addr) == 4) - # the next one should fail - try: - addr = nodes[0].getrawchangeaddress() - raise AssertionError('Keypool should be exhausted after three addresses') - except JSONRPCException,e: - assert(e.error['code']==-12) + # drain the keys + addr = set() + addr.add(nodes[0].getrawchangeaddress()) + addr.add(nodes[0].getrawchangeaddress()) + addr.add(nodes[0].getrawchangeaddress()) + addr.add(nodes[0].getrawchangeaddress()) + # assert that four unique addresses were returned + assert(len(addr) == 4) + # the next one should fail + try: + addr = nodes[0].getrawchangeaddress() + raise AssertionError('Keypool should be exhausted after three addresses') + except JSONRPCException,e: + assert(e.error['code']==-12) - # refill keypool with three new addresses - nodes[0].walletpassphrase('test', 12000) - nodes[0].keypoolrefill(3) - nodes[0].walletlock() + # refill keypool with three new addresses + nodes[0].walletpassphrase('test', 1) + nodes[0].keypoolrefill(3) + # test walletpassphrase timeout + time.sleep(1.1) + assert_equal(nodes[0].getwalletinfo()["unlocked_until"], 0) - # drain them by mining - nodes[0].generate(1) - nodes[0].generate(1) - nodes[0].generate(1) - nodes[0].generate(1) - try: + # drain them by mining nodes[0].generate(1) - raise AssertionError('Keypool should be exhausted after three addesses') - except JSONRPCException,e: - assert(e.error['code']==-12) + nodes[0].generate(1) + nodes[0].generate(1) + nodes[0].generate(1) + try: + nodes[0].generate(1) + raise AssertionError('Keypool should be exhausted after three addesses') + except JSONRPCException,e: + assert(e.error['code']==-12) -def main(): - import optparse + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain(self.options.tmpdir) - parser = optparse.OptionParser(usage="%prog [options]") - parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true", - help="Leave bitcoinds and test.* datadir on exit or error") - parser.add_option("--srcdir", dest="srcdir", default="../../src", - help="Source directory containing bitcoind/bitcoin-cli (default: %default%)") - parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"), - help="Root directory for datadirs") - (options, args) = parser.parse_args() - - os.environ['PATH'] = options.srcdir+":"+os.environ['PATH'] - - check_json_precision() - - success = False - nodes = [] - try: - print("Initializing test directory "+options.tmpdir) - if not os.path.isdir(options.tmpdir): - os.makedirs(options.tmpdir) - initialize_chain(options.tmpdir) - - nodes = start_nodes(1, options.tmpdir) - - run_test(nodes, options.tmpdir) - - success = True - - except AssertionError as e: - print("Assertion failed: "+e.message) - except JSONRPCException as e: - print("JSONRPC error: "+e.error['message']) - traceback.print_tb(sys.exc_info()[2]) - except Exception as e: - print("Unexpected exception caught during testing: "+str(sys.exc_info()[0])) - traceback.print_tb(sys.exc_info()[2]) - - if not options.nocleanup: - print("Cleaning up") - stop_nodes(nodes) - wait_bitcoinds() - shutil.rmtree(options.tmpdir) - - if success: - print("Tests successful") - sys.exit(0) - else: - print("Failed") - sys.exit(1) + def setup_network(self): + self.nodes = start_nodes(1, self.options.tmpdir) if __name__ == '__main__': - main() + KeyPoolTest().main() diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index b30a6bc9d..45ede8f04 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,7 +7,15 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * +from test_framework.mininode import CTransaction +import cStringIO +import binascii +def txFromHex(hexstring): + tx = CTransaction() + f = cStringIO.StringIO(binascii.unhexlify(hexstring)) + tx.deserialize(f) + return tx def check_array_result(object_array, to_match, expected): """ @@ -32,6 +40,11 @@ def check_array_result(object_array, to_match, expected): class ListTransactionsTest(BitcoinTestFramework): + def setup_nodes(self): + #This test requires mocktime + enable_mocktime() + return start_nodes(4, self.options.tmpdir) + def run_test(self): # Simple send, 0 to 1: txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) @@ -103,6 +116,107 @@ class ListTransactionsTest(BitcoinTestFramework): {"category":"receive","amount":Decimal("0.1")}, {"txid":txid, "account" : "watchonly"} ) + self.run_rbf_opt_in_test() + + # Check that the opt-in-rbf flag works properly, for sent and received + # transactions. + def run_rbf_opt_in_test(self): + # Check whether a transaction signals opt-in RBF itself + def is_opt_in(node, txid): + rawtx = node.getrawtransaction(txid, 1) + for x in rawtx["vin"]: + if x["sequence"] < 0xfffffffe: + return True + return False + + # Find an unconfirmed output matching a certain txid + def get_unconfirmed_utxo_entry(node, txid_to_match): + utxo = node.listunspent(0, 0) + for i in utxo: + if i["txid"] == txid_to_match: + return i + return None + + # 1. Chain a few transactions that don't opt-in. + txid_1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1) + assert(not is_opt_in(self.nodes[0], txid_1)) + check_array_result(self.nodes[0].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"}) + sync_mempools(self.nodes) + check_array_result(self.nodes[1].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"}) + + # Tx2 will build off txid_1, still not opting in to RBF. + utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_1) + + # Create tx2 using createrawtransaction + inputs = [{"txid":utxo_to_use["txid"], "vout":utxo_to_use["vout"]}] + outputs = {self.nodes[0].getnewaddress(): 0.999} + tx2 = self.nodes[1].createrawtransaction(inputs, outputs) + tx2_signed = self.nodes[1].signrawtransaction(tx2)["hex"] + txid_2 = self.nodes[1].sendrawtransaction(tx2_signed) + + # ...and check the result + assert(not is_opt_in(self.nodes[1], txid_2)) + check_array_result(self.nodes[1].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"}) + sync_mempools(self.nodes) + check_array_result(self.nodes[0].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"}) + + # Tx3 will opt-in to RBF + utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[0], txid_2) + inputs = [{"txid": txid_2, "vout":utxo_to_use["vout"]}] + outputs = {self.nodes[1].getnewaddress(): 0.998} + tx3 = self.nodes[0].createrawtransaction(inputs, outputs) + tx3_modified = txFromHex(tx3) + tx3_modified.vin[0].nSequence = 0 + tx3 = binascii.hexlify(tx3_modified.serialize()).decode('utf-8') + tx3_signed = self.nodes[0].signrawtransaction(tx3)['hex'] + txid_3 = self.nodes[0].sendrawtransaction(tx3_signed) + + assert(is_opt_in(self.nodes[0], txid_3)) + check_array_result(self.nodes[0].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"}) + sync_mempools(self.nodes) + check_array_result(self.nodes[1].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"}) + + # Tx4 will chain off tx3. Doesn't signal itself, but depends on one + # that does. + utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_3) + inputs = [{"txid": txid_3, "vout":utxo_to_use["vout"]}] + outputs = {self.nodes[0].getnewaddress(): 0.997} + tx4 = self.nodes[1].createrawtransaction(inputs, outputs) + tx4_signed = self.nodes[1].signrawtransaction(tx4)["hex"] + txid_4 = self.nodes[1].sendrawtransaction(tx4_signed) + + assert(not is_opt_in(self.nodes[1], txid_4)) + check_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"}) + sync_mempools(self.nodes) + check_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"}) + + # Replace tx3, and check that tx4 becomes unknown + tx3_b = tx3_modified + tx3_b.vout[0].nValue -= 0.004*100000000 # bump the fee + tx3_b = binascii.hexlify(tx3_b.serialize()).decode('utf-8') + tx3_b_signed = self.nodes[0].signrawtransaction(tx3_b)['hex'] + txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True) + assert(is_opt_in(self.nodes[0], txid_3b)) + + check_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"}) + sync_mempools(self.nodes) + check_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"}) + + # Check gettransaction as well: + for n in self.nodes[0:2]: + assert_equal(n.gettransaction(txid_1)["bip125-replaceable"], "no") + assert_equal(n.gettransaction(txid_2)["bip125-replaceable"], "no") + assert_equal(n.gettransaction(txid_3)["bip125-replaceable"], "yes") + assert_equal(n.gettransaction(txid_3b)["bip125-replaceable"], "yes") + assert_equal(n.gettransaction(txid_4)["bip125-replaceable"], "unknown") + + # After mining a transaction, it's no longer BIP125-replaceable + self.nodes[0].generate(1) + assert(txid_3b not in self.nodes[0].getrawmempool()) + assert_equal(self.nodes[0].gettransaction(txid_3b)["bip125-replaceable"], "no") + assert_equal(self.nodes[0].gettransaction(txid_4)["bip125-replaceable"], "unknown") + + if __name__ == '__main__': ListTransactionsTest().main() diff --git a/qa/rpc-tests/maxblocksinflight.py b/qa/rpc-tests/maxblocksinflight.py index a601147ce..0313bce73 100755 --- a/qa/rpc-tests/maxblocksinflight.py +++ b/qa/rpc-tests/maxblocksinflight.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # @@ -34,7 +34,6 @@ class TestManager(NodeConnCB): def __init__(self): NodeConnCB.__init__(self) self.log = logging.getLogger("BlockRelayTest") - self.create_callback_map() def add_new_connection(self, connection): self.connection = connection diff --git a/qa/rpc-tests/maxuploadtarget.py b/qa/rpc-tests/maxuploadtarget.py index e714465db..4d6b343f7 100755 --- a/qa/rpc-tests/maxuploadtarget.py +++ b/qa/rpc-tests/maxuploadtarget.py @@ -25,7 +25,6 @@ if uploadtarget has been reached. class TestNode(NodeConnCB): def __init__(self): NodeConnCB.__init__(self) - self.create_callback_map() self.connection = None self.ping_counter = 1 self.last_pong = msg_pong() @@ -85,22 +84,7 @@ class TestNode(NodeConnCB): class MaxUploadTest(BitcoinTestFramework): def __init__(self): self.utxo = [] - - # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create - # So we have big transactions and full blocks to fill up our block files - # create one script_pubkey - script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes - for i in xrange (512): - script_pubkey = script_pubkey + "01" - # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change - self.txouts = "81" - for k in xrange(128): - # add txout value - self.txouts = self.txouts + "0000000000000000" - # add length of script_pubkey - self.txouts = self.txouts + "fd0402" - # add script_pubkey - self.txouts = self.txouts + script_pubkey + self.txouts = gen_return_txouts() def add_options(self, parser): parser.add_option("--testbinary", dest="testbinary", diff --git a/qa/rpc-tests/mempool_limit.py b/qa/rpc-tests/mempool_limit.py new file mode 100755 index 000000000..7914ceea2 --- /dev/null +++ b/qa/rpc-tests/mempool_limit.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# Test mempool limiting together/eviction with the wallet + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * + +class MempoolLimitTest(BitcoinTestFramework): + + def __init__(self): + self.txouts = gen_return_txouts() + + def setup_network(self): + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, ["-maxmempool=5", "-spendzeroconfchange=0", "-debug"])) + self.is_network_split = False + self.sync_all() + self.relayfee = self.nodes[0].getnetworkinfo()['relayfee'] + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 2) + + def run_test(self): + txids = [] + utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 90) + + #create a mempool tx that will be evicted + us0 = utxos.pop() + inputs = [{ "txid" : us0["txid"], "vout" : us0["vout"]}] + outputs = {self.nodes[0].getnewaddress() : 0.0001} + tx = self.nodes[0].createrawtransaction(inputs, outputs) + self.nodes[0].settxfee(self.relayfee) # specifically fund this tx with low fee + txF = self.nodes[0].fundrawtransaction(tx) + self.nodes[0].settxfee(0) # return to automatic fee selection + txFS = self.nodes[0].signrawtransaction(txF['hex']) + txid = self.nodes[0].sendrawtransaction(txFS['hex']) + self.nodes[0].lockunspent(True, [us0]) + + relayfee = self.nodes[0].getnetworkinfo()['relayfee'] + base_fee = relayfee*100 + for i in xrange (4): + txids.append([]) + txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], (i+1)*base_fee) + + # by now, the tx should be evicted, check confirmation state + assert(txid not in self.nodes[0].getrawmempool()) + txdata = self.nodes[0].gettransaction(txid) + assert(txdata['confirmations'] == 0) #confirmation should still be 0 + +if __name__ == '__main__': + MempoolLimitTest().main() diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index 746c26ff5..47c1028b9 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -8,9 +8,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -def satoshi_round(amount): - return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) - MAX_ANCESTORS = 25 MAX_DESCENDANTS = 25 @@ -67,17 +64,50 @@ class MempoolPackagesTest(BitcoinTestFramework): for x in reversed(chain): assert_equal(mempool[x]['descendantcount'], descendant_count) descendant_fees += mempool[x]['fee'] + assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee']) assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees) descendant_size += mempool[x]['size'] assert_equal(mempool[x]['descendantsize'], descendant_size) descendant_count += 1 + # Check that descendant modified fees includes fee deltas from + # prioritisetransaction + self.nodes[0].prioritisetransaction(chain[-1], 0, 1000) + mempool = self.nodes[0].getrawmempool(True) + + descendant_fees = 0 + for x in reversed(chain): + descendant_fees += mempool[x]['fee'] + assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees+1000) + # Adding one more transaction on to the chain should fail. try: self.chain_transaction(self.nodes[0], txid, vout, value, fee, 1) except JSONRPCException as e: print "too-long-ancestor-chain successfully rejected" + # Check that prioritising a tx before it's added to the mempool works + # First clear the mempool by mining a block. + self.nodes[0].generate(1) + sync_blocks(self.nodes) + assert_equal(len(self.nodes[0].getrawmempool()), 0) + # Prioritise a transaction that has been mined, then add it back to the + # mempool by using invalidateblock. + self.nodes[0].prioritisetransaction(chain[-1], 0, 2000) + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + # Keep node1's tip synced with node0 + self.nodes[1].invalidateblock(self.nodes[1].getbestblockhash()) + + # Now check that the transaction is in the mempool, with the right modified fee + mempool = self.nodes[0].getrawmempool(True) + + descendant_fees = 0 + for x in reversed(chain): + descendant_fees += mempool[x]['fee'] + if (x == chain[-1]): + assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee']+satoshi_round(0.00002)) + assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees+2000) + # TODO: check that node1's mempool is as expected # TODO: test ancestor size limits diff --git a/qa/rpc-tests/mempool_coinbase_spends.py b/qa/rpc-tests/mempool_reorg.py similarity index 68% rename from qa/rpc-tests/mempool_coinbase_spends.py rename to qa/rpc-tests/mempool_reorg.py index c64a15b9f..40684e7fb 100755 --- a/qa/rpc-tests/mempool_coinbase_spends.py +++ b/qa/rpc-tests/mempool_reorg.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,8 +10,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil # Create one-input, one-output, no-fee transaction: class MempoolCoinbaseTest(BitcoinTestFramework): @@ -25,7 +23,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework): self.nodes.append(start_node(1, self.options.tmpdir, args)) connect_nodes(self.nodes[1], 0) self.is_network_split = False - self.sync_all + self.sync_all() def create_tx(self, from_txid, to_address, amount): inputs = [{ "txid" : from_txid, "vout" : 0}] @@ -52,24 +50,34 @@ class MempoolCoinbaseTest(BitcoinTestFramework): # 3. Indirect (coinbase and child both in chain) : spend_103 and spend_103_1 # Use invalidatblock to make all of the above coinbase spends invalid (immature coinbase), # and make sure the mempool code behaves correctly. - b = [ self.nodes[0].getblockhash(n) for n in range(102, 105) ] + b = [ self.nodes[0].getblockhash(n) for n in range(101, 105) ] coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spend_101_raw = self.create_tx(coinbase_txids[0], node1_address, 50) - spend_102_raw = self.create_tx(coinbase_txids[1], node0_address, 50) - spend_103_raw = self.create_tx(coinbase_txids[2], node0_address, 50) + spend_101_raw = self.create_tx(coinbase_txids[1], node1_address, 49.99) + spend_102_raw = self.create_tx(coinbase_txids[2], node0_address, 49.99) + spend_103_raw = self.create_tx(coinbase_txids[3], node0_address, 49.99) + + # Create a block-height-locked transaction which will be invalid after reorg + timelock_tx = self.nodes[0].createrawtransaction([{"txid": coinbase_txids[0], "vout": 0}], {node0_address: 49.99}) + # Set the time lock + timelock_tx = timelock_tx.replace("ffffffff", "11111111", 1) + timelock_tx = timelock_tx[:-8] + hex(self.nodes[0].getblockcount() + 2)[2:] + "000000" + timelock_tx = self.nodes[0].signrawtransaction(timelock_tx)["hex"] + assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) # Broadcast and mine spend_102 and 103: spend_102_id = self.nodes[0].sendrawtransaction(spend_102_raw) spend_103_id = self.nodes[0].sendrawtransaction(spend_103_raw) self.nodes[0].generate(1) + assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) # Create 102_1 and 103_1: - spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 50) - spend_103_1_raw = self.create_tx(spend_103_id, node1_address, 50) + spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 49.98) + spend_103_1_raw = self.create_tx(spend_103_id, node1_address, 49.98) # Broadcast and mine 103_1: spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw) - self.nodes[0].generate(1) + last_block = self.nodes[0].generate(1) + timelock_tx_id = self.nodes[0].sendrawtransaction(timelock_tx) # ... now put spend_101 and spend_102_1 in memory pools: spend_101_id = self.nodes[0].sendrawtransaction(spend_101_raw) @@ -77,7 +85,11 @@ class MempoolCoinbaseTest(BitcoinTestFramework): self.sync_all() - assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_101_id, spend_102_1_id ])) + assert_equal(set(self.nodes[0].getrawmempool()), {spend_101_id, spend_102_1_id, timelock_tx_id}) + + for node in self.nodes: + node.invalidateblock(last_block[0]) + assert_equal(set(self.nodes[0].getrawmempool()), {spend_101_id, spend_102_1_id, spend_103_1_id}) # Use invalidateblock to re-org back and make all those coinbase spends # immature/invalid: diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py index 19c74bb75..9fcc88a2a 100755 --- a/qa/rpc-tests/mempool_resurrect_test.py +++ b/qa/rpc-tests/mempool_resurrect_test.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,8 +10,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil # Create one-input, one-output, no-fee transaction: class MempoolCoinbaseTest(BitcoinTestFramework): @@ -45,13 +43,13 @@ class MempoolCoinbaseTest(BitcoinTestFramework): b = [ self.nodes[0].getblockhash(n) for n in range(1, 4) ] coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spends1_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ] + spends1_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in coinbase_txids ] spends1_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw ] blocks = [] blocks.extend(self.nodes[0].generate(1)) - spends2_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in spends1_id ] + spends2_raw = [ self.create_tx(txid, node0_address, 49.98) for txid in spends1_id ] spends2_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw ] blocks.extend(self.nodes[0].generate(1)) diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index fc17c5069..16f512db3 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,8 +15,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil # Create one-input, one-output, no-fee transaction: class MempoolSpendCoinbaseTest(BitcoinTestFramework): @@ -46,7 +44,7 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework): # is too immature to spend. b = [ self.nodes[0].getblockhash(n) for n in range(101, 103) ] coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spends_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ] + spends_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in coinbase_txids ] spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0]) diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py index 72a80ce6c..eb718f39e 100755 --- a/qa/rpc-tests/merkle_blocks.py +++ b/qa/rpc-tests/merkle_blocks.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,8 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os -import shutil class MerkleBlockTest(BitcoinTestFramework): @@ -44,9 +42,9 @@ class MerkleBlockTest(BitcoinTestFramework): assert_equal(self.nodes[2].getbalance(), 0) node0utxos = self.nodes[0].listunspent(1) - tx1 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 50}) + tx1 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99}) txid1 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx1)["hex"]) - tx2 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 50}) + tx2 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 49.99}) txid2 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx2)["hex"]) assert_raises(JSONRPCException, self.nodes[0].gettxoutproof, [txid1]) @@ -64,7 +62,7 @@ class MerkleBlockTest(BitcoinTestFramework): assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2], blockhash)), txlist) txin_spent = self.nodes[1].listunspent(1).pop() - tx3 = self.nodes[1].createrawtransaction([txin_spent], {self.nodes[0].getnewaddress(): 50}) + tx3 = self.nodes[1].createrawtransaction([txin_spent], {self.nodes[0].getnewaddress(): 49.98}) self.nodes[0].sendrawtransaction(self.nodes[1].signrawtransaction(tx3)["hex"]) self.nodes[0].generate(1) self.sync_all() @@ -72,7 +70,7 @@ class MerkleBlockTest(BitcoinTestFramework): txid_spent = txin_spent["txid"] txid_unspent = txid1 if txin_spent["txid"] != txid1 else txid2 - # We cant find the block from a fully-spent tx + # We can't find the block from a fully-spent tx assert_raises(JSONRPCException, self.nodes[2].gettxoutproof, [txid_spent]) # ...but we can if we specify the block assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_spent], blockhash)), [txid_spent]) diff --git a/qa/rpc-tests/multi_rpc.py b/qa/rpc-tests/multi_rpc.py new file mode 100755 index 000000000..62071d426 --- /dev/null +++ b/qa/rpc-tests/multi_rpc.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python2 +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test mulitple rpc user config option rpcauth +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +import base64 + +try: + import http.client as httplib +except ImportError: + import httplib +try: + import urllib.parse as urlparse +except ImportError: + import urlparse + +class HTTPBasicsTest (BitcoinTestFramework): + def setup_nodes(self): + return start_nodes(4, self.options.tmpdir) + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain(self.options.tmpdir) + #Append rpcauth to bitcoin.conf before initialization + rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144" + rpcauth2 = "rpcauth=rt2:f8607b1a88861fac29dfccf9b52ff9f$ff36a0c23c8c62b4846112e50fa888416e94c17bfd4c42f88fd8f55ec6a3137e" + with open(os.path.join(self.options.tmpdir+"/node0", "bitcoin.conf"), 'a') as f: + f.write(rpcauth+"\n") + f.write(rpcauth2+"\n") + + def run_test(self): + + ################################################## + # Check correctness of the rpcauth config option # + ################################################## + url = urlparse.urlparse(self.nodes[0].url) + + #Old authpair + authpair = url.username + ':' + url.password + + #New authpair generated via contrib/rpcuser tool + rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144" + password = "cA773lm788buwYe4g4WT+05pKyNruVKjQ25x3n0DQcM=" + + #Second authpair with different username + rpcauth2 = "rpcauth=rt2:f8607b1a88861fac29dfccf9b52ff9f$ff36a0c23c8c62b4846112e50fa888416e94c17bfd4c42f88fd8f55ec6a3137e" + password2 = "8/F3uMDw4KSEbw96U3CA1C4X05dkHDN2BPFjTgZW4KI=" + authpairnew = "rt:"+password + + headers = {"Authorization": "Basic " + base64.b64encode(authpair)} + + conn = httplib.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + resp = conn.getresponse() + assert_equal(resp.status==401, False) + conn.close() + + #Use new authpair to confirm both work + headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)} + + conn = httplib.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + resp = conn.getresponse() + assert_equal(resp.status==401, False) + conn.close() + + #Wrong login name with rt's password + authpairnew = "rtwrong:"+password + headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)} + + conn = httplib.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + resp = conn.getresponse() + assert_equal(resp.status==401, True) + conn.close() + + #Wrong password for rt + authpairnew = "rt:"+password+"wrong" + headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)} + + conn = httplib.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + resp = conn.getresponse() + assert_equal(resp.status==401, True) + conn.close() + + #Correct for rt2 + authpairnew = "rt2:"+password2 + headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)} + + conn = httplib.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + resp = conn.getresponse() + assert_equal(resp.status==401, False) + conn.close() + + #Wrong password for rt2 + authpairnew = "rt2:"+password2+"wrong" + headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)} + + conn = httplib.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + resp = conn.getresponse() + assert_equal(resp.status==401, True) + conn.close() + + + +if __name__ == '__main__': + HTTPBasicsTest ().main () diff --git a/qa/rpc-tests/nodehandling.py b/qa/rpc-tests/nodehandling.py index e383a3a12..c6c8c436e 100755 --- a/qa/rpc-tests/nodehandling.py +++ b/qa/rpc-tests/nodehandling.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,7 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import base64 try: import http.client as httplib @@ -54,7 +53,7 @@ class NodeHandlingTest (BitcoinTestFramework): self.nodes[2].setban("127.0.0.0/24", "add") self.nodes[2].setban("192.168.0.1", "add", 1) #ban for 1 seconds self.nodes[2].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) #ban for 1000 seconds - listBeforeShutdown = self.nodes[2].listbanned(); + listBeforeShutdown = self.nodes[2].listbanned() assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) #must be here time.sleep(2) #make 100% sure we expired 192.168.0.1 node time @@ -62,7 +61,7 @@ class NodeHandlingTest (BitcoinTestFramework): stop_node(self.nodes[2], 2) self.nodes[2] = start_node(2, self.options.tmpdir) - listAfterShutdown = self.nodes[2].listbanned(); + listAfterShutdown = self.nodes[2].listbanned() assert_equal("127.0.0.0/24", listAfterShutdown[0]['address']) assert_equal("127.0.0.0/32", listAfterShutdown[1]['address']) assert_equal("/19" in listAfterShutdown[2]['address'], True) diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py index 700deab20..bf355780c 100755 --- a/qa/rpc-tests/p2p-acceptblock.py +++ b/qa/rpc-tests/p2p-acceptblock.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # @@ -62,7 +62,6 @@ The test: class TestNode(NodeConnCB): def __init__(self): NodeConnCB.__init__(self) - self.create_callback_map() self.connection = None self.ping_counter = 1 self.last_pong = msg_pong() diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/qa/rpc-tests/p2p-fullblocktest.py index 9555940ce..b1e8ca53e 100755 --- a/qa/rpc-tests/p2p-fullblocktest.py +++ b/qa/rpc-tests/p2p-fullblocktest.py @@ -1,21 +1,16 @@ #!/usr/bin/env python2 - -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # from test_framework.test_framework import ComparisonTestFramework from test_framework.util import * -from test_framework.comptool import TestManager, TestInstance -from test_framework.mininode import * +from test_framework.comptool import TestManager, TestInstance, RejectResult from test_framework.blocktools import * -import logging -import copy import time -import numbers from test_framework.key import CECKey -from test_framework.script import CScript, CScriptOp, SignatureHash, SIGHASH_ALL, OP_TRUE +from test_framework.script import CScript, SignatureHash, SIGHASH_ALL, OP_TRUE, OP_FALSE class PreviousSpendableOutput(object): def __init__(self, tx = CTransaction(), n = -1): @@ -122,13 +117,29 @@ class FullBlockTest(ComparisonTestFramework): return TestInstance([[self.tip, True]]) # returns a test case that asserts that the current tip was rejected - def rejected(): - return TestInstance([[self.tip, False]]) + def rejected(reject = None): + if reject is None: + return TestInstance([[self.tip, False]]) + else: + return TestInstance([[self.tip, reject]]) # move the tip back to a previous block def tip(number): self.tip = self.blocks[number] + # add transactions to a block produced by next_block + def update_block(block_number, new_transactions): + block = self.blocks[block_number] + old_hash = block.sha256 + self.add_transactions_to_block(block, new_transactions) + block.solve() + # Update the internal state just like in next_block + self.tip = block + self.block_heights[block.sha256] = self.block_heights[old_hash] + del self.block_heights[old_hash] + self.blocks[block_number] = block + return block + # creates a new block and advances the tip to that block block = self.next_block @@ -141,14 +152,15 @@ class FullBlockTest(ComparisonTestFramework): # Now we need that block to mature so we can spend the coinbase. test = TestInstance(sync_every_block=False) - for i in range(100): + for i in range(99): block(1000 + i) test.blocks_and_transactions.append([self.tip, True]) save_spendable_output() yield test - # Start by bulding a couple of blocks on top (which output is spent is in parentheses): + # Start by building a couple of blocks on top (which output is spent is + # in parentheses): # genesis -> b1 (0) -> b2 (1) out0 = get_spendable_output() block(1, spend=out0) @@ -156,8 +168,7 @@ class FullBlockTest(ComparisonTestFramework): yield accepted() out1 = get_spendable_output() - block(2, spend=out1) - # Inv again, then deliver twice (shouldn't break anything). + b2 = block(2, spend=out1) yield accepted() @@ -168,8 +179,8 @@ class FullBlockTest(ComparisonTestFramework): # # Nothing should happen at this point. We saw b2 first so it takes priority. tip(1) - block(3, spend=out1) - # Deliver twice (should still not break anything) + b3 = block(3, spend=out1) + txout_b3 = PreviousSpendableOutput(b3.vtx[1], 1) yield rejected() @@ -214,7 +225,7 @@ class FullBlockTest(ComparisonTestFramework): # \-> b3 (1) -> b4 (2) tip(6) block(9, spend=out4, additional_coinbase_value=1) - yield rejected() + yield rejected(RejectResult(16, 'bad-cb-amount')) # Create a fork that ends in a block with too much fee (the one that causes the reorg) @@ -226,7 +237,7 @@ class FullBlockTest(ComparisonTestFramework): yield rejected() block(11, spend=out4, additional_coinbase_value=1) - yield rejected() + yield rejected(RejectResult(16, 'bad-cb-amount')) # Try again, but with a valid fork first @@ -252,6 +263,10 @@ class FullBlockTest(ComparisonTestFramework): yield TestInstance([[b12, True, b13.sha256]]) # New tip should be b13. + # Add a block with MAX_BLOCK_SIGOPS and one with one more sigop + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) -> b16 (6) + # \-> b3 (1) -> b4 (2) # Test that a block with a lot of checksigs is okay lots_of_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50 - 1)) @@ -264,8 +279,121 @@ class FullBlockTest(ComparisonTestFramework): out6 = get_spendable_output() too_many_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50)) block(16, spend=out6, script=too_many_checksigs) + yield rejected(RejectResult(16, 'bad-blk-sigops')) + + + # Attempt to spend a transaction created on a different fork + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) -> b17 (b3.vtx[1]) + # \-> b3 (1) -> b4 (2) + tip(15) + block(17, spend=txout_b3) + yield rejected(RejectResult(16, 'bad-txns-inputs-missingorspent')) + + # Attempt to spend a transaction created on a different fork (on a fork this time) + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) + # \-> b18 (b3.vtx[1]) -> b19 (6) + # \-> b3 (1) -> b4 (2) + tip(13) + block(18, spend=txout_b3) yield rejected() + block(19, spend=out6) + yield rejected() + + # Attempt to spend a coinbase at depth too low + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) -> b20 (7) + # \-> b3 (1) -> b4 (2) + tip(15) + out7 = get_spendable_output() + block(20, spend=out7) + yield rejected(RejectResult(16, 'bad-txns-premature-spend-of-coinbase')) + + # Attempt to spend a coinbase at depth too low (on a fork this time) + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) + # \-> b21 (6) -> b22 (5) + # \-> b3 (1) -> b4 (2) + tip(13) + block(21, spend=out6) + yield rejected() + + block(22, spend=out5) + yield rejected() + + # Create a block on either side of MAX_BLOCK_SIZE and make sure its accepted/rejected + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6) + # \-> b24 (6) -> b25 (7) + # \-> b3 (1) -> b4 (2) + tip(15) + b23 = block(23, spend=out6) + old_hash = b23.sha256 + tx = CTransaction() + script_length = MAX_BLOCK_SIZE - len(b23.serialize()) - 69 + script_output = CScript([chr(0)*script_length]) + tx.vout.append(CTxOut(0, script_output)) + tx.vin.append(CTxIn(COutPoint(b23.vtx[1].sha256, 1))) + b23 = update_block(23, [tx]) + # Make sure the math above worked out to produce a max-sized block + assert_equal(len(b23.serialize()), MAX_BLOCK_SIZE) + yield accepted() + + # Make the next block one byte bigger and check that it fails + tip(15) + b24 = block(24, spend=out6) + script_length = MAX_BLOCK_SIZE - len(b24.serialize()) - 69 + script_output = CScript([chr(0)*(script_length+1)]) + tx.vout = [CTxOut(0, script_output)] + b24 = update_block(24, [tx]) + assert_equal(len(b24.serialize()), MAX_BLOCK_SIZE+1) + yield rejected(RejectResult(16, 'bad-blk-length')) + + b25 = block(25, spend=out7) + yield rejected() + + # Create blocks with a coinbase input script size out of range + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6) -> b30 (7) + # \-> ... (6) -> ... (7) + # \-> b3 (1) -> b4 (2) + tip(15) + b26 = block(26, spend=out6) + b26.vtx[0].vin[0].scriptSig = chr(0) + b26.vtx[0].rehash() + # update_block causes the merkle root to get updated, even with no new + # transactions, and updates the required state. + b26 = update_block(26, []) + yield rejected(RejectResult(16, 'bad-cb-length')) + + # Extend the b26 chain to make sure bitcoind isn't accepting b26 + b27 = block(27, spend=out7) + yield rejected() + + # Now try a too-large-coinbase script + tip(15) + b28 = block(28, spend=out6) + b28.vtx[0].vin[0].scriptSig = chr(0)*101 + b28.vtx[0].rehash() + b28 = update_block(28, []) + yield rejected(RejectResult(16, 'bad-cb-length')) + + # Extend the b28 chain to make sure bitcoind isn't accepted b28 + b29 = block(29, spend=out7) + # TODO: Should get a reject message back with "bad-prevblk", except + # there's a bug that prevents this from being detected. Just note + # failure for now, and add the reject result later. + yield rejected() + + # b30 has a max-sized coinbase scriptSig. + tip(23) + b30 = block(30) + b30.vtx[0].vin[0].scriptSig = chr(0)*100 + b30.vtx[0].rehash() + b30 = update_block(30, []) + yield accepted() if __name__ == '__main__': diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py new file mode 100755 index 000000000..4a79d38da --- /dev/null +++ b/qa/rpc-tests/prioritise_transaction.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python2 +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test PrioritiseTransaction code +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * + +COIN = 100000000 + +class PrioritiseTransactionTest(BitcoinTestFramework): + + def __init__(self): + self.txouts = gen_return_txouts() + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 1) + + def setup_network(self): + self.nodes = [] + self.is_network_split = False + + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-printpriority=1"])) + self.relayfee = self.nodes[0].getnetworkinfo()['relayfee'] + + def run_test(self): + utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 90) + base_fee = self.relayfee*100 # our transactions are smaller than 100kb + txids = [] + + # Create 3 batches of transactions at 3 different fee rate levels + for i in xrange(3): + txids.append([]) + txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], (i+1)*base_fee) + + # add a fee delta to something in the cheapest bucket and make sure it gets mined + # also check that a different entry in the cheapest bucket is NOT mined (lower + # the priority to ensure its not mined due to priority) + self.nodes[0].prioritisetransaction(txids[0][0], 0, int(3*base_fee*COIN)) + self.nodes[0].prioritisetransaction(txids[0][1], -1e15, 0) + + self.nodes[0].generate(1) + + mempool = self.nodes[0].getrawmempool() + print "Assert that prioritised transasction was mined" + assert(txids[0][0] not in mempool) + assert(txids[0][1] in mempool) + + high_fee_tx = None + for x in txids[2]: + if x not in mempool: + high_fee_tx = x + + # Something high-fee should have been mined! + assert(high_fee_tx != None) + + # Add a prioritisation before a tx is in the mempool (de-prioritising a + # high-fee transaction). + self.nodes[0].prioritisetransaction(high_fee_tx, -1e15, -int(2*base_fee*COIN)) + + # Add everything back to mempool + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + + # Check to make sure our high fee rate tx is back in the mempool + mempool = self.nodes[0].getrawmempool() + assert(high_fee_tx in mempool) + + # Now verify the high feerate transaction isn't mined. + self.nodes[0].generate(5) + + # High fee transaction should not have been mined, but other high fee rate + # transactions should have been. + mempool = self.nodes[0].getrawmempool() + print "Assert that de-prioritised transaction is still in mempool" + assert(high_fee_tx in mempool) + for x in txids[2]: + if (x != high_fee_tx): + assert(x not in mempool) + + # Create a free, low priority transaction. Should be rejected. + utxo_list = self.nodes[0].listunspent() + assert(len(utxo_list) > 0) + utxo = utxo_list[0] + + inputs = [] + outputs = {} + inputs.append({"txid" : utxo["txid"], "vout" : utxo["vout"]}) + outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee + raw_tx = self.nodes[0].createrawtransaction(inputs, outputs) + tx_hex = self.nodes[0].signrawtransaction(raw_tx)["hex"] + txid = self.nodes[0].sendrawtransaction(tx_hex) + + # A tx that spends an in-mempool tx has 0 priority, so we can use it to + # test the effect of using prioritise transaction for mempool acceptance + inputs = [] + inputs.append({"txid": txid, "vout": 0}) + outputs = {} + outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee + raw_tx2 = self.nodes[0].createrawtransaction(inputs, outputs) + tx2_hex = self.nodes[0].signrawtransaction(raw_tx2)["hex"] + tx2_id = self.nodes[0].decoderawtransaction(tx2_hex)["txid"] + + try: + self.nodes[0].sendrawtransaction(tx2_hex) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) # insufficient fee + assert(tx2_id not in self.nodes[0].getrawmempool()) + else: + assert(False) + + # This is a less than 1000-byte transaction, so just set the fee + # to be the minimum for a 1000 byte transaction and check that it is + # accepted. + self.nodes[0].prioritisetransaction(tx2_id, 0, int(self.relayfee*COIN)) + + print "Assert that prioritised free transaction is accepted to mempool" + assert_equal(self.nodes[0].sendrawtransaction(tx2_hex), tx2_id) + assert(tx2_id in self.nodes[0].getrawmempool()) + +if __name__ == '__main__': + PrioritiseTransactionTest().main() diff --git a/qa/rpc-tests/proxy_test.py b/qa/rpc-tests/proxy_test.py index 3623c1616..7f77e664d 100755 --- a/qa/rpc-tests/proxy_test.py +++ b/qa/rpc-tests/proxy_test.py @@ -3,9 +3,6 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. import socket -import traceback, sys -from binascii import hexlify -import time, os from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType from test_framework.test_framework import BitcoinTestFramework @@ -34,7 +31,8 @@ addnode connect to onion addnode connect to generic DNS name ''' -class ProxyTest(BitcoinTestFramework): + +class ProxyTest(BitcoinTestFramework): def __init__(self): # Create two proxies on different ports # ... one unauthenticated diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index 21f8d6938..b0f4b88ae 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -13,7 +13,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os.path def calc_usage(blockdir): return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f))/(1024*1024) @@ -23,24 +22,7 @@ class PruneTest(BitcoinTestFramework): def __init__(self): self.utxo = [] self.address = ["",""] - - # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create - # So we have big transactions and full blocks to fill up our block files - - # create one script_pubkey - script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes - for i in xrange (512): - script_pubkey = script_pubkey + "01" - # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change - self.txouts = "81" - for k in xrange(128): - # add txout value - self.txouts = self.txouts + "0000000000000000" - # add length of script_pubkey - self.txouts = self.txouts + "fd0402" - # add script_pubkey - self.txouts = self.txouts + script_pubkey - + self.txouts = gen_return_txouts() def setup_chain(self): print("Initializing test directory "+self.options.tmpdir) diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index 173faf736..dd9e5e28a 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,8 +10,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from pprint import pprint -from time import sleep # Create one-input, one-output, no-fee transaction: class RawTransactionsTest(BitcoinTestFramework): @@ -43,9 +41,9 @@ class RawTransactionsTest(BitcoinTestFramework): self.sync_all() self.nodes[0].generate(101) self.sync_all() - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5); - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0); - self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0); + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0) self.sync_all() self.nodes[0].generate(5) self.sync_all() @@ -64,7 +62,7 @@ class RawTransactionsTest(BitcoinTestFramework): except JSONRPCException,e: errorString = e.error['message'] - assert_equal("Missing inputs" in errorString, True); + assert("Missing inputs" in errorString) ######################### # RAW TX MULTISIG TESTS # @@ -83,7 +81,7 @@ class RawTransactionsTest(BitcoinTestFramework): bal = self.nodes[2].getbalance() # send 1.2 BTC to msig adr - txId = self.nodes[0].sendtoaddress(mSigObj, 1.2); + txId = self.nodes[0].sendtoaddress(mSigObj, 1.2) self.sync_all() self.nodes[0].generate(1) self.sync_all() @@ -105,7 +103,7 @@ class RawTransactionsTest(BitcoinTestFramework): mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']]) mSigObjValid = self.nodes[2].validateaddress(mSigObj) - txId = self.nodes[0].sendtoaddress(mSigObj, 2.2); + txId = self.nodes[0].sendtoaddress(mSigObj, 2.2) decTx = self.nodes[0].gettransaction(txId) rawTx = self.nodes[0].decoderawtransaction(decTx['hex']) sPK = rawTx['vout'][0]['scriptPubKey']['hex'] @@ -123,7 +121,7 @@ class RawTransactionsTest(BitcoinTestFramework): for outpoint in rawTx['vout']: if outpoint['value'] == Decimal('2.20000000'): vout = outpoint - break; + break bal = self.nodes[0].getbalance() inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex']}] diff --git a/qa/rpc-tests/receivedby.py b/qa/rpc-tests/receivedby.py index 16d6bd4cf..606426b39 100755 --- a/qa/rpc-tests/receivedby.py +++ b/qa/rpc-tests/receivedby.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -53,6 +53,11 @@ def check_array_result(object_array, to_match, expected, should_not_find = False class ReceivedByTest(BitcoinTestFramework): + def setup_nodes(self): + #This test requires mocktime + enable_mocktime() + return start_nodes(4, self.options.tmpdir) + def run_test(self): ''' listreceivedbyaddress Test diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py index f2e3f248e..321c2fe42 100755 --- a/qa/rpc-tests/reindex.py +++ b/qa/rpc-tests/reindex.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -8,7 +8,6 @@ # from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -import os.path class ReindexTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/replace-by-fee.py b/qa/rpc-tests/replace-by-fee.py new file mode 100755 index 000000000..ba1956853 --- /dev/null +++ b/qa/rpc-tests/replace-by-fee.py @@ -0,0 +1,592 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test replace by fee code +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +from test_framework.script import * +from test_framework.mininode import * +import binascii + +COIN = 100000000 +MAX_REPLACEMENT_LIMIT = 100 + +def satoshi_round(amount): + return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) + +def txToHex(tx): + return binascii.hexlify(tx.serialize()).decode('utf-8') + +def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])): + """Create a txout with a given amount and scriptPubKey + + Mines coins as needed. + + confirmed - txouts created will be confirmed in the blockchain; + unconfirmed otherwise. + """ + fee = 1*COIN + while node.getbalance() < satoshi_round((amount + fee)/COIN): + node.generate(100) + #print (node.getbalance(), amount, fee) + + new_addr = node.getnewaddress() + #print new_addr + txid = node.sendtoaddress(new_addr, satoshi_round((amount+fee)/COIN)) + tx1 = node.getrawtransaction(txid, 1) + txid = int(txid, 16) + i = None + + for i, txout in enumerate(tx1['vout']): + #print i, txout['scriptPubKey']['addresses'] + if txout['scriptPubKey']['addresses'] == [new_addr]: + #print i + break + assert i is not None + + tx2 = CTransaction() + tx2.vin = [CTxIn(COutPoint(txid, i))] + tx2.vout = [CTxOut(amount, scriptPubKey)] + tx2.rehash() + + binascii.hexlify(tx2.serialize()).decode('utf-8') + + signed_tx = node.signrawtransaction(binascii.hexlify(tx2.serialize()).decode('utf-8')) + + txid = node.sendrawtransaction(signed_tx['hex'], True) + + # If requested, ensure txouts are confirmed. + if confirmed: + mempool_size = len(node.getrawmempool()) + while mempool_size > 0: + node.generate(1) + new_size = len(node.getrawmempool()) + # Error out if we have something stuck in the mempool, as this + # would likely be a bug. + assert(new_size < mempool_size) + mempool_size = new_size + + return COutPoint(int(txid, 16), 0) + +class ReplaceByFeeTest(BitcoinTestFramework): + + def setup_network(self): + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", "-debug", + "-relaypriority=0", "-whitelist=127.0.0.1", + "-limitancestorcount=50", + "-limitancestorsize=101", + "-limitdescendantcount=200", + "-limitdescendantsize=101" + ])) + self.is_network_split = False + + def run_test(self): + make_utxo(self.nodes[0], 1*COIN) + + print "Running test simple doublespend..." + self.test_simple_doublespend() + + print "Running test doublespend chain..." + self.test_doublespend_chain() + + print "Running test doublespend tree..." + self.test_doublespend_tree() + + print "Running test replacement feeperkb..." + self.test_replacement_feeperkb() + + print "Running test spends of conflicting outputs..." + self.test_spends_of_conflicting_outputs() + + print "Running test new unconfirmed inputs..." + self.test_new_unconfirmed_inputs() + + print "Running test too many replacements..." + self.test_too_many_replacements() + + print "Running test opt-in..." + self.test_opt_in() + + print "Running test prioritised transactions..." + self.test_prioritised_transactions() + + print "Passed\n" + + def test_simple_doublespend(self): + """Simple doublespend""" + tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + + tx1a = CTransaction() + tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)] + tx1a.vout = [CTxOut(1*COIN, CScript([b'a']))] + tx1a_hex = txToHex(tx1a) + tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) + + # Should fail because we haven't changed the fee + tx1b = CTransaction() + tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] + tx1b.vout = [CTxOut(1*COIN, CScript([b'b']))] + tx1b_hex = txToHex(tx1b) + + try: + tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) # insufficient fee + else: + assert(False) + + # Extra 0.1 BTC fee + tx1b = CTransaction() + tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] + tx1b.vout = [CTxOut(0.9*COIN, CScript([b'b']))] + tx1b_hex = txToHex(tx1b) + tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) + + mempool = self.nodes[0].getrawmempool() + + assert (tx1a_txid not in mempool) + assert (tx1b_txid in mempool) + + assert_equal(tx1b_hex, self.nodes[0].getrawtransaction(tx1b_txid)) + + def test_doublespend_chain(self): + """Doublespend of a long chain""" + + initial_nValue = 50*COIN + tx0_outpoint = make_utxo(self.nodes[0], initial_nValue) + + prevout = tx0_outpoint + remaining_value = initial_nValue + chain_txids = [] + while remaining_value > 10*COIN: + remaining_value -= 1*COIN + tx = CTransaction() + tx.vin = [CTxIn(prevout, nSequence=0)] + tx.vout = [CTxOut(remaining_value, CScript([1]))] + tx_hex = txToHex(tx) + txid = self.nodes[0].sendrawtransaction(tx_hex, True) + chain_txids.append(txid) + prevout = COutPoint(int(txid, 16), 0) + + # Whether the double-spend is allowed is evaluated by including all + # child fees - 40 BTC - so this attempt is rejected. + dbl_tx = CTransaction() + dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)] + dbl_tx.vout = [CTxOut(initial_nValue - 30*COIN, CScript([1]))] + dbl_tx_hex = txToHex(dbl_tx) + + try: + self.nodes[0].sendrawtransaction(dbl_tx_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) # insufficient fee + else: + assert(False) # transaction mistakenly accepted! + + # Accepted with sufficient fee + dbl_tx = CTransaction() + dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)] + dbl_tx.vout = [CTxOut(1*COIN, CScript([1]))] + dbl_tx_hex = txToHex(dbl_tx) + self.nodes[0].sendrawtransaction(dbl_tx_hex, True) + + mempool = self.nodes[0].getrawmempool() + for doublespent_txid in chain_txids: + assert(doublespent_txid not in mempool) + + def test_doublespend_tree(self): + """Doublespend of a big tree of transactions""" + + initial_nValue = 50*COIN + tx0_outpoint = make_utxo(self.nodes[0], initial_nValue) + + def branch(prevout, initial_value, max_txs, tree_width=5, fee=0.0001*COIN, _total_txs=None): + if _total_txs is None: + _total_txs = [0] + if _total_txs[0] >= max_txs: + return + + txout_value = (initial_value - fee) // tree_width + if txout_value < fee: + return + + vout = [CTxOut(txout_value, CScript([i+1])) + for i in range(tree_width)] + tx = CTransaction() + tx.vin = [CTxIn(prevout, nSequence=0)] + tx.vout = vout + tx_hex = txToHex(tx) + + assert(len(tx.serialize()) < 100000) + txid = self.nodes[0].sendrawtransaction(tx_hex, True) + yield tx + _total_txs[0] += 1 + + txid = int(txid, 16) + + for i, txout in enumerate(tx.vout): + for x in branch(COutPoint(txid, i), txout_value, + max_txs, + tree_width=tree_width, fee=fee, + _total_txs=_total_txs): + yield x + + fee = 0.0001*COIN + n = MAX_REPLACEMENT_LIMIT + tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee)) + assert_equal(len(tree_txs), n) + + # Attempt double-spend, will fail because too little fee paid + dbl_tx = CTransaction() + dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)] + dbl_tx.vout = [CTxOut(initial_nValue - fee*n, CScript([1]))] + dbl_tx_hex = txToHex(dbl_tx) + try: + self.nodes[0].sendrawtransaction(dbl_tx_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) # insufficient fee + else: + assert(False) + + # 1 BTC fee is enough + dbl_tx = CTransaction() + dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)] + dbl_tx.vout = [CTxOut(initial_nValue - fee*n - 1*COIN, CScript([1]))] + dbl_tx_hex = txToHex(dbl_tx) + self.nodes[0].sendrawtransaction(dbl_tx_hex, True) + + mempool = self.nodes[0].getrawmempool() + + for tx in tree_txs: + tx.rehash() + assert (tx.hash not in mempool) + + # Try again, but with more total transactions than the "max txs + # double-spent at once" anti-DoS limit. + for n in (MAX_REPLACEMENT_LIMIT+1, MAX_REPLACEMENT_LIMIT*2): + fee = 0.0001*COIN + tx0_outpoint = make_utxo(self.nodes[0], initial_nValue) + tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee)) + assert_equal(len(tree_txs), n) + + dbl_tx = CTransaction() + dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)] + dbl_tx.vout = [CTxOut(initial_nValue - 2*fee*n, CScript([1]))] + dbl_tx_hex = txToHex(dbl_tx) + try: + self.nodes[0].sendrawtransaction(dbl_tx_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) + assert_equal("too many potential replacements" in exp.error['message'], True) + else: + assert(False) + + for tx in tree_txs: + tx.rehash() + self.nodes[0].getrawtransaction(tx.hash) + + def test_replacement_feeperkb(self): + """Replacement requires fee-per-KB to be higher""" + tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + + tx1a = CTransaction() + tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)] + tx1a.vout = [CTxOut(1*COIN, CScript([b'a']))] + tx1a_hex = txToHex(tx1a) + tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) + + # Higher fee, but the fee per KB is much lower, so the replacement is + # rejected. + tx1b = CTransaction() + tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] + tx1b.vout = [CTxOut(0.001*COIN, CScript([b'a'*999000]))] + tx1b_hex = txToHex(tx1b) + + try: + tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) # insufficient fee + else: + assert(False) + + def test_spends_of_conflicting_outputs(self): + """Replacements that spend conflicting tx outputs are rejected""" + utxo1 = make_utxo(self.nodes[0], 1.2*COIN) + utxo2 = make_utxo(self.nodes[0], 3.0*COIN) + + tx1a = CTransaction() + tx1a.vin = [CTxIn(utxo1, nSequence=0)] + tx1a.vout = [CTxOut(1.1*COIN, CScript([b'a']))] + tx1a_hex = txToHex(tx1a) + tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) + + tx1a_txid = int(tx1a_txid, 16) + + # Direct spend an output of the transaction we're replacing. + tx2 = CTransaction() + tx2.vin = [CTxIn(utxo1, nSequence=0), CTxIn(utxo2, nSequence=0)] + tx2.vin.append(CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)) + tx2.vout = tx1a.vout + tx2_hex = txToHex(tx2) + + try: + tx2_txid = self.nodes[0].sendrawtransaction(tx2_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) + else: + assert(False) + + # Spend tx1a's output to test the indirect case. + tx1b = CTransaction() + tx1b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)] + tx1b.vout = [CTxOut(1.0*COIN, CScript([b'a']))] + tx1b_hex = txToHex(tx1b) + tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) + tx1b_txid = int(tx1b_txid, 16) + + tx2 = CTransaction() + tx2.vin = [CTxIn(utxo1, nSequence=0), CTxIn(utxo2, nSequence=0), + CTxIn(COutPoint(tx1b_txid, 0))] + tx2.vout = tx1a.vout + tx2_hex = txToHex(tx2) + + try: + tx2_txid = self.nodes[0].sendrawtransaction(tx2_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) + else: + assert(False) + + def test_new_unconfirmed_inputs(self): + """Replacements that add new unconfirmed inputs are rejected""" + confirmed_utxo = make_utxo(self.nodes[0], 1.1*COIN) + unconfirmed_utxo = make_utxo(self.nodes[0], 0.1*COIN, False) + + tx1 = CTransaction() + tx1.vin = [CTxIn(confirmed_utxo)] + tx1.vout = [CTxOut(1.0*COIN, CScript([b'a']))] + tx1_hex = txToHex(tx1) + tx1_txid = self.nodes[0].sendrawtransaction(tx1_hex, True) + + tx2 = CTransaction() + tx2.vin = [CTxIn(confirmed_utxo), CTxIn(unconfirmed_utxo)] + tx2.vout = tx1.vout + tx2_hex = txToHex(tx2) + + try: + tx2_txid = self.nodes[0].sendrawtransaction(tx2_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) + else: + assert(False) + + def test_too_many_replacements(self): + """Replacements that evict too many transactions are rejected""" + # Try directly replacing more than MAX_REPLACEMENT_LIMIT + # transactions + + # Start by creating a single transaction with many outputs + initial_nValue = 10*COIN + utxo = make_utxo(self.nodes[0], initial_nValue) + fee = 0.0001*COIN + split_value = int((initial_nValue-fee)/(MAX_REPLACEMENT_LIMIT+1)) + actual_fee = initial_nValue - split_value*(MAX_REPLACEMENT_LIMIT+1) + + outputs = [] + for i in range(MAX_REPLACEMENT_LIMIT+1): + outputs.append(CTxOut(split_value, CScript([1]))) + + splitting_tx = CTransaction() + splitting_tx.vin = [CTxIn(utxo, nSequence=0)] + splitting_tx.vout = outputs + splitting_tx_hex = txToHex(splitting_tx) + + txid = self.nodes[0].sendrawtransaction(splitting_tx_hex, True) + txid = int(txid, 16) + + # Now spend each of those outputs individually + for i in range(MAX_REPLACEMENT_LIMIT+1): + tx_i = CTransaction() + tx_i.vin = [CTxIn(COutPoint(txid, i), nSequence=0)] + tx_i.vout = [CTxOut(split_value-fee, CScript([b'a']))] + tx_i_hex = txToHex(tx_i) + self.nodes[0].sendrawtransaction(tx_i_hex, True) + + # Now create doublespend of the whole lot; should fail. + # Need a big enough fee to cover all spending transactions and have + # a higher fee rate + double_spend_value = (split_value-100*fee)*(MAX_REPLACEMENT_LIMIT+1) + inputs = [] + for i in range(MAX_REPLACEMENT_LIMIT+1): + inputs.append(CTxIn(COutPoint(txid, i), nSequence=0)) + double_tx = CTransaction() + double_tx.vin = inputs + double_tx.vout = [CTxOut(double_spend_value, CScript([b'a']))] + double_tx_hex = txToHex(double_tx) + + try: + self.nodes[0].sendrawtransaction(double_tx_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) + assert_equal("too many potential replacements" in exp.error['message'], True) + else: + assert(False) + + # If we remove an input, it should pass + double_tx = CTransaction() + double_tx.vin = inputs[0:-1] + double_tx.vout = [CTxOut(double_spend_value, CScript([b'a']))] + double_tx_hex = txToHex(double_tx) + self.nodes[0].sendrawtransaction(double_tx_hex, True) + + def test_opt_in(self): + """ Replacing should only work if orig tx opted in """ + tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + + # Create a non-opting in transaction + tx1a = CTransaction() + tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0xffffffff)] + tx1a.vout = [CTxOut(1*COIN, CScript([b'a']))] + tx1a_hex = txToHex(tx1a) + tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) + + # Shouldn't be able to double-spend + tx1b = CTransaction() + tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] + tx1b.vout = [CTxOut(0.9*COIN, CScript([b'b']))] + tx1b_hex = txToHex(tx1b) + + try: + tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) + else: + print tx1b_txid + assert(False) + + tx1_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + + # Create a different non-opting in transaction + tx2a = CTransaction() + tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0xfffffffe)] + tx2a.vout = [CTxOut(1*COIN, CScript([b'a']))] + tx2a_hex = txToHex(tx2a) + tx2a_txid = self.nodes[0].sendrawtransaction(tx2a_hex, True) + + # Still shouldn't be able to double-spend + tx2b = CTransaction() + tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)] + tx2b.vout = [CTxOut(0.9*COIN, CScript([b'b']))] + tx2b_hex = txToHex(tx2b) + + try: + tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) + else: + assert(False) + + # Now create a new transaction that spends from tx1a and tx2a + # opt-in on one of the inputs + # Transaction should be replaceable on either input + + tx1a_txid = int(tx1a_txid, 16) + tx2a_txid = int(tx2a_txid, 16) + + tx3a = CTransaction() + tx3a.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0xffffffff), + CTxIn(COutPoint(tx2a_txid, 0), nSequence=0xfffffffd)] + tx3a.vout = [CTxOut(0.9*COIN, CScript([b'c'])), CTxOut(0.9*COIN, CScript([b'd']))] + tx3a_hex = txToHex(tx3a) + + self.nodes[0].sendrawtransaction(tx3a_hex, True) + + tx3b = CTransaction() + tx3b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)] + tx3b.vout = [CTxOut(0.5*COIN, CScript([b'e']))] + tx3b_hex = txToHex(tx3b) + + tx3c = CTransaction() + tx3c.vin = [CTxIn(COutPoint(tx2a_txid, 0), nSequence=0)] + tx3c.vout = [CTxOut(0.5*COIN, CScript([b'f']))] + tx3c_hex = txToHex(tx3c) + + self.nodes[0].sendrawtransaction(tx3b_hex, True) + # If tx3b was accepted, tx3c won't look like a replacement, + # but make sure it is accepted anyway + self.nodes[0].sendrawtransaction(tx3c_hex, True) + + def test_prioritised_transactions(self): + # Ensure that fee deltas used via prioritisetransaction are + # correctly used by replacement logic + + # 1. Check that feeperkb uses modified fees + tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + + tx1a = CTransaction() + tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)] + tx1a.vout = [CTxOut(1*COIN, CScript([b'a']))] + tx1a_hex = txToHex(tx1a) + tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True) + + # Higher fee, but the actual fee per KB is much lower. + tx1b = CTransaction() + tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)] + tx1b.vout = [CTxOut(0.001*COIN, CScript([b'a'*740000]))] + tx1b_hex = txToHex(tx1b) + + # Verify tx1b cannot replace tx1a. + try: + tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) + else: + assert(False) + + # Use prioritisetransaction to set tx1a's fee to 0. + self.nodes[0].prioritisetransaction(tx1a_txid, 0, int(-0.1*COIN)) + + # Now tx1b should be able to replace tx1a + tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True) + + assert(tx1b_txid in self.nodes[0].getrawmempool()) + + # 2. Check that absolute fee checks use modified fee. + tx1_outpoint = make_utxo(self.nodes[0], 1.1*COIN) + + tx2a = CTransaction() + tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0)] + tx2a.vout = [CTxOut(1*COIN, CScript([b'a']))] + tx2a_hex = txToHex(tx2a) + tx2a_txid = self.nodes[0].sendrawtransaction(tx2a_hex, True) + + # Lower fee, but we'll prioritise it + tx2b = CTransaction() + tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)] + tx2b.vout = [CTxOut(1.01*COIN, CScript([b'a']))] + tx2b.rehash() + tx2b_hex = txToHex(tx2b) + + # Verify tx2b cannot replace tx2a. + try: + tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True) + except JSONRPCException as exp: + assert_equal(exp.error['code'], -26) + else: + assert(False) + + # Now prioritise tx2b to have a higher modified fee + self.nodes[0].prioritisetransaction(tx2b.hash, 0, int(0.1*COIN)) + + # tx2b should now be accepted + tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True) + + assert(tx2b_txid in self.nodes[0].getrawmempool()) + +if __name__ == '__main__': + ReplaceByFeeTest().main() diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index e084ad55a..8c8353650 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,9 +12,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * from struct import * import binascii -import json import StringIO -import decimal try: import http.client as httplib @@ -143,9 +141,9 @@ class RESTTest (BitcoinTestFramework): binaryRequest = b'\x01\x02' binaryRequest += binascii.unhexlify(txid) - binaryRequest += pack("i", n); - binaryRequest += binascii.unhexlify(vintx); - binaryRequest += pack("i", 0); + binaryRequest += pack("i", n) + binaryRequest += binascii.unhexlify(vintx) + binaryRequest += pack("i", 0) bin_response = http_post_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', binaryRequest) output = StringIO.StringIO() @@ -206,7 +204,7 @@ class RESTTest (BitcoinTestFramework): json_request = '/checkmempool/' for x in range(0, 15): json_request += txid+'-'+str(n)+'/' - json_request = json_request.rstrip("/"); + json_request = json_request.rstrip("/") response = http_post_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json', '', True) assert_equal(response.status, 200) #must be a 500 because we exceeding the limits @@ -254,7 +252,7 @@ class RESTTest (BitcoinTestFramework): response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"json", True) assert_equal(response_header_json.status, 200) response_header_json_str = response_header_json.read() - json_obj = json.loads(response_header_json_str, parse_float=decimal.Decimal) + json_obj = json.loads(response_header_json_str, parse_float=Decimal) assert_equal(len(json_obj), 1) #ensure that there is one header in the json response assert_equal(json_obj[0]['hash'], bb_hash) #request/response hash should be the same @@ -282,7 +280,7 @@ class RESTTest (BitcoinTestFramework): assert_equal(len(json_obj), 5) #now we should have 5 header objects # do tx test - tx_hash = block_json_obj['tx'][0]['txid']; + tx_hash = block_json_obj['tx'][0]['txid'] json_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"json") json_obj = json.loads(json_string) assert_equal(json_obj['txid'], tx_hash) diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index 7a9da6678..10a48b555 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -1,17 +1,12 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # Test for -rpcbind, as well as -rpcallowip and -rpcconnect -# Add python-bitcoinrpc to module search path: -import os -import sys +# TODO extend this test from the test framework (like all other tests) -import json -import shutil -import subprocess import tempfile import traceback diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py new file mode 100755 index 000000000..2bc32584b --- /dev/null +++ b/qa/rpc-tests/sendheaders.py @@ -0,0 +1,517 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2015 The Bitcoin Core developers +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# + +from test_framework.mininode import * +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +from test_framework.blocktools import create_block, create_coinbase + +''' +SendHeadersTest -- test behavior of headers messages to announce blocks. + +Setup: + +- Two nodes, two p2p connections to node0. One p2p connection should only ever + receive inv's (omitted from testing description below, this is our control). + Second node is used for creating reorgs. + +Part 1: No headers announcements before "sendheaders" +a. node mines a block [expect: inv] + send getdata for the block [expect: block] +b. node mines another block [expect: inv] + send getheaders and getdata [expect: headers, then block] +c. node mines another block [expect: inv] + peer mines a block, announces with header [expect: getdata] +d. node mines another block [expect: inv] + +Part 2: After "sendheaders", headers announcements should generally work. +a. peer sends sendheaders [expect: no response] + peer sends getheaders with current tip [expect: no response] +b. node mines a block [expect: tip header] +c. for N in 1, ..., 10: + * for announce-type in {inv, header} + - peer mines N blocks, announces with announce-type + [ expect: getheaders/getdata or getdata, deliver block(s) ] + - node mines a block [ expect: 1 header ] + +Part 3: Headers announcements stop after large reorg and resume after getheaders or inv from peer. +- For response-type in {inv, getheaders} + * node mines a 7 block reorg [ expect: headers announcement of 8 blocks ] + * node mines an 8-block reorg [ expect: inv at tip ] + * peer responds with getblocks/getdata [expect: inv, blocks ] + * node mines another block [ expect: inv at tip, peer sends getdata, expect: block ] + * node mines another block at tip [ expect: inv ] + * peer responds with getheaders with an old hashstop more than 8 blocks back [expect: headers] + * peer requests block [ expect: block ] + * node mines another block at tip [ expect: inv, peer sends getdata, expect: block ] + * peer sends response-type [expect headers if getheaders, getheaders/getdata if mining new block] + * node mines 1 block [expect: 1 header, peer responds with getdata] + +Part 4: Test direct fetch behavior +a. Announce 2 old block headers. + Expect: no getdata requests. +b. Announce 3 new blocks via 1 headers message. + Expect: one getdata request for all 3 blocks. + (Send blocks.) +c. Announce 1 header that forks off the last two blocks. + Expect: no response. +d. Announce 1 more header that builds on that fork. + Expect: one getdata request for two blocks. +e. Announce 16 more headers that build on that fork. + Expect: getdata request for 14 more blocks. +f. Announce 1 more header that builds on that fork. + Expect: no response. +''' + +class BaseNode(NodeConnCB): + def __init__(self): + NodeConnCB.__init__(self) + self.connection = None + self.last_inv = None + self.last_headers = None + self.last_block = None + self.ping_counter = 1 + self.last_pong = msg_pong(0) + self.last_getdata = None + self.sleep_time = 0.05 + self.block_announced = False + + def clear_last_announcement(self): + with mininode_lock: + self.block_announced = False + self.last_inv = None + self.last_headers = None + + def add_connection(self, conn): + self.connection = conn + + # Request data for a list of block hashes + def get_data(self, block_hashes): + msg = msg_getdata() + for x in block_hashes: + msg.inv.append(CInv(2, x)) + self.connection.send_message(msg) + + def get_headers(self, locator, hashstop): + msg = msg_getheaders() + msg.locator.vHave = locator + msg.hashstop = hashstop + self.connection.send_message(msg) + + def send_block_inv(self, blockhash): + msg = msg_inv() + msg.inv = [CInv(2, blockhash)] + self.connection.send_message(msg) + + # Wrapper for the NodeConn's send_message function + def send_message(self, message): + self.connection.send_message(message) + + def on_inv(self, conn, message): + self.last_inv = message + self.block_announced = True + + def on_headers(self, conn, message): + self.last_headers = message + self.block_announced = True + + def on_block(self, conn, message): + self.last_block = message.block + self.last_block.calc_sha256() + + def on_getdata(self, conn, message): + self.last_getdata = message + + def on_pong(self, conn, message): + self.last_pong = message + + # Test whether the last announcement we received had the + # right header or the right inv + # inv and headers should be lists of block hashes + def check_last_announcement(self, headers=None, inv=None): + expect_headers = headers if headers != None else [] + expect_inv = inv if inv != None else [] + test_function = lambda: self.block_announced + self.sync(test_function) + with mininode_lock: + self.block_announced = False + + success = True + compare_inv = [] + if self.last_inv != None: + compare_inv = [x.hash for x in self.last_inv.inv] + if compare_inv != expect_inv: + success = False + + hash_headers = [] + if self.last_headers != None: + # treat headers as a list of block hashes + hash_headers = [ x.sha256 for x in self.last_headers.headers ] + if hash_headers != expect_headers: + success = False + + self.last_inv = None + self.last_headers = None + return success + + # Syncing helpers + def sync(self, test_function, timeout=60): + while timeout > 0: + with mininode_lock: + if test_function(): + return + time.sleep(self.sleep_time) + timeout -= self.sleep_time + raise AssertionError("Sync failed to complete") + + def sync_with_ping(self, timeout=60): + self.send_message(msg_ping(nonce=self.ping_counter)) + test_function = lambda: self.last_pong.nonce == self.ping_counter + self.sync(test_function, timeout) + self.ping_counter += 1 + return + + def wait_for_block(self, blockhash, timeout=60): + test_function = lambda: self.last_block != None and self.last_block.sha256 == blockhash + self.sync(test_function, timeout) + return + + def wait_for_getdata(self, hash_list, timeout=60): + if hash_list == []: + return + + test_function = lambda: self.last_getdata != None and [x.hash for x in self.last_getdata.inv] == hash_list + self.sync(test_function, timeout) + return + + def send_header_for_blocks(self, new_blocks): + headers_message = msg_headers() + headers_message.headers = [ CBlockHeader(b) for b in new_blocks ] + self.send_message(headers_message) + + def send_getblocks(self, locator): + getblocks_message = msg_getblocks() + getblocks_message.locator.vHave = locator + self.send_message(getblocks_message) + +# InvNode: This peer should only ever receive inv's, because it doesn't ever send a +# "sendheaders" message. +class InvNode(BaseNode): + def __init__(self): + BaseNode.__init__(self) + +# TestNode: This peer is the one we use for most of the testing. +class TestNode(BaseNode): + def __init__(self): + BaseNode.__init__(self) + +class SendHeadersTest(BitcoinTestFramework): + def setup_chain(self): + initialize_chain_clean(self.options.tmpdir, 2) + + def setup_network(self): + self.nodes = [] + self.nodes = start_nodes(2, self.options.tmpdir, [["-debug", "-logtimemicros=1"]]*2) + connect_nodes(self.nodes[0], 1) + + # mine count blocks and return the new tip + def mine_blocks(self, count): + # Clear out last block announcement from each p2p listener + [ x.clear_last_announcement() for x in self.p2p_connections ] + self.nodes[0].generate(count) + return int(self.nodes[0].getbestblockhash(), 16) + + # mine a reorg that invalidates length blocks (replacing them with + # length+1 blocks). + # Note: we clear the state of our p2p connections after the + # to-be-reorged-out blocks are mined, so that we don't break later tests. + # return the list of block hashes newly mined + def mine_reorg(self, length): + self.nodes[0].generate(length) # make sure all invalidated blocks are node0's + sync_blocks(self.nodes, wait=0.1) + [x.clear_last_announcement() for x in self.p2p_connections] + + tip_height = self.nodes[1].getblockcount() + hash_to_invalidate = self.nodes[1].getblockhash(tip_height-(length-1)) + self.nodes[1].invalidateblock(hash_to_invalidate) + all_hashes = self.nodes[1].generate(length+1) # Must be longer than the orig chain + sync_blocks(self.nodes, wait=0.1) + return [int(x, 16) for x in all_hashes] + + def run_test(self): + # Setup the p2p connections and start up the network thread. + inv_node = InvNode() + test_node = TestNode() + + self.p2p_connections = [inv_node, test_node] + + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], inv_node)) + # Set nServices to 0 for test_node, so no block download will occur outside of + # direct fetching + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_node, services=0)) + inv_node.add_connection(connections[0]) + test_node.add_connection(connections[1]) + + NetworkThread().start() # Start up network handling in another thread + + # Test logic begins here + inv_node.wait_for_verack() + test_node.wait_for_verack() + + tip = int(self.nodes[0].getbestblockhash(), 16) + + # PART 1 + # 1. Mine a block; expect inv announcements each time + print "Part 1: headers don't start before sendheaders message..." + for i in xrange(4): + old_tip = tip + tip = self.mine_blocks(1) + assert_equal(inv_node.check_last_announcement(inv=[tip]), True) + assert_equal(test_node.check_last_announcement(inv=[tip]), True) + # Try a few different responses; none should affect next announcement + if i == 0: + # first request the block + test_node.get_data([tip]) + test_node.wait_for_block(tip, timeout=5) + elif i == 1: + # next try requesting header and block + test_node.get_headers(locator=[old_tip], hashstop=tip) + test_node.get_data([tip]) + test_node.wait_for_block(tip) + test_node.clear_last_announcement() # since we requested headers... + elif i == 2: + # this time announce own block via headers + height = self.nodes[0].getblockcount() + last_time = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['time'] + block_time = last_time + 1 + new_block = create_block(tip, create_coinbase(height+1), block_time) + new_block.solve() + test_node.send_header_for_blocks([new_block]) + test_node.wait_for_getdata([new_block.sha256], timeout=5) + test_node.send_message(msg_block(new_block)) + test_node.sync_with_ping() # make sure this block is processed + inv_node.clear_last_announcement() + test_node.clear_last_announcement() + + print "Part 1: success!" + print "Part 2: announce blocks with headers after sendheaders message..." + # PART 2 + # 2. Send a sendheaders message and test that headers announcements + # commence and keep working. + test_node.send_message(msg_sendheaders()) + prev_tip = int(self.nodes[0].getbestblockhash(), 16) + test_node.get_headers(locator=[prev_tip], hashstop=0L) + test_node.sync_with_ping() + + # Now that we've synced headers, headers announcements should work + tip = self.mine_blocks(1) + assert_equal(inv_node.check_last_announcement(inv=[tip]), True) + assert_equal(test_node.check_last_announcement(headers=[tip]), True) + + height = self.nodes[0].getblockcount()+1 + block_time += 10 # Advance far enough ahead + for i in xrange(10): + # Mine i blocks, and alternate announcing either via + # inv (of tip) or via headers. After each, new blocks + # mined by the node should successfully be announced + # with block header, even though the blocks are never requested + for j in xrange(2): + blocks = [] + for b in xrange(i+1): + blocks.append(create_block(tip, create_coinbase(height), block_time)) + blocks[-1].solve() + tip = blocks[-1].sha256 + block_time += 1 + height += 1 + if j == 0: + # Announce via inv + test_node.send_block_inv(tip) + test_node.wait_for_getdata([tip], timeout=5) + # Test that duplicate inv's won't result in duplicate + # getdata requests, or duplicate headers announcements + inv_node.send_block_inv(tip) + # Should have received a getheaders as well! + test_node.send_header_for_blocks(blocks) + test_node.wait_for_getdata([x.sha256 for x in blocks[0:-1]], timeout=5) + [ inv_node.send_block_inv(x.sha256) for x in blocks[0:-1] ] + inv_node.sync_with_ping() + else: + # Announce via headers + test_node.send_header_for_blocks(blocks) + test_node.wait_for_getdata([x.sha256 for x in blocks], timeout=5) + # Test that duplicate headers won't result in duplicate + # getdata requests (the check is further down) + inv_node.send_header_for_blocks(blocks) + inv_node.sync_with_ping() + [ test_node.send_message(msg_block(x)) for x in blocks ] + test_node.sync_with_ping() + inv_node.sync_with_ping() + # This block should not be announced to the inv node (since it also + # broadcast it) + assert_equal(inv_node.last_inv, None) + assert_equal(inv_node.last_headers, None) + tip = self.mine_blocks(1) + assert_equal(inv_node.check_last_announcement(inv=[tip]), True) + assert_equal(test_node.check_last_announcement(headers=[tip]), True) + height += 1 + block_time += 1 + + print "Part 2: success!" + + print "Part 3: headers announcements can stop after large reorg, and resume after headers/inv from peer..." + + # PART 3. Headers announcements can stop after large reorg, and resume after + # getheaders or inv from peer. + for j in xrange(2): + # First try mining a reorg that can propagate with header announcement + new_block_hashes = self.mine_reorg(length=7) + tip = new_block_hashes[-1] + assert_equal(inv_node.check_last_announcement(inv=[tip]), True) + assert_equal(test_node.check_last_announcement(headers=new_block_hashes), True) + + block_time += 8 + + # Mine a too-large reorg, which should be announced with a single inv + new_block_hashes = self.mine_reorg(length=8) + tip = new_block_hashes[-1] + assert_equal(inv_node.check_last_announcement(inv=[tip]), True) + assert_equal(test_node.check_last_announcement(inv=[tip]), True) + + block_time += 9 + + fork_point = self.nodes[0].getblock("%02x" % new_block_hashes[0])["previousblockhash"] + fork_point = int(fork_point, 16) + + # Use getblocks/getdata + test_node.send_getblocks(locator = [fork_point]) + assert_equal(test_node.check_last_announcement(inv=new_block_hashes), True) + test_node.get_data(new_block_hashes) + test_node.wait_for_block(new_block_hashes[-1]) + + for i in xrange(3): + # Mine another block, still should get only an inv + tip = self.mine_blocks(1) + assert_equal(inv_node.check_last_announcement(inv=[tip]), True) + assert_equal(test_node.check_last_announcement(inv=[tip]), True) + if i == 0: + # Just get the data -- shouldn't cause headers announcements to resume + test_node.get_data([tip]) + test_node.wait_for_block(tip) + elif i == 1: + # Send a getheaders message that shouldn't trigger headers announcements + # to resume (best header sent will be too old) + test_node.get_headers(locator=[fork_point], hashstop=new_block_hashes[1]) + test_node.get_data([tip]) + test_node.wait_for_block(tip) + elif i == 2: + test_node.get_data([tip]) + test_node.wait_for_block(tip) + # This time, try sending either a getheaders to trigger resumption + # of headers announcements, or mine a new block and inv it, also + # triggering resumption of headers announcements. + if j == 0: + test_node.get_headers(locator=[tip], hashstop=0L) + test_node.sync_with_ping() + else: + test_node.send_block_inv(tip) + test_node.sync_with_ping() + # New blocks should now be announced with header + tip = self.mine_blocks(1) + assert_equal(inv_node.check_last_announcement(inv=[tip]), True) + assert_equal(test_node.check_last_announcement(headers=[tip]), True) + + print "Part 3: success!" + + print "Part 4: Testing direct fetch behavior..." + tip = self.mine_blocks(1) + height = self.nodes[0].getblockcount() + 1 + last_time = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['time'] + block_time = last_time + 1 + + # Create 2 blocks. Send the blocks, then send the headers. + blocks = [] + for b in xrange(2): + blocks.append(create_block(tip, create_coinbase(height), block_time)) + blocks[-1].solve() + tip = blocks[-1].sha256 + block_time += 1 + height += 1 + inv_node.send_message(msg_block(blocks[-1])) + + inv_node.sync_with_ping() # Make sure blocks are processed + test_node.last_getdata = None + test_node.send_header_for_blocks(blocks) + test_node.sync_with_ping() + # should not have received any getdata messages + with mininode_lock: + assert_equal(test_node.last_getdata, None) + + # This time, direct fetch should work + blocks = [] + for b in xrange(3): + blocks.append(create_block(tip, create_coinbase(height), block_time)) + blocks[-1].solve() + tip = blocks[-1].sha256 + block_time += 1 + height += 1 + + test_node.send_header_for_blocks(blocks) + test_node.sync_with_ping() + test_node.wait_for_getdata([x.sha256 for x in blocks], timeout=test_node.sleep_time) + + [ test_node.send_message(msg_block(x)) for x in blocks ] + + test_node.sync_with_ping() + + # Now announce a header that forks the last two blocks + tip = blocks[0].sha256 + height -= 1 + blocks = [] + + # Create extra blocks for later + for b in xrange(20): + blocks.append(create_block(tip, create_coinbase(height), block_time)) + blocks[-1].solve() + tip = blocks[-1].sha256 + block_time += 1 + height += 1 + + # Announcing one block on fork should not trigger direct fetch + # (less work than tip) + test_node.last_getdata = None + test_node.send_header_for_blocks(blocks[0:1]) + test_node.sync_with_ping() + with mininode_lock: + assert_equal(test_node.last_getdata, None) + + # Announcing one more block on fork should trigger direct fetch for + # both blocks (same work as tip) + test_node.send_header_for_blocks(blocks[1:2]) + test_node.sync_with_ping() + test_node.wait_for_getdata([x.sha256 for x in blocks[0:2]], timeout=test_node.sleep_time) + + # Announcing 16 more headers should trigger direct fetch for 14 more + # blocks + test_node.send_header_for_blocks(blocks[2:18]) + test_node.sync_with_ping() + test_node.wait_for_getdata([x.sha256 for x in blocks[2:16]], timeout=test_node.sleep_time) + + # Announcing 1 more header should not trigger any response + test_node.last_getdata = None + test_node.send_header_for_blocks(blocks[18:19]) + test_node.sync_with_ping() + with mininode_lock: + assert_equal(test_node.last_getdata, None) + + print "Part 4: success!" + + # Finally, check that the inv node never received a getdata request, + # throughout the test + assert_equal(inv_node.last_getdata, None) + +if __name__ == '__main__': + SendHeadersTest().main() diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index c15c5fda0..b209ae0c1 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -19,9 +19,6 @@ P2SH_2 = "2NBdpwq8Aoo1EEKEXPNrKvr5xQr3M9UfcZA" # P2SH of "OP_2 OP_DROP" # 4 bytes of OP_TRUE and push 2-byte redeem script of "OP_1 OP_DROP" or "OP_2 OP_DROP" SCRIPT_SIG = ["0451025175", "0451025275"] -def satoshi_round(amount): - return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) - def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment): ''' Create and send a transaction with a random fee. @@ -120,15 +117,26 @@ def check_estimates(node, fees_seen, max_invalid, print_estimates = True): last_e = e valid_estimate = False invalid_estimates = 0 - for e in all_estimates: + for i,e in enumerate(all_estimates): # estimate is for i+1 if e >= 0: valid_estimate = True + # estimatesmartfee should return the same result + assert_equal(node.estimatesmartfee(i+1)["feerate"], e) + else: invalid_estimates += 1 - # Once we're at a high enough confirmation count that we can give an estimate - # We should have estimates for all higher confirmation counts - if valid_estimate and e < 0: - raise AssertionError("Invalid estimate appears at higher confirm count than valid estimate") + + # estimatesmartfee should still be valid + approx_estimate = node.estimatesmartfee(i+1)["feerate"] + answer_found = node.estimatesmartfee(i+1)["blocks"] + assert(approx_estimate > 0) + assert(answer_found > i+1) + + # Once we're at a high enough confirmation count that we can give an estimate + # We should have estimates for all higher confirmation counts + if valid_estimate: + raise AssertionError("Invalid estimate appears at higher confirm count than valid estimate") + # Check on the expected number of different confirmation counts # that we might not have valid estimates for if invalid_estimates > max_invalid: @@ -184,13 +192,13 @@ class EstimateFeeTest(BitcoinTestFramework): # NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes, # (17k is room enough for 110 or so transactions) self.nodes.append(start_node(1, self.options.tmpdir, - ["-blockprioritysize=1500", "-blockmaxsize=18000", + ["-blockprioritysize=1500", "-blockmaxsize=17000", "-maxorphantx=1000", "-relaypriority=0", "-debug=estimatefee"])) connect_nodes(self.nodes[1], 0) # Node2 is a stingy miner, that - # produces too small blocks (room for only 70 or so transactions) - node2args = ["-blockprioritysize=0", "-blockmaxsize=12000", "-maxorphantx=1000", "-relaypriority=0"] + # produces too small blocks (room for only 55 or so transactions) + node2args = ["-blockprioritysize=0", "-blockmaxsize=8000", "-maxorphantx=1000", "-relaypriority=0"] self.nodes.append(start_node(2, self.options.tmpdir, node2args)) connect_nodes(self.nodes[0], 2) @@ -229,22 +237,19 @@ class EstimateFeeTest(BitcoinTestFramework): self.fees_per_kb = [] self.memutxo = [] self.confutxo = self.txouts # Start with the set of confirmed txouts after splitting - print("Checking estimates for 1/2/3/6/15/25 blocks") - print("Creating transactions and mining them with a huge block size") - # Create transactions and mine 20 big blocks with node 0 such that the mempool is always emptied - self.transact_and_mine(30, self.nodes[0]) - check_estimates(self.nodes[1], self.fees_per_kb, 1) + print("Will output estimates for 1/2/3/6/15/25 blocks") - print("Creating transactions and mining them with a block size that can't keep up") - # Create transactions and mine 30 small blocks with node 2, but create txs faster than we can mine - self.transact_and_mine(20, self.nodes[2]) - check_estimates(self.nodes[1], self.fees_per_kb, 3) + for i in xrange(2): + print("Creating transactions and mining them with a block size that can't keep up") + # Create transactions and mine 10 small blocks with node 2, but create txs faster than we can mine + self.transact_and_mine(10, self.nodes[2]) + check_estimates(self.nodes[1], self.fees_per_kb, 14) - print("Creating transactions and mining them at a block size that is just big enough") - # Generate transactions while mining 40 more blocks, this time with node1 - # which mines blocks with capacity just above the rate that transactions are being created - self.transact_and_mine(40, self.nodes[1]) - check_estimates(self.nodes[1], self.fees_per_kb, 2) + print("Creating transactions and mining them at a block size that is just big enough") + # Generate transactions while mining 10 more blocks, this time with node1 + # which mines blocks with capacity just above the rate that transactions are being created + self.transact_and_mine(10, self.nodes[1]) + check_estimates(self.nodes[1], self.fees_per_kb, 2) # Finish by mining a normal-sized block: while len(self.nodes[1].getrawmempool()) > 0: diff --git a/qa/rpc-tests/test_framework/blocktools.py b/qa/rpc-tests/test_framework/blocktools.py index 59aa8c15c..7eea41b75 100644 --- a/qa/rpc-tests/test_framework/blocktools.py +++ b/qa/rpc-tests/test_framework/blocktools.py @@ -1,11 +1,11 @@ # blocktools.py - utilities for manipulating blocks and transactions -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # from mininode import * -from script import CScript, CScriptOp, OP_TRUE, OP_CHECKSIG +from script import CScript, OP_TRUE, OP_CHECKSIG # Create a block (with regtest difficulty) def create_block(hashprev, coinbase, nTime=None): diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py index e0b3ce040..a4cd4d0a8 100755 --- a/qa/rpc-tests/test_framework/comptool.py +++ b/qa/rpc-tests/test_framework/comptool.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# +# Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # @@ -41,17 +41,32 @@ def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): return False +class RejectResult(object): + ''' + Outcome that expects rejection of a transaction or block. + ''' + def __init__(self, code, reason=''): + self.code = code + self.reason = reason + def match(self, other): + if self.code != other.code: + return False + return other.reason.startswith(self.reason) + def __repr__(self): + return '%i:%s' % (self.code,self.reason or '*') + class TestNode(NodeConnCB): def __init__(self, block_store, tx_store): NodeConnCB.__init__(self) - self.create_callback_map() self.conn = None self.bestblockhash = None self.block_store = block_store self.block_request_map = {} self.tx_store = tx_store self.tx_request_map = {} + self.block_reject_map = {} + self.tx_reject_map = {} # When the pingmap is non-empty we're waiting for # a response @@ -95,6 +110,12 @@ class TestNode(NodeConnCB): except KeyError: raise AssertionError("Got pong for unknown ping [%s]" % repr(message)) + def on_reject(self, conn, message): + if message.message == 'tx': + self.tx_reject_map[message.data] = RejectResult(message.code, message.reason) + if message.message == 'block': + self.block_reject_map[message.data] = RejectResult(message.code, message.reason) + def send_inv(self, obj): mtype = 2 if isinstance(obj, CBlock) else 1 self.conn.send_message(msg_inv([CInv(mtype, obj.sha256)])) @@ -244,6 +265,15 @@ class TestManager(object): if outcome is None: if c.cb.bestblockhash != self.connections[0].cb.bestblockhash: return False + elif isinstance(outcome, RejectResult): # Check that block was rejected w/ code + if c.cb.bestblockhash == blockhash: + return False + if blockhash not in c.cb.block_reject_map: + print 'Block not in reject map: %064x' % (blockhash) + return False + if not outcome.match(c.cb.block_reject_map[blockhash]): + print 'Block rejected with %s instead of expected %s: %064x' % (c.cb.block_reject_map[blockhash], outcome, blockhash) + return False elif ((c.cb.bestblockhash == blockhash) != outcome): # print c.cb.bestblockhash, blockhash, outcome return False @@ -263,6 +293,15 @@ class TestManager(object): if c.cb.lastInv != self.connections[0].cb.lastInv: # print c.rpc.getrawmempool() return False + elif isinstance(outcome, RejectResult): # Check that tx was rejected w/ code + if txhash in c.cb.lastInv: + return False + if txhash not in c.cb.tx_reject_map: + print 'Tx not in reject map: %064x' % (txhash) + return False + if not outcome.match(c.cb.tx_reject_map[txhash]): + print 'Tx rejected with %s instead of expected %s: %064x' % (c.cb.tx_reject_map[txhash], outcome, txhash) + return False elif ((txhash in c.cb.lastInv) != outcome): # print c.rpc.getrawmempool(), c.cb.lastInv return False diff --git a/qa/rpc-tests/test_framework/coverage.py b/qa/rpc-tests/test_framework/coverage.py index 50f066a85..d21a001b6 100644 --- a/qa/rpc-tests/test_framework/coverage.py +++ b/qa/rpc-tests/test_framework/coverage.py @@ -1,3 +1,9 @@ +#!/usr/bin/env python2 +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# + """ This module contains utilities for doing coverage analysis on the RPC interface. diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index b7d78e74f..ca65fb6e7 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -36,6 +36,7 @@ MY_VERSION = 60001 # past bip-31 for ping/pong MY_SUBVERSION = "/python-mininode-tester:0.0.1/" MAX_INV_SZ = 50000 +MAX_BLOCK_SIZE = 1000000 # Keep our own socket map for asyncore, so that we can track disconnects # ourselves (to workaround an issue with closing an asyncore socket when @@ -751,8 +752,8 @@ class msg_inv(object): class msg_getdata(object): command = "getdata" - def __init__(self): - self.inv = [] + def __init__(self, inv=None): + self.inv = inv if inv != None else [] def deserialize(self, f): self.inv = deser_vector(f, CInv) @@ -905,6 +906,20 @@ class msg_mempool(object): def __repr__(self): return "msg_mempool()" +class msg_sendheaders(object): + command = "sendheaders" + + def __init__(self): + pass + + def deserialize(self, f): + pass + + def serialize(self): + return "" + + def __repr__(self): + return "msg_sendheaders()" # getheaders message has # number of entries @@ -989,33 +1004,37 @@ class msg_reject(object): class NodeConnCB(object): def __init__(self): self.verack_received = False + # deliver_sleep_time is helpful for debugging race conditions in p2p + # tests; it causes message delivery to sleep for the specified time + # before acquiring the global lock and delivering the next message. + self.deliver_sleep_time = None - # Derived classes should call this function once to set the message map - # which associates the derived classes' functions to incoming messages - def create_callback_map(self): - self.cbmap = { - "version": self.on_version, - "verack": self.on_verack, - "addr": self.on_addr, - "alert": self.on_alert, - "inv": self.on_inv, - "getdata": self.on_getdata, - "getblocks": self.on_getblocks, - "tx": self.on_tx, - "block": self.on_block, - "getaddr": self.on_getaddr, - "ping": self.on_ping, - "pong": self.on_pong, - "headers": self.on_headers, - "getheaders": self.on_getheaders, - "reject": self.on_reject, - "mempool": self.on_mempool - } + def set_deliver_sleep_time(self, value): + with mininode_lock: + self.deliver_sleep_time = value + + def get_deliver_sleep_time(self): + with mininode_lock: + return self.deliver_sleep_time + + # Spin until verack message is received from the node. + # Tests may want to use this as a signal that the test can begin. + # This can be called from the testing thread, so it needs to acquire the + # global lock. + def wait_for_verack(self): + while True: + with mininode_lock: + if self.verack_received: + return + time.sleep(0.05) def deliver(self, conn, message): + deliver_sleep = self.get_deliver_sleep_time() + if deliver_sleep is not None: + time.sleep(deliver_sleep) with mininode_lock: try: - self.cbmap[message.command](conn, message) + getattr(self, 'on_' + message.command)(conn, message) except: print "ERROR delivering %s (%s)" % (repr(message), sys.exc_info()[0]) @@ -1084,7 +1103,7 @@ class NodeConn(asyncore.dispatcher): "regtest": "\xfa\xbf\xb5\xda" # regtest } - def __init__(self, dstaddr, dstport, rpc, callback, net="regtest"): + def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", services=1): asyncore.dispatcher.__init__(self, map=mininode_socket_map) self.log = logging.getLogger("NodeConn(%s:%d)" % (dstaddr, dstport)) self.dstaddr = dstaddr @@ -1102,6 +1121,7 @@ class NodeConn(asyncore.dispatcher): # stuff version msg into sendbuf vt = msg_version() + vt.nServices = services vt.addrTo.ip = self.dstaddr vt.addrTo.port = self.dstport vt.addrFrom.ip = "0.0.0.0" diff --git a/qa/rpc-tests/test_framework/netutil.py b/qa/rpc-tests/test_framework/netutil.py index b30a88a4f..50daa8793 100644 --- a/qa/rpc-tests/test_framework/netutil.py +++ b/qa/rpc-tests/test_framework/netutil.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py index 0a78cf6fb..bf5e25fb2 100644 --- a/qa/rpc-tests/test_framework/script.py +++ b/qa/rpc-tests/test_framework/script.py @@ -14,7 +14,8 @@ Functionality to build scripts, as well as SignatureHash(). from __future__ import absolute_import, division, print_function, unicode_literals -from test_framework.mininode import CTransaction, CTxOut, hash256 +from .mininode import CTransaction, CTxOut, hash256 +from binascii import hexlify import sys bchr = chr @@ -24,10 +25,9 @@ if sys.version > '3': bchr = lambda x: bytes([x]) bord = lambda x: x -import copy import struct -from test_framework.bignum import bn2vch +from .bignum import bn2vch MAX_SCRIPT_SIZE = 10000 MAX_SCRIPT_ELEMENT_SIZE = 520 @@ -226,7 +226,7 @@ OP_CHECKMULTISIGVERIFY = CScriptOp(0xaf) # expansion OP_NOP1 = CScriptOp(0xb0) -OP_NOP2 = CScriptOp(0xb1) +OP_CHECKLOCKTIMEVERIFY = CScriptOp(0xb1) OP_NOP3 = CScriptOp(0xb2) OP_NOP4 = CScriptOp(0xb3) OP_NOP5 = CScriptOp(0xb4) @@ -353,7 +353,7 @@ VALID_OPCODES = { OP_CHECKMULTISIGVERIFY, OP_NOP1, - OP_NOP2, + OP_CHECKLOCKTIMEVERIFY, OP_NOP3, OP_NOP4, OP_NOP5, @@ -472,7 +472,7 @@ OPCODE_NAMES.update({ OP_CHECKMULTISIG : 'OP_CHECKMULTISIG', OP_CHECKMULTISIGVERIFY : 'OP_CHECKMULTISIGVERIFY', OP_NOP1 : 'OP_NOP1', - OP_NOP2 : 'OP_NOP2', + OP_CHECKLOCKTIMEVERIFY : 'OP_CHECKLOCKTIMEVERIFY', OP_NOP3 : 'OP_NOP3', OP_NOP4 : 'OP_NOP4', OP_NOP5 : 'OP_NOP5', @@ -591,7 +591,7 @@ OPCODES_BY_NAME = { 'OP_CHECKMULTISIG' : OP_CHECKMULTISIG, 'OP_CHECKMULTISIGVERIFY' : OP_CHECKMULTISIGVERIFY, 'OP_NOP1' : OP_NOP1, - 'OP_NOP2' : OP_NOP2, + 'OP_CHECKLOCKTIMEVERIFY' : OP_CHECKLOCKTIMEVERIFY, 'OP_NOP3' : OP_NOP3, 'OP_NOP4' : OP_NOP4, 'OP_NOP5' : OP_NOP5, @@ -777,7 +777,7 @@ class CScript(bytes): # need to change def _repr(o): if isinstance(o, bytes): - return "x('%s')" % binascii.hexlify(o).decode('utf8') + return "x('%s')" % hexlify(o).decode('utf8') else: return repr(o) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index ae2d91ab6..584f318d0 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -120,7 +120,7 @@ class BitcoinTestFramework(object): if self.options.coveragedir: enable_coverage(self.options.coveragedir) - os.environ['PATH'] = self.options.srcdir+":"+os.environ['PATH'] + os.environ['PATH'] = self.options.srcdir+":"+self.options.srcdir+"/qt:"+os.environ['PATH'] check_json_precision() diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 30dd5de58..8c472a518 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. # @@ -22,6 +22,26 @@ from .authproxy import AuthServiceProxy, JSONRPCException COVERAGE_DIR = None +#Set Mocktime default to OFF. +#MOCKTIME is only needed for scripts that use the +#cached version of the blockchain. If the cached +#version of the blockchain is used without MOCKTIME +#then the mempools will not sync due to IBD. +MOCKTIME = 0 + +def enable_mocktime(): + #For backwared compatibility of the python scripts + #with previous versions of the cache, set MOCKTIME + #to Jan 1, 2014 + (201 * 10 * 60) + global MOCKTIME + MOCKTIME = 1388534400 + (201 * 10 * 60) + +def disable_mocktime(): + global MOCKTIME + MOCKTIME = 0 + +def get_mocktime(): + return MOCKTIME def enable_coverage(dirname): """Maintain a log of which RPC calls are made during testing.""" @@ -67,6 +87,9 @@ def check_json_precision(): if satoshis != 2000000000000003: raise RuntimeError("JSON encode/decode loses precision") +def count_bytes(hex_string): + return len(bytearray.fromhex(hex_string)) + def sync_blocks(rpc_connections, wait=1): """ Wait until everybody has the same block count @@ -99,11 +122,12 @@ def initialize_datadir(dirname, n): if not os.path.isdir(datadir): os.makedirs(datadir) with open(os.path.join(datadir, "bitcoin.conf"), 'w') as f: - f.write("regtest=1\n"); - f.write("rpcuser=rt\n"); - f.write("rpcpassword=rt\n"); - f.write("port="+str(p2p_port(n))+"\n"); - f.write("rpcport="+str(rpc_port(n))+"\n"); + f.write("regtest=1\n") + f.write("rpcuser=rt\n") + f.write("rpcpassword=rt\n") + f.write("port="+str(p2p_port(n))+"\n") + f.write("rpcport="+str(rpc_port(n))+"\n") + f.write("listenonion=0\n") return datadir def initialize_chain(test_dir): @@ -127,7 +151,7 @@ def initialize_chain(test_dir): # Create cache directories, run bitcoinds: for i in range(4): datadir=initialize_datadir("cache", i) - args = [ os.getenv("BITCOIND", "bitcoind"), "-keypool=1", "-datadir="+datadir, "-discover=0" ] + args = [ os.getenv("BITCOIND", "bitcoind"), "-server", "-keypool=1", "-datadir="+datadir, "-discover=0" ] if i > 0: args.append("-connect=127.0.0.1:"+str(p2p_port(0))) bitcoind_processes[i] = subprocess.Popen(args) @@ -151,9 +175,10 @@ def initialize_chain(test_dir): # Create a 200-block-long chain; each of the 4 nodes # gets 25 mature blocks and 25 immature. - # blocks are created with timestamps 10 minutes apart, starting - # at 1 Jan 2014 - block_time = 1388534400 + # blocks are created with timestamps 10 minutes apart + # starting from 2010 minutes in the past + enable_mocktime() + block_time = get_mocktime() - (201 * 10 * 60) for i in range(2): for peer in range(4): for j in range(25): @@ -166,6 +191,7 @@ def initialize_chain(test_dir): # Shut them down, and clean up cache directories: stop_nodes(rpcs) wait_bitcoinds() + disable_mocktime() for i in range(4): os.remove(log_filename("cache", i, "debug.log")) os.remove(log_filename("cache", i, "db.log")) @@ -214,7 +240,7 @@ def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary= datadir = os.path.join(dirname, "node"+str(i)) if binary is None: binary = os.getenv("BITCOIND", "bitcoind") - args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ] + args = [ binary, "-datadir="+datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-mocktime="+str(get_mocktime()) ] if extra_args is not None: args.extend(extra_args) bitcoind_processes[i] = subprocess.Popen(args) devnull = open(os.devnull, "w") @@ -401,3 +427,87 @@ def assert_raises(exc, fun, *args, **kwds): raise AssertionError("Unexpected exception raised: "+type(e).__name__) else: raise AssertionError("No exception raised") + +def assert_is_hex_string(string): + try: + int(string, 16) + except Exception as e: + raise AssertionError( + "Couldn't interpret %r as hexadecimal; raised: %s" % (string, e)) + +def assert_is_hash_string(string, length=64): + if not isinstance(string, basestring): + raise AssertionError("Expected a string, got type %r" % type(string)) + elif length and len(string) != length: + raise AssertionError( + "String of length %d expected; got %d" % (length, len(string))) + elif not re.match('[abcdef0-9]+$', string): + raise AssertionError( + "String %r contains invalid characters for a hash." % string) + +def satoshi_round(amount): + return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) + +def create_confirmed_utxos(fee, node, count): + node.generate(int(0.5*count)+101) + utxos = node.listunspent() + iterations = count - len(utxos) + addr1 = node.getnewaddress() + addr2 = node.getnewaddress() + if iterations <= 0: + return utxos + for i in xrange(iterations): + t = utxos.pop() + inputs = [] + inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) + outputs = {} + send_value = t['amount'] - fee + outputs[addr1] = satoshi_round(send_value/2) + outputs[addr2] = satoshi_round(send_value/2) + raw_tx = node.createrawtransaction(inputs, outputs) + signed_tx = node.signrawtransaction(raw_tx)["hex"] + txid = node.sendrawtransaction(signed_tx) + + while (node.getmempoolinfo()['size'] > 0): + node.generate(1) + + utxos = node.listunspent() + assert(len(utxos) >= count) + return utxos + +def gen_return_txouts(): + # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create + # So we have big transactions (and therefore can't fit very many into each block) + # create one script_pubkey + script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes + for i in xrange (512): + script_pubkey = script_pubkey + "01" + # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change + txouts = "81" + for k in xrange(128): + # add txout value + txouts = txouts + "0000000000000000" + # add length of script_pubkey + txouts = txouts + "fd0402" + # add script_pubkey + txouts = txouts + script_pubkey + return txouts + +def create_lots_of_big_transactions(node, txouts, utxos, fee): + addr = node.getnewaddress() + txids = [] + for i in xrange(len(utxos)): + t = utxos.pop() + inputs = [] + inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) + outputs = {} + send_value = t['amount'] - fee + outputs[addr] = satoshi_round(send_value) + rawtx = node.createrawtransaction(inputs, outputs) + newtx = rawtx[0:92] + newtx = newtx + txouts + newtx = newtx + rawtx[94:] + signresult = node.signrawtransaction(newtx, None, None, "NONE") + txid = node.sendrawtransaction(signresult["hex"], True) + txids.append(txid) + return txids diff --git a/qa/rpc-tests/txn_clone.py b/qa/rpc-tests/txn_clone.py index e8ced0e5b..b132aec4b 100755 --- a/qa/rpc-tests/txn_clone.py +++ b/qa/rpc-tests/txn_clone.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -8,11 +8,7 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.authproxy import AuthServiceProxy, JSONRPCException -from decimal import Decimal from test_framework.util import * -import os -import shutil class TxnMallTest(BitcoinTestFramework): @@ -57,16 +53,10 @@ class TxnMallTest(BitcoinTestFramework): clone_inputs = [{"txid":rawtx1["vin"][0]["txid"],"vout":rawtx1["vin"][0]["vout"]}] clone_outputs = {rawtx1["vout"][0]["scriptPubKey"]["addresses"][0]:rawtx1["vout"][0]["value"], rawtx1["vout"][1]["scriptPubKey"]["addresses"][0]:rawtx1["vout"][1]["value"]} - clone_raw = self.nodes[0].createrawtransaction(clone_inputs, clone_outputs) + clone_locktime = rawtx1["locktime"] + clone_raw = self.nodes[0].createrawtransaction(clone_inputs, clone_outputs, clone_locktime) - # 3 hex manipulations on the clone are required - - # manipulation 1. sequence is at version+#inputs+input+sigstub - posseq = 2*(4+1+36+1) - seqbe = '%08x' % rawtx1["vin"][0]["sequence"] - clone_raw = clone_raw[:posseq] + seqbe[6:8] + seqbe[4:6] + seqbe[2:4] + seqbe[0:2] + clone_raw[posseq + 8:] - - # manipulation 2. createrawtransaction randomizes the order of its outputs, so swap them if necessary. + # createrawtransaction randomizes the order of its outputs, so swap them if necessary. # output 0 is at version+#inputs+input+sigstub+sequence+#outputs # 40 BTC serialized is 00286bee00000000 pos0 = 2*(4+1+36+1+4+1) @@ -78,11 +68,6 @@ class TxnMallTest(BitcoinTestFramework): output1 = clone_raw[pos0 + output_len : pos0 + 2 * output_len] clone_raw = clone_raw[:pos0] + output1 + output0 + clone_raw[pos0 + 2 * output_len:] - # manipulation 3. locktime is after outputs - poslt = pos0 + 2 * output_len - ltbe = '%08x' % rawtx1["locktime"] - clone_raw = clone_raw[:poslt] + ltbe[6:8] + ltbe[4:6] + ltbe[2:4] + ltbe[0:2] + clone_raw[poslt + 8:] - # Use a different signature hash type to sign. This creates an equivalent but malleated clone. # Don't send the clone anywhere yet tx1_clone = self.nodes[0].signrawtransaction(clone_raw, None, None, "ALL|ANYONECANPAY") @@ -136,7 +121,7 @@ class TxnMallTest(BitcoinTestFramework): tx2 = self.nodes[0].gettransaction(txid2) # Verify expected confirmations - assert_equal(tx1["confirmations"], -1) + assert_equal(tx1["confirmations"], -2) assert_equal(tx1_clone["confirmations"], 2) assert_equal(tx2["confirmations"], 1) diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py index 36081127b..8d7f6e505 100755 --- a/qa/rpc-tests/txn_doublespend.py +++ b/qa/rpc-tests/txn_doublespend.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,9 +9,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * -from decimal import Decimal -import os -import shutil class TxnMallTest(BitcoinTestFramework): @@ -99,7 +96,7 @@ class TxnMallTest(BitcoinTestFramework): # Now give doublespend and its parents to miner: self.nodes[2].sendrawtransaction(fund_foo_tx["hex"]) self.nodes[2].sendrawtransaction(fund_bar_tx["hex"]) - self.nodes[2].sendrawtransaction(doublespend["hex"]) + doublespend_txid = self.nodes[2].sendrawtransaction(doublespend["hex"]) # ... mine a block... self.nodes[2].generate(1) @@ -107,14 +104,15 @@ class TxnMallTest(BitcoinTestFramework): connect_nodes(self.nodes[1], 2) self.nodes[2].generate(1) # Mine another block to make sure we sync sync_blocks(self.nodes) + assert_equal(self.nodes[0].gettransaction(doublespend_txid)["confirmations"], 2) # Re-fetch transaction info: tx1 = self.nodes[0].gettransaction(txid1) tx2 = self.nodes[0].gettransaction(txid2) - + # Both transactions should be conflicted - assert_equal(tx1["confirmations"], -1) - assert_equal(tx2["confirmations"], -1) + assert_equal(tx1["confirmations"], -2) + assert_equal(tx2["confirmations"], -2) # Node0's total balance should be starting balance, plus 100BTC for # two more matured blocks, minus 1240 for the double-spend, plus fees (which are diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index f9ec6f429..6cd879e4a 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -1,29 +1,24 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# -# Exercise the wallet. Ported from wallet.sh. -# Does the following: -# a) creates 3 nodes, with an empty chain (no blocks). -# b) node0 mines a block -# c) node1 mines 101 blocks, so now nodes 0 and 1 have 50btc, node2 has none. -# d) node0 sends 21 btc to node2, in two transactions (11 btc, then 10 btc). -# e) node0 mines a block, collects the fee on the second transaction -# f) node1 mines 100 blocks, to mature node0's just-mined block -# g) check that node0 has 100-21, node2 has 21 -# h) node0 should now have 2 unspent outputs; send these to node2 via raw tx broadcast by node1 -# i) have node1 mine a block -# j) check balances - node0 should have 0, node2 should have 100 -# k) test ResendWalletTransactions - create transactions, startup fourth node, make sure it syncs -# - from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * class WalletTest (BitcoinTestFramework): + def check_fee_amount(self, curr_balance, balance_with_fee, fee_per_byte, tx_size): + """Return curr_balance after asserting the fee was in range""" + fee = balance_with_fee - curr_balance + target_fee = fee_per_byte * tx_size + if fee < target_fee: + raise AssertionError("Fee of %s BTC too low! (Should be %s BTC)"%(str(fee), str(target_fee))) + # allow the node's estimation to be at most 2 bytes off + if fee > fee_per_byte * (tx_size + 2): + raise AssertionError("Fee of %s BTC too high! (Should be %s BTC)"%(str(fee), str(target_fee))) + return curr_balance + def setup_chain(self): print("Initializing test directory "+self.options.tmpdir) initialize_chain_clean(self.options.tmpdir, 4) @@ -54,7 +49,6 @@ class WalletTest (BitcoinTestFramework): assert_equal(self.nodes[2].getbalance(), 0) # Send 21 BTC from 0 to 2 using sendtoaddress call. - # Second transaction will be child of first, and will require a fee self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) @@ -86,7 +80,7 @@ class WalletTest (BitcoinTestFramework): inputs = [] outputs = {} inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]}) - outputs[self.nodes[2].getnewaddress("from1")] = utxo["amount"] + outputs[self.nodes[2].getnewaddress("from1")] = utxo["amount"] - 3 raw_tx = self.nodes[0].createrawtransaction(inputs, outputs) txns_to_send.append(self.nodes[0].signrawtransaction(raw_tx)) @@ -99,38 +93,42 @@ class WalletTest (BitcoinTestFramework): self.sync_all() assert_equal(self.nodes[0].getbalance(), 0) - assert_equal(self.nodes[2].getbalance(), 100) - assert_equal(self.nodes[2].getbalance("from1"), 100-21) + assert_equal(self.nodes[2].getbalance(), 94) + assert_equal(self.nodes[2].getbalance("from1"), 94-21) # Send 10 BTC normal address = self.nodes[0].getnewaddress("test") - self.nodes[2].settxfee(Decimal('0.001')) + fee_per_byte = Decimal('0.001') / 1000 + self.nodes[2].settxfee(fee_per_byte * 1000) txid = self.nodes[2].sendtoaddress(address, 10, "", "", False) self.nodes[2].generate(1) self.sync_all() - assert_equal(self.nodes[2].getbalance(), Decimal('89.99900000')) - assert_equal(self.nodes[0].getbalance(), Decimal('10.00000000')) + node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), Decimal('84'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) + assert_equal(self.nodes[0].getbalance(), Decimal('10')) # Send 10 BTC with subtract fee from amount txid = self.nodes[2].sendtoaddress(address, 10, "", "", True) self.nodes[2].generate(1) self.sync_all() - assert_equal(self.nodes[2].getbalance(), Decimal('79.99900000')) - assert_equal(self.nodes[0].getbalance(), Decimal('19.99900000')) + node_2_bal -= Decimal('10') + assert_equal(self.nodes[2].getbalance(), node_2_bal) + node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), Decimal('20'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) # Sendmany 10 BTC txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", []) self.nodes[2].generate(1) self.sync_all() - assert_equal(self.nodes[2].getbalance(), Decimal('69.99800000')) - assert_equal(self.nodes[0].getbalance(), Decimal('29.99900000')) + node_0_bal += Decimal('10') + node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), node_2_bal - Decimal('10'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) + assert_equal(self.nodes[0].getbalance(), node_0_bal) # Sendmany 10 BTC with subtract fee from amount txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [address]) self.nodes[2].generate(1) self.sync_all() - assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000')) - assert_equal(self.nodes[0].getbalance(), Decimal('39.99800000')) + node_2_bal -= Decimal('10') + assert_equal(self.nodes[2].getbalance(), node_2_bal) + node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), node_0_bal + Decimal('10'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid))) # Test ResendWalletTransactions: # Create a couple of transactions, then start up a fourth @@ -145,7 +143,7 @@ class WalletTest (BitcoinTestFramework): sync_blocks(self.nodes) relayed = self.nodes[0].resendwallettransactions() - assert_equal(set(relayed), set([txid1, txid2])) + assert_equal(set(relayed), {txid1, txid2}) sync_mempools(self.nodes) assert(txid1 in self.nodes[3].getrawmempool()) @@ -175,7 +173,7 @@ class WalletTest (BitcoinTestFramework): for uTx in unspentTxs: if uTx['txid'] == zeroValueTxid: found = True - assert_equal(uTx['amount'], Decimal('0.00000000')); + assert_equal(uTx['amount'], Decimal('0')) assert(found) #do some -walletbroadcast tests @@ -187,21 +185,22 @@ class WalletTest (BitcoinTestFramework): connect_nodes_bi(self.nodes,0,2) self.sync_all() - txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2); + txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2) txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) self.nodes[1].generate(1) #mine a block, tx should not be in there self.sync_all() - assert_equal(self.nodes[2].getbalance(), Decimal('59.99800000')); #should not be changed because tx was not broadcasted + assert_equal(self.nodes[2].getbalance(), node_2_bal) #should not be changed because tx was not broadcasted #now broadcast from another node, mine a block, sync, and check the balance self.nodes[1].sendrawtransaction(txObjNotBroadcasted['hex']) self.nodes[1].generate(1) self.sync_all() + node_2_bal += 2 txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) - assert_equal(self.nodes[2].getbalance(), Decimal('61.99800000')); #should not be + assert_equal(self.nodes[2].getbalance(), node_2_bal) #create another tx - txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2); + txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2) #restart the nodes with -walletbroadcast=1 stop_nodes(self.nodes) @@ -214,23 +213,24 @@ class WalletTest (BitcoinTestFramework): self.nodes[0].generate(1) sync_blocks(self.nodes) + node_2_bal += 2 #tx should be added to balance because after restarting the nodes tx should be broadcastet - assert_equal(self.nodes[2].getbalance(), Decimal('63.99800000')); #should not be + assert_equal(self.nodes[2].getbalance(), node_2_bal) #send a tx with value in a string (PR#6380 +) txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "2") txObj = self.nodes[0].gettransaction(txId) - assert_equal(txObj['amount'], Decimal('-2.00000000')) + assert_equal(txObj['amount'], Decimal('-2')) txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "0.0001") txObj = self.nodes[0].gettransaction(txId) - assert_equal(txObj['amount'], Decimal('-0.00010000')) + assert_equal(txObj['amount'], Decimal('-0.0001')) #check if JSON parser can handle scientific notation in strings txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1e-4") txObj = self.nodes[0].gettransaction(txId) - assert_equal(txObj['amount'], Decimal('-0.00010000')) + assert_equal(txObj['amount'], Decimal('-0.0001')) #this should fail errorString = "" @@ -239,7 +239,7 @@ class WalletTest (BitcoinTestFramework): except JSONRPCException,e: errorString = e.error['message'] - assert_equal("Invalid amount" in errorString, True); + assert_equal("Invalid amount" in errorString, True) errorString = "" try: @@ -247,7 +247,31 @@ class WalletTest (BitcoinTestFramework): except JSONRPCException,e: errorString = e.error['message'] - assert_equal("not an integer" in errorString, True); + assert_equal("not an integer" in errorString, True) + + #check if wallet or blochchain maintenance changes the balance + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + balance_nodes = [self.nodes[i].getbalance() for i in range(3)] + + maintenance = [ + '-rescan', + '-reindex', + '-zapwallettxes=1', + '-zapwallettxes=2', + '-salvagewallet', + ] + for m in maintenance: + print "check " + m + stop_nodes(self.nodes) + wait_bitcoinds() + self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + self.sync_all() + assert_equal(balance_nodes, [self.nodes[i].getbalance() for i in range(3)]) if __name__ == '__main__': diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py index da100d7fc..1221a0911 100755 --- a/qa/rpc-tests/walletbackup.py +++ b/qa/rpc-tests/walletbackup.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/zapwallettxes.py b/qa/rpc-tests/zapwallettxes.py index 0ec8ec536..1ee0f79ac 100755 --- a/qa/rpc-tests/zapwallettxes.py +++ b/qa/rpc-tests/zapwallettxes.py @@ -1,5 +1,5 @@ #!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2014-2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py index bcb132321..88532541a 100755 --- a/qa/rpc-tests/zmq_test.py +++ b/qa/rpc-tests/zmq_test.py @@ -11,7 +11,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import * import zmq import binascii -from test_framework.mininode import hash256 try: import http.client as httplib @@ -42,7 +41,7 @@ class ZMQTest (BitcoinTestFramework): def run_test(self): self.sync_all() - genhashes = self.nodes[0].generate(1); + genhashes = self.nodes[0].generate(1) self.sync_all() print "listen..." @@ -58,7 +57,7 @@ class ZMQTest (BitcoinTestFramework): assert_equal(genhashes[0], blkhash) #blockhash from generate must be equal to the hash received over zmq n = 10 - genhashes = self.nodes[1].generate(n); + genhashes = self.nodes[1].generate(n) self.sync_all() zmqHashes = [] @@ -76,7 +75,7 @@ class ZMQTest (BitcoinTestFramework): hashRPC = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.0) self.sync_all() - #now we should receive a zmq msg because the tx was broadcastet + # now we should receive a zmq msg because the tx was broadcast msg = self.zmqSubSocket.recv_multipart() topic = str(msg[0]) body = msg[1] diff --git a/share/rpcuser/README.md b/share/rpcuser/README.md new file mode 100644 index 000000000..7c2c909a4 --- /dev/null +++ b/share/rpcuser/README.md @@ -0,0 +1,11 @@ +RPC Tools +--------------------- + +### [RPCUser](/share/rpcuser) ### + +Create an RPC user login credential. + +Usage: + +./rpcuser.py + diff --git a/share/rpcuser/rpcuser.py b/share/rpcuser/rpcuser.py new file mode 100755 index 000000000..9fd176908 --- /dev/null +++ b/share/rpcuser/rpcuser.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python2 +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import hashlib +import sys +import os +from random import SystemRandom +import base64 +import hmac + +if len(sys.argv) < 2: + sys.stderr.write('Please include username as an argument.\n') + sys.exit(0) + +username = sys.argv[1] + +#This uses os.urandom() underneath +cryptogen = SystemRandom() + +#Create 16 byte hex salt +salt_sequence = [cryptogen.randrange(256) for i in range(16)] +hexseq = list(map(hex, salt_sequence)) +salt = "".join([x[2:] for x in hexseq]) + +#Create 32 byte b64 password +password = base64.urlsafe_b64encode(os.urandom(32)) + +digestmod = hashlib.sha256 + +if sys.version_info.major >= 3: + password = password.decode('utf-8') + digestmod = 'SHA256' + +m = hmac.new(bytearray(salt, 'utf-8'), bytearray(password, 'utf-8'), digestmod) +result = m.hexdigest() + +print("String to be appended to bitcoin.conf:") +print("rpcauth="+username+":"+salt+"$"+result) +print("Your password:\n"+password) diff --git a/src/Makefile.am b/src/Makefile.am index 959eef8a2..0b6578cf4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,6 +28,7 @@ BITCOIN_INCLUDES += -I$(srcdir)/univalue/include LIBBITCOIN_SERVER=libbitcoin_server.a LIBBITCOIN_WALLET=libbitcoin_wallet.a LIBBITCOIN_COMMON=libbitcoin_common.a +LIBBITCOIN_CONSENSUS=libbitcoin_consensus.a LIBBITCOIN_CLI=libbitcoin_cli.a LIBBITCOIN_UTIL=libbitcoin_util.a LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a @@ -47,6 +48,7 @@ EXTRA_LIBRARIES = \ crypto/libbitcoin_crypto.a \ libbitcoin_util.a \ libbitcoin_common.a \ + libbitcoin_consensus.a \ libbitcoin_server.a \ libbitcoin_cli.a if ENABLE_WALLET @@ -59,9 +61,9 @@ endif if BUILD_BITCOIN_LIBS lib_LTLIBRARIES = libbitcoinconsensus.la -LIBBITCOIN_CONSENSUS=libbitcoinconsensus.la +LIBBITCOINCONSENSUS=libbitcoinconsensus.la else -LIBBITCOIN_CONSENSUS= +LIBBITCOINCONSENSUS= endif bin_PROGRAMS = @@ -76,13 +78,11 @@ if BUILD_BITCOIN_UTILS bin_PROGRAMS += bitcoin-cli bitcoin-tx endif -.PHONY: FORCE +.PHONY: FORCE check-symbols check-security # bitcoin core # BITCOIN_CORE_H = \ addrman.h \ alert.h \ - amount.h \ - arith_uint256.h \ base58.h \ bloom.h \ chain.h \ @@ -100,11 +100,8 @@ BITCOIN_CORE_H = \ compat/sanity.h \ compressor.h \ consensus/consensus.h \ - consensus/params.h \ - consensus/validation.h \ core_io.h \ core_memusage.h \ - hash.h \ httprpc.h \ httpserver.h \ init.h \ @@ -116,30 +113,23 @@ BITCOIN_CORE_H = \ memusage.h \ merkleblock.h \ miner.h \ - mruset.h \ net.h \ netbase.h \ noui.h \ policy/fees.h \ policy/policy.h \ + policy/rbf.h \ pow.h \ - primitives/block.h \ - primitives/transaction.h \ protocol.h \ - pubkey.h \ random.h \ reverselock.h \ - rpcclient.h \ - rpcprotocol.h \ - rpcserver.h \ + rpc/client.h \ + rpc/protocol.h \ + rpc/server.h \ scheduler.h \ - script/interpreter.h \ - script/script.h \ - script/script_error.h \ script/sigcache.h \ script/sign.h \ script/standard.h \ - serialize.h \ streams.h \ support/allocators/secure.h \ support/allocators/zeroafterfree.h \ @@ -148,21 +138,18 @@ BITCOIN_CORE_H = \ sync.h \ threadsafety.h \ timedata.h \ - tinyformat.h \ torcontrol.h \ txdb.h \ txmempool.h \ ui_interface.h \ - uint256.h \ undo.h \ util.h \ utilmoneystr.h \ - utilstrencodings.h \ utiltime.h \ validationinterface.h \ - version.h \ wallet/crypter.h \ wallet/db.h \ + wallet/rpcwallet.h \ wallet/wallet.h \ wallet/wallet_ismine.h \ wallet/walletdb.h \ @@ -200,12 +187,12 @@ libbitcoin_server_a_SOURCES = \ policy/policy.cpp \ pow.cpp \ rest.cpp \ - rpcblockchain.cpp \ - rpcmining.cpp \ - rpcmisc.cpp \ - rpcnet.cpp \ - rpcrawtransaction.cpp \ - rpcserver.cpp \ + rpc/blockchain.cpp \ + rpc/mining.cpp \ + rpc/misc.cpp \ + rpc/net.cpp \ + rpc/rawtransaction.cpp \ + rpc/server.cpp \ script/sigcache.cpp \ timedata.cpp \ torcontrol.cpp \ @@ -238,6 +225,7 @@ libbitcoin_wallet_a_SOURCES = \ wallet/wallet.cpp \ wallet/wallet_ismine.cpp \ wallet/walletdb.cpp \ + policy/rbf.cpp \ $(BITCOIN_CORE_H) # crypto primitives library @@ -258,30 +246,57 @@ crypto_libbitcoin_crypto_a_SOURCES = \ crypto/sha512.cpp \ crypto/sha512.h +# consensus: shared between all executables that validate any consensus rules. +libbitcoin_consensus_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_consensus_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +libbitcoin_consensus_a_SOURCES = \ + amount.h \ + arith_uint256.cpp \ + arith_uint256.h \ + consensus/merkle.cpp \ + consensus/merkle.h \ + consensus/params.h \ + consensus/validation.h \ + hash.cpp \ + hash.h \ + prevector.h \ + primitives/block.cpp \ + primitives/block.h \ + primitives/transaction.cpp \ + primitives/transaction.h \ + pubkey.cpp \ + pubkey.h \ + script/bitcoinconsensus.cpp \ + script/interpreter.cpp \ + script/interpreter.h \ + script/script.cpp \ + script/script.h \ + script/script_error.cpp \ + script/script_error.h \ + serialize.h \ + tinyformat.h \ + uint256.cpp \ + uint256.h \ + utilstrencodings.cpp \ + utilstrencodings.h \ + version.h + # common: shared between bitcoind, and bitcoin-qt and non-server tools libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_common_a_SOURCES = \ amount.cpp \ - arith_uint256.cpp \ base58.cpp \ chainparams.cpp \ coins.cpp \ compressor.cpp \ core_read.cpp \ core_write.cpp \ - hash.cpp \ key.cpp \ keystore.cpp \ netbase.cpp \ - primitives/block.cpp \ - primitives/transaction.cpp \ protocol.cpp \ - pubkey.cpp \ scheduler.cpp \ - script/interpreter.cpp \ - script/script.cpp \ - script/script_error.cpp \ script/sign.cpp \ script/standard.cpp \ $(BITCOIN_CORE_H) @@ -299,10 +314,9 @@ libbitcoin_util_a_SOURCES = \ compat/glibcxx_sanity.cpp \ compat/strnlen.cpp \ random.cpp \ - rpcprotocol.cpp \ + rpc/protocol.cpp \ support/cleanse.cpp \ sync.cpp \ - uint256.cpp \ util.cpp \ utilmoneystr.cpp \ utilstrencodings.cpp \ @@ -317,7 +331,7 @@ endif libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_cli_a_SOURCES = \ - rpcclient.cpp \ + rpc/client.cpp \ $(BITCOIN_CORE_H) nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h @@ -338,6 +352,7 @@ bitcoind_LDADD = \ $(LIBBITCOIN_COMMON) \ $(LIBUNIVALUE) \ $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_CONSENSUS) \ $(LIBBITCOIN_CRYPTO) \ $(LIBLEVELDB) \ $(LIBMEMENV) \ @@ -385,6 +400,7 @@ bitcoin_tx_LDADD = \ $(LIBUNIVALUE) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_CONSENSUS) \ $(LIBBITCOIN_CRYPTO) \ $(LIBSECP256K1) @@ -394,20 +410,7 @@ bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) # bitcoinconsensus library # if BUILD_BITCOIN_LIBS include_HEADERS = script/bitcoinconsensus.h -libbitcoinconsensus_la_SOURCES = \ - crypto/hmac_sha512.cpp \ - crypto/ripemd160.cpp \ - crypto/sha1.cpp \ - crypto/sha256.cpp \ - crypto/sha512.cpp \ - hash.cpp \ - primitives/transaction.cpp \ - pubkey.cpp \ - script/bitcoinconsensus.cpp \ - script/interpreter.cpp \ - script/script.cpp \ - uint256.cpp \ - utilstrencodings.cpp +libbitcoinconsensus_la_SOURCES = $(crypto_libbitcoin_crypto_a_SOURCES) $(libbitcoin_consensus_a_SOURCES) if GLIBC_BACK_COMPAT libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp @@ -455,6 +458,18 @@ clean-local: $(AM_V_CXX) $(OBJCXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CXXFLAGS) $(QT_INCLUDES) $(AM_CXXFLAGS) $(PIE_FLAGS) $(CXXFLAGS) -c -o $@ $< +check-symbols: $(bin_PROGRAMS) +if GLIBC_BACK_COMPAT + @echo "Checking glibc back compat..." + $(AM_V_at) READELF=$(READELF) CPPFILT=$(CPPFILT) $(top_srcdir)/contrib/devtools/symbol-check.py < $(bin_PROGRAMS) +endif + +check-security: $(bin_PROGRAMS) +if HARDEN + @echo "Checking binary security..." + $(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(top_srcdir)/contrib/devtools/security-check.py < $(bin_PROGRAMS) +endif + %.pb.cc %.pb.h: %.proto @test -f $(PROTOC) $(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$(abspath $(nRefCount; n++) nFactor *= 2; - if (nFactor > 1 && (GetRandInt(nFactor) != 0)) + if (nFactor > 1 && (RandomInt(nFactor) != 0)) return false; } else { pinfo = Create(addr, source, &nId); @@ -339,12 +340,12 @@ CAddrInfo CAddrMan::Select_(bool newOnly) // Use a 50% chance for choosing between tried and new table entries. if (!newOnly && - (nTried > 0 && (nNew == 0 || GetRandInt(2) == 0))) { + (nTried > 0 && (nNew == 0 || RandomInt(2) == 0))) { // use a tried node double fChanceFactor = 1.0; while (1) { - int nKBucket = GetRandInt(ADDRMAN_TRIED_BUCKET_COUNT); - int nKBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE); + int nKBucket = RandomInt(ADDRMAN_TRIED_BUCKET_COUNT); + int nKBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE); while (vvTried[nKBucket][nKBucketPos] == -1) { nKBucket = (nKBucket + insecure_rand()) % ADDRMAN_TRIED_BUCKET_COUNT; nKBucketPos = (nKBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE; @@ -352,7 +353,7 @@ CAddrInfo CAddrMan::Select_(bool newOnly) int nId = vvTried[nKBucket][nKBucketPos]; assert(mapInfo.count(nId) == 1); CAddrInfo& info = mapInfo[nId]; - if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) + if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) return info; fChanceFactor *= 1.2; } @@ -360,8 +361,8 @@ CAddrInfo CAddrMan::Select_(bool newOnly) // use a new node double fChanceFactor = 1.0; while (1) { - int nUBucket = GetRandInt(ADDRMAN_NEW_BUCKET_COUNT); - int nUBucketPos = GetRandInt(ADDRMAN_BUCKET_SIZE); + int nUBucket = RandomInt(ADDRMAN_NEW_BUCKET_COUNT); + int nUBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE); while (vvNew[nUBucket][nUBucketPos] == -1) { nUBucket = (nUBucket + insecure_rand()) % ADDRMAN_NEW_BUCKET_COUNT; nUBucketPos = (nUBucketPos + insecure_rand()) % ADDRMAN_BUCKET_SIZE; @@ -369,7 +370,7 @@ CAddrInfo CAddrMan::Select_(bool newOnly) int nId = vvNew[nUBucket][nUBucketPos]; assert(mapInfo.count(nId) == 1); CAddrInfo& info = mapInfo[nId]; - if (GetRandInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) + if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) return info; fChanceFactor *= 1.2; } @@ -465,7 +466,7 @@ void CAddrMan::GetAddr_(std::vector& vAddr) if (vAddr.size() >= nNodes) break; - int nRndPos = GetRandInt(vRandom.size() - n) + n; + int nRndPos = RandomInt(vRandom.size() - n) + n; SwapRandom(n, nRndPos); assert(mapInfo.count(vRandom[n]) == 1); @@ -494,3 +495,7 @@ void CAddrMan::Connected_(const CService& addr, int64_t nTime) if (nTime - info.nTime > nUpdateInterval) info.nTime = nTime; } + +int CAddrMan::RandomInt(int nMax){ + return GetRandInt(nMax); +} diff --git a/src/addrman.h b/src/addrman.h index 1123caabf..4f3de8d7c 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -1,4 +1,5 @@ // Copyright (c) 2012 Pieter Wuille +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -175,9 +176,6 @@ private: //! critical section to protect the inner data structures mutable CCriticalSection cs; - //! secret key to randomize bucket select with - uint256 nKey; - //! last used nId int nIdCount; @@ -203,6 +201,8 @@ private: int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]; protected: + //! secret key to randomize bucket select with + uint256 nKey; //! Find an entry. CAddrInfo* Find(const CNetAddr& addr, int *pnId = NULL); @@ -235,6 +235,9 @@ protected: //! Select an address to connect to, if newOnly is set to true, only the new table is selected from. CAddrInfo Select_(bool newOnly); + //! Wraps GetRandInt to allow tests to override RandomInt and make it determinismistic. + virtual int RandomInt(int nMax); + #ifdef DEBUG_ADDRMAN //! Perform consistency check. Returns an error code or zero. int Check_(); @@ -569,11 +572,6 @@ public: Check(); } } - - //! Ensure that bucket placement is always the same for testing purposes. - void MakeDeterministic(){ - nKey.SetNull(); //Do not use outside of tests. - } }; diff --git a/src/alert.cpp b/src/alert.cpp index 91e54a917..eb1cd5e7f 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -138,7 +138,7 @@ bool CAlert::RelayTo(CNode* pnode) const AppliesToMe() || GetAdjustedTime() < nRelayUntil) { - pnode->PushMessage("alert", *this); + pnode->PushMessage(NetMsgType::ALERT, *this); return true; } } diff --git a/src/alert.h b/src/alert.h index 4f9fff918..8cb86e338 100644 --- a/src/alert.h +++ b/src/alert.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/amount.cpp b/src/amount.cpp index b46918198..a3abd8cd8 100644 --- a/src/amount.cpp +++ b/src/amount.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/amount.h b/src/amount.h index a4c7764cd..a48b17d51 100644 --- a/src/amount.h +++ b/src/amount.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -30,7 +30,7 @@ extern const std::string CURRENCY_UNIT; static const CAmount MAX_MONEY = 21000000 * COIN; inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } -/** Type-safe wrapper class to for fee rates +/** Type-safe wrapper class for fee rates * (how much to pay based on transaction size) */ class CFeeRate diff --git a/src/arith_uint256.h b/src/arith_uint256.h index 103c78bb8..ba3d62015 100644 --- a/src/arith_uint256.h +++ b/src/arith_uint256.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/base58.cpp b/src/base58.cpp index c80918505..5e26cf8d4 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/base58.h b/src/base58.h index 90014b949..a3980118a 100644 --- a/src/base58.h +++ b/src/base58.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index f8e3880ea..34980d9ca 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,8 +9,8 @@ #include "chainparamsbase.h" #include "clientversion.h" -#include "rpcclient.h" -#include "rpcprotocol.h" +#include "rpc/client.h" +#include "rpc/protocol.h" #include "util.h" #include "utilstrencodings.h" @@ -26,6 +26,7 @@ using namespace std; +static const char DEFAULT_RPCCONNECT[] = "127.0.0.1"; static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900; std::string HelpMessageCli() @@ -33,11 +34,11 @@ std::string HelpMessageCli() string strUsage; strUsage += HelpMessageGroup(_("Options:")); strUsage += HelpMessageOpt("-?", _("This help message")); - strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf")); + strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME)); strUsage += HelpMessageOpt("-datadir=", _("Specify data directory")); AppendParamsHelpMessages(strUsage); - strUsage += HelpMessageOpt("-rpcconnect=", strprintf(_("Send commands to node running on (default: %s)"), "127.0.0.1")); - strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Connect to JSON-RPC on (default: %u or testnet: %u)"), 8332, 18332)); + strUsage += HelpMessageOpt("-rpcconnect=", strprintf(_("Send commands to node running on (default: %s)"), DEFAULT_RPCCONNECT)); + strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Connect to JSON-RPC on (default: %u or testnet: %u)"), BaseParams(CBaseChainParams::MAIN).RPCPort(), BaseParams(CBaseChainParams::TESTNET).RPCPort())); strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start")); strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcpassword=", _("Password for JSON-RPC connections")); @@ -145,7 +146,7 @@ static void http_request_done(struct evhttp_request *req, void *ctx) UniValue CallRPC(const string& strMethod, const UniValue& params) { - std::string host = GetArg("-rpcconnect", "127.0.0.1"); + std::string host = GetArg("-rpcconnect", DEFAULT_RPCCONNECT); int port = GetArg("-rpcport", BaseParams().RPCPort()); // Create event base diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index aaa2ef128..95d7a085a 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 9ad5a4786..28bc374ac 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,14 +9,13 @@ #include "chainparams.h" #include "clientversion.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "init.h" #include "noui.h" #include "scheduler.h" #include "util.h" #include "httpserver.h" #include "httprpc.h" -#include "rpcserver.h" #include "utilstrencodings.h" #include @@ -156,6 +155,9 @@ bool AppInit(int argc, char* argv[]) #endif SoftSetBoolArg("-server", true); + // Set this early so that parameter interactions go to console + InitLogging(); + InitParameterInteraction(); fRet = AppInit2(threadGroup, scheduler); } catch (const std::exception& e) { diff --git a/src/bloom.cpp b/src/bloom.cpp index de8720659..4e6f0e5d2 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -216,30 +216,54 @@ void CBloomFilter::UpdateEmptyFull() isEmpty = empty; } -CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate) : - b1(nElements * 2, fpRate, 0), b2(nElements * 2, fpRate, 0) +CRollingBloomFilter::CRollingBloomFilter(unsigned int nElements, double fpRate) { - // Implemented using two bloom filters of 2 * nElements each. - // We fill them up, and clear them, staggered, every nElements - // inserted, so at least one always contains the last nElements - // inserted. - nInsertions = 0; - nBloomSize = nElements * 2; - + double logFpRate = log(fpRate); + /* The optimal number of hash functions is log(fpRate) / log(0.5), but + * restrict it to the range 1-50. */ + nHashFuncs = std::max(1, std::min((int)round(logFpRate / log(0.5)), 50)); + /* In this rolling bloom filter, we'll store between 2 and 3 generations of nElements / 2 entries. */ + nEntriesPerGeneration = (nElements + 1) / 2; + uint32_t nMaxElements = nEntriesPerGeneration * 3; + /* The maximum fpRate = pow(1.0 - exp(-nHashFuncs * nMaxElements / nFilterBits), nHashFuncs) + * => pow(fpRate, 1.0 / nHashFuncs) = 1.0 - exp(-nHashFuncs * nMaxElements / nFilterBits) + * => 1.0 - pow(fpRate, 1.0 / nHashFuncs) = exp(-nHashFuncs * nMaxElements / nFilterBits) + * => log(1.0 - pow(fpRate, 1.0 / nHashFuncs)) = -nHashFuncs * nMaxElements / nFilterBits + * => nFilterBits = -nHashFuncs * nMaxElements / log(1.0 - pow(fpRate, 1.0 / nHashFuncs)) + * => nFilterBits = -nHashFuncs * nMaxElements / log(1.0 - exp(logFpRate / nHashFuncs)) + */ + uint32_t nFilterBits = (uint32_t)ceil(-1.0 * nHashFuncs * nMaxElements / log(1.0 - exp(logFpRate / nHashFuncs))); + data.clear(); + /* We store up to 16 'bits' per data element. */ + data.resize((nFilterBits + 15) / 16); reset(); } +/* Similar to CBloomFilter::Hash */ +inline unsigned int CRollingBloomFilter::Hash(unsigned int nHashNum, const std::vector& vDataToHash) const { + return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (data.size() * 16); +} + void CRollingBloomFilter::insert(const std::vector& vKey) { - if (nInsertions == 0) { - b1.clear(); - } else if (nInsertions == nBloomSize / 2) { - b2.clear(); + if (nEntriesThisGeneration == nEntriesPerGeneration) { + nEntriesThisGeneration = 0; + nGeneration++; + if (nGeneration == 4) { + nGeneration = 1; + } + /* Wipe old entries that used this generation number. */ + for (uint32_t p = 0; p < data.size() * 16; p++) { + if (get(p) == nGeneration) { + put(p, 0); + } + } } - b1.insert(vKey); - b2.insert(vKey); - if (++nInsertions == nBloomSize) { - nInsertions = 0; + nEntriesThisGeneration++; + + for (int n = 0; n < nHashFuncs; n++) { + uint32_t h = Hash(n, vKey); + put(h, nGeneration); } } @@ -251,10 +275,13 @@ void CRollingBloomFilter::insert(const uint256& hash) bool CRollingBloomFilter::contains(const std::vector& vKey) const { - if (nInsertions < nBloomSize / 2) { - return b2.contains(vKey); + for (int n = 0; n < nHashFuncs; n++) { + uint32_t h = Hash(n, vKey); + if (get(h) == 0) { + return false; + } } - return b1.contains(vKey); + return true; } bool CRollingBloomFilter::contains(const uint256& hash) const @@ -265,8 +292,10 @@ bool CRollingBloomFilter::contains(const uint256& hash) const void CRollingBloomFilter::reset() { - unsigned int nNewTweak = GetRand(std::numeric_limits::max()); - b1.reset(nNewTweak); - b2.reset(nNewTweak); - nInsertions = 0; + nTweak = GetRand(std::numeric_limits::max()); + nEntriesThisGeneration = 0; + nGeneration = 1; + for (std::vector::iterator it = data.begin(); it != data.end(); it++) { + *it = 0; + } } diff --git a/src/bloom.h b/src/bloom.h index a4dba8cb4..b0ad8b875 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -110,8 +110,11 @@ public: * reset() is provided, which also changes nTweak to decrease the impact of * false-positives. * - * contains(item) will always return true if item was one of the last N things + * contains(item) will always return true if item was one of the last N to 1.5*N * insert()'ed ... but may also return true for items that were not inserted. + * + * It needs around 1.8 bytes per element per factor 0.1 of false positive rate. + * (More accurately: 3/(log(256)*log(2)) * log(1/fpRate) * nElements bytes) */ class CRollingBloomFilter { @@ -129,10 +132,23 @@ public: void reset(); private: - unsigned int nBloomSize; - unsigned int nInsertions; - CBloomFilter b1, b2; + int nEntriesPerGeneration; + int nEntriesThisGeneration; + int nGeneration; + std::vector data; + unsigned int nTweak; + int nHashFuncs; + + unsigned int Hash(unsigned int nHashNum, const std::vector& vDataToHash) const; + + inline int get(uint32_t position) const { + return (data[(position >> 4) % data.size()] >> (2 * (position & 0xF))) & 0x3; + } + + inline void put(uint32_t position, uint32_t val) { + uint32_t& cell = data[(position >> 4) % data.size()]; + cell = (cell & ~(((uint32_t)3) << (2 * (position & 0xF)))) | (val << (2 * (position & 0xF))); + } }; - #endif // BITCOIN_BLOOM_H diff --git a/src/chain.cpp b/src/chain.cpp index 5b8ce076c..32f6480f8 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -51,6 +51,9 @@ CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { } const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { + if (pindex == NULL) { + return NULL; + } if (pindex->nHeight > Height()) pindex = pindex->GetAncestor(Height()); while (pindex && !Contains(pindex)) @@ -107,3 +110,35 @@ void CBlockIndex::BuildSkip() if (pprev) pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); } + +arith_uint256 GetBlockProof(const CBlockIndex& block) +{ + arith_uint256 bnTarget; + bool fNegative; + bool fOverflow; + bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); + if (fNegative || fOverflow || bnTarget == 0) + return 0; + // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 + // as it's too large for a arith_uint256. However, as 2**256 is at least as large + // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, + // or ~bnTarget / (nTarget+1) + 1. + return (~bnTarget / (bnTarget + 1)) + 1; +} + +int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params) +{ + arith_uint256 r; + int sign = 1; + if (to.nChainWork > from.nChainWork) { + r = to.nChainWork - from.nChainWork; + } else { + r = from.nChainWork - to.nChainWork; + sign = -1; + } + r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip); + if (r.bits() > 63) { + return sign * std::numeric_limits::max(); + } + return sign * r.GetLow64(); +} diff --git a/src/chain.h b/src/chain.h index 01be2d6e5..919998356 100644 --- a/src/chain.h +++ b/src/chain.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -282,6 +282,10 @@ public: const CBlockIndex* GetAncestor(int height) const; }; +arith_uint256 GetBlockProof(const CBlockIndex& block); +/** Return the time it would take to redo the work difference between from and to, assuming the current hashrate corresponds to the difficulty at tip, in seconds. */ +int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&); + /** Used to marshal pointers into hashes for db storage. */ class CDiskBlockIndex : public CBlockIndex { diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 5d6d1ef9d..b962f6ac0 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -1,9 +1,10 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "chainparams.h" +#include "consensus/merkle.h" #include "tinyformat.h" #include "util.h" @@ -32,7 +33,7 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi genesis.nVersion = nVersion; genesis.vtx.push_back(txNew); genesis.hashPrevBlock.SetNull(); - genesis.hashMerkleRoot = genesis.ComputeMerkleRoot(); + genesis.hashMerkleRoot = BlockMerkleRoot(genesis); return genesis; } @@ -91,7 +92,6 @@ public: pchMessageStart[3] = 0xd9; vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); nDefaultPort = 8333; - nMaxTipAge = 24 * 60 * 60; nPruneAfterHeight = 100000; genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN); @@ -168,7 +168,6 @@ public: pchMessageStart[3] = 0x07; vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"); nDefaultPort = 18333; - nMaxTipAge = 0x7fffffff; nPruneAfterHeight = 1000; genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN); @@ -178,7 +177,6 @@ public: vFixedSeeds.clear(); vSeeds.clear(); - vSeeds.push_back(CDNSSeedData("alexykot.me", "testnet-seed.alexykot.me")); vSeeds.push_back(CDNSSeedData("bitcoin.petertodd.org", "testnet-seed.bitcoin.petertodd.org")); vSeeds.push_back(CDNSSeedData("bluematt.me", "testnet-seed.bluematt.me")); vSeeds.push_back(CDNSSeedData("bitcoin.schildbach.de", "testnet-seed.bitcoin.schildbach.de")); @@ -232,7 +230,6 @@ public: pchMessageStart[1] = 0xbf; pchMessageStart[2] = 0xb5; pchMessageStart[3] = 0xda; - nMaxTipAge = 24 * 60 * 60; nDefaultPort = 18444; nPruneAfterHeight = 1000; diff --git a/src/chainparams.h b/src/chainparams.h index cb061d596..88bc66676 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -64,8 +64,7 @@ public: bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; } /** Policy: Filter transactions that do not match well-defined patterns */ bool RequireStandard() const { return fRequireStandard; } - int64_t MaxTipAge() const { return nMaxTipAge; } - int64_t PruneAfterHeight() const { return nPruneAfterHeight; } + uint64_t PruneAfterHeight() const { return nPruneAfterHeight; } /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } /** In the future use NetworkIDString() for RPC fields */ @@ -84,7 +83,6 @@ protected: //! Raw pub key bytes for the broadcast alert signing key. std::vector vAlertPubKey; int nDefaultPort; - long nMaxTipAge; uint64_t nPruneAfterHeight; std::vector vSeeds; std::vector base58Prefixes[MAX_BASE58_TYPES]; diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index db2dc751f..cb71a8b55 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -65,19 +65,6 @@ public: }; static CBaseRegTestParams regTestParams; -/* - * Unit test - */ -class CBaseUnitTestParams : public CBaseMainParams -{ -public: - CBaseUnitTestParams() - { - strDataDir = "unittest"; - } -}; -static CBaseUnitTestParams unitTestParams; - static CBaseChainParams* pCurrentBaseParams = 0; const CBaseChainParams& BaseParams() @@ -86,18 +73,23 @@ const CBaseChainParams& BaseParams() return *pCurrentBaseParams; } -void SelectBaseParams(const std::string& chain) +CBaseChainParams& BaseParams(const std::string& chain) { if (chain == CBaseChainParams::MAIN) - pCurrentBaseParams = &mainParams; + return mainParams; else if (chain == CBaseChainParams::TESTNET) - pCurrentBaseParams = &testNetParams; + return testNetParams; else if (chain == CBaseChainParams::REGTEST) - pCurrentBaseParams = ®TestParams; + return regTestParams; else throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); } +void SelectBaseParams(const std::string& chain) +{ + pCurrentBaseParams = &BaseParams(chain); +} + std::string ChainNameFromCommandLine() { bool fRegTest = GetBoolArg("-regtest", false); diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index 095c4cbdc..59493afb9 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -42,6 +42,8 @@ void AppendParamsHelpMessages(std::string& strUsage, bool debugHelp=true); */ const CBaseChainParams& BaseParams(); +CBaseChainParams& BaseParams(const std::string& chain); + /** Sets the params returned by Params() to those for the given network. */ void SelectBaseParams(const std::string& chain); diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 423362859..1406e8680 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -8,885 +8,943 @@ * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly. */ static SeedSpec6 pnSeed6_main[] = { - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0x22,0xa8,0x80}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x01,0xca,0x80,0xda}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x02,0x1e,0x00,0xd2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x09,0x60,0xcb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x2d,0x47,0x82}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x2d,0x62,0x8d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x66,0x91,0x44}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x87,0xa0,0x4d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xbd,0x86,0xf6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xc7,0xa4,0x84}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xf9,0x87,0x66}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0x13,0x2c,0x6e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0x16,0xe6,0x08}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0e,0xc8,0xc8,0x91}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xe4,0x00,0xbc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0xe4,0x00,0xc8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x18,0xa8,0x61}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x1c,0x23,0xe3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x5c,0x4c,0xaa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x63,0x40,0x77}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe4,0xa6,0x80}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0xe5,0x2d,0x20}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x08,0x69,0x80}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x10,0x45,0x89}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x5e,0x62,0x60}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x66,0x76,0x07}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x76,0xa6,0xe4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x7a,0x85,0x31}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xa6,0x61,0xa2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xd5,0xeb,0xf2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xe2,0x6b,0x40}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xe4,0xc0,0xab}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1b,0x8c,0x85,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x29,0x28,0x19}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x2b,0x65,0x3b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xb8,0xc3,0xb5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xc1,0x8b,0x42}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xc8,0x46,0x66}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xcd,0x0a,0x97}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2a,0x03,0x6a,0xe3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2a,0x3c,0x85,0x6a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x38,0x55,0xe7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x38,0x66,0xe4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4f,0x82,0xeb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcc,0x3d}, 11101}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x26,0xeb,0xe5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x3b,0x02,0x4a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x65,0x84,0x25}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x65,0xa8,0x32}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa3,0x4c,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x02,0x91,0xc9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x16,0x8e,0xd6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x35,0xac,0xc5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xbd,0xa1,0xa4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xe6,0x8c,0xa6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xe7,0x03,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0xff,0x50,0x67}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0e,0xca,0xe6,0x31}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x12,0x55,0x0b,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x5b,0x61,0x19}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x5e,0x64,0x7a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x17,0x5f,0x63,0x84}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x73,0x08,0xce}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x7f,0x80,0xbf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0x9a,0xb2,0x19}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xcf,0x67,0x2b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xcf,0x68,0x69}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xd2,0xe6,0x96}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xe0,0x12,0x54}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x18,0xf6,0xa8,0x6a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1b,0xfe,0x40,0x2f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x06,0x47,0x7b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x06,0x47,0x7c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x0e,0x86,0x0d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x1e,0x24,0xdc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xa4,0x06,0x68}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xaa,0x6a,0xcb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xb9,0x86,0xc9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xcc,0x80,0x63}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0xcc,0x80,0xdb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x01,0xdb,0x58}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x61,0x84,0x6d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x78,0xa0,0x37}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x78,0xa9,0x7b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0x8b,0x20,0x2e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x25,0xdd,0xa3,0xda}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x26,0x82,0xc0,0x48}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x29,0x4b,0x60,0x50}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x03,0x00,0x31}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x21,0x48,0xb9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x21,0x60,0x81}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x38,0x04,0x3f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4f,0x00,0x7f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4f,0x50,0x66}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4f,0x61,0x1e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2d,0x4f,0x84,0xdb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x15,0x61,0x87}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xcd,0x43}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1c,0xce,0xbc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x1d,0x14,0xd1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x32,0xea,0xb3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0x65,0xa0,0xa8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa6,0xa1,0x23}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xa6,0xa1,0x67}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xb6,0x84,0x64}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xdf,0x24,0x5e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xda,0xe3,0x5c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe2,0x6d,0x14}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe3,0x42,0x84}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe3,0x42,0x8a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xa5,0x9a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xa5,0x9b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xe5,0xee,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xea,0x68,0x30}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xef,0x6b,0x4a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xf9,0x27,0x64}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xfa,0x62,0x6c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xf4,0x00,0x8a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x2e,0xfe,0x48,0xc3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x05,0x0d,0x2c}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x07,0x25,0x72}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x51,0x35,0x97}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x73,0x2b,0xfd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x14,0x57}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x74,0x21,0x5c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x7d,0xa7,0xf5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x8f,0x09,0x33}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0xbc,0xc0,0x85}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0x4d,0xa2,0x4c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0x99,0x61,0x6d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa5,0xc0,0x7d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x60,0x69,0x55}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3b,0xa7,0xc4,0x87}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3c,0x1d,0xe3,0xa3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x1e,0x25,0x67}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x27,0x69,0x3c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x32,0x6a,0x28,0xe7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0x1d,0x00,0x25}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x34,0x4c,0xc0,0xf6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0x98,0xc0,0xb3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xa9,0x40,0xae}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xaf,0xa0,0x16}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x36,0xc7,0x80,0x00}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0x60,0xab,0x81}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3a,0xa1,0xee,0x39}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3c,0xfb,0xc3,0xdd}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3d,0x23,0xe1,0x13}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x2b,0x82,0xb2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x6d,0x31,0x1a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xca,0x00,0x61}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0x42,0xe3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0xc0,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x4a,0x62,0xcd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x9c,0xc1,0x64}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x41,0x27,0x0c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x6b,0xc8,0x1e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0x85,0xc2,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xb5,0xee,0xba}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xb7,0x16,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0x55,0x78}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xd2,0xa2,0x59}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x3e,0xee,0x22,0x7d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x19,0xab,0x49}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x1b,0xa6,0x1e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x35,0x89,0x65}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x47,0x48,0x2c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x53,0xe1,0x92}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x79,0x03,0xa3}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xcb,0x66,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0xe5,0x8e,0x30}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x60,0xc1,0xa5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x1e,0x03,0x07}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0x5e,0x83,0x3b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x41,0xbc,0x88,0xe9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x0b,0xa2,0xda}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x17,0xe4,0x85}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x5a,0x89,0x59}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x72,0x21,0x31}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x76,0x85,0xc2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x87,0x0a,0x7e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0x96,0x69,0x4d}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xac,0x0a,0x04}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xc2,0x26,0xfa}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xc2,0x26,0xfd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xd7,0xc0,0x68}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0x3c,0x62,0x73}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xa4,0x23,0x24}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xbf,0xa2,0xf4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xcf,0xc3,0x4d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xdb,0xe9,0x8c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xc2,0x26,0xfe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xe7,0x61,0xac}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x42,0xf0,0xed,0x9b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0x9f,0x0d,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xcd,0x4a,0xce}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xdd,0xc1,0x37}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xe4,0xa2,0xe4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x32,0x43,0xc7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x3e,0x03,0xcb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x43,0xe3,0x48,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x41,0x78,0x35}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x41,0xcd,0xe2}, 9000}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x6a,0x2a,0xbf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x96,0xb5,0xc6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xc4,0xc4,0x6a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0xe0,0xc2,0x51}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x2e,0x05,0xc2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x32,0xab,0xee}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x40,0x2b,0x98}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x41,0x29,0x0d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x5a,0x84,0xc8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x8f,0x01,0xf3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x92,0x62,0xd8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xa5,0xf6,0x26}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xcf,0x06,0x87}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xfb,0xd0,0x1a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x26,0x01,0x65}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x26,0x09,0x42}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x5a,0x02,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0x3a,0xe4,0xe2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc7,0x0b,0xbd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xc7,0xc1,0xca}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xcd,0xe8,0xb5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xec,0xc8,0xa2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x18,0x49,0xba}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x44,0x90,0x04,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x27,0x31,0xc7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x32,0xab,0xcd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x41,0x29,0x15}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x71,0x62,0x3d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x77,0x61,0x27}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0x92,0x46,0x7c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x45,0xc1,0x47,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x2e,0x0a,0xed}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0x50,0xc8,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x46,0xb9,0x61,0x75}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x47,0xfe,0xa0,0x19}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x1c,0xcb,0x05}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x34,0x82,0x6e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x35,0x6f,0x25}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x53,0xc2,0x7a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0x80,0x20,0xa7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xb3,0x88,0x50}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x48,0xeb,0x26,0x46}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x1f,0xab,0x95}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x20,0x89,0x48}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0x89,0x85,0xee}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xb5,0xc0,0x67}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xbe,0x02,0x3c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xc3,0xc0,0x89}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x49,0xde,0x23,0x75}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x39,0xc7,0xb4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x52,0xe9,0xcd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x55,0x42,0x52}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x65,0xe0,0x7f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x71,0x45,0x10}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x7a,0xeb,0x44}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xc1,0x44,0x8d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xd0,0xa4,0xdb}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x64,0x25,0x7a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x91,0x95,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0xa8,0x22,0x14}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x14,0x2c,0xf0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x64,0x46,0x11}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xa8,0x03,0xef}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xba,0x8c,0x67}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x5c,0x44,0xdd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x6d,0x65,0x8e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x6e,0x0b,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xf2,0x6c,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2e,0x60,0x96}, 9020}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x32,0x2c,0xc1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x48,0x3c,0x53}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0x50,0xea,0x74}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4a,0xcf,0xe9,0xc1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x70,0xe9,0x80}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x76,0xa6,0xc5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x8c,0x00,0xf1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0x9f,0xf0,0x42}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4b,0xae,0x05,0x1a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x48,0xa0,0xfc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x48,0xa0,0xfe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x4a,0xaa,0x70}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0x4f,0xc9,0x36}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xaf,0xa6,0xa4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4c,0xb3,0x69,0x1b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0x44,0x25,0xc8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xea,0x31,0xc4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4d,0xf7,0xe5,0x5d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x18,0x48,0x4e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x2f,0x20,0x93}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x54,0x64,0x5f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x79,0x45,0x17}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0x81,0xa7,0x05}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4e,0xc1,0x60,0x9b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x13,0x25,0xb3}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x84,0xe6,0x90}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x85,0x2b,0x3f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa0,0x4c,0x99}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa9,0x22,0x18}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xbc,0x07,0x4e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xd9,0xe2,0x19}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xdf,0x64,0xb3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xf0,0x81,0xdd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x01,0xad,0xf3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0x86,0xc9,0x42}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x4f,0xa9,0x23,0xeb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x39,0xe3,0x0e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x40,0x41,0x57}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x56,0x5c,0x46}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x64,0xcb,0x97}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0x65,0x20,0x79}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xa1,0xb2,0x49}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x50,0xf0,0x81,0xaa}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x07,0x0b,0x32}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x07,0x10,0x11}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x42,0x6f,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x50,0x09,0x47}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x8c,0x2b,0x8a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xab,0x22,0x25}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xae,0xf7,0x32}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xb5,0x9b,0x35}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xb8,0x05,0xfd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xbb,0x45,0x82}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xe6,0x03,0x54}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x2a,0x80,0x33}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x4a,0xe2,0x15}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x8e,0x4b,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x07,0x0b,0x37}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x11,0x11,0x28}, 9333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x1e,0x27,0x53}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x5a,0x24,0x07}, 9444}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0x88,0xe0,0x4d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xa2,0xe7,0xd3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xb8,0x00,0x8f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x51,0xc6,0x80,0x56}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x0b,0x21,0xe5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x4f,0x80,0x86}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x76,0xe9,0x6f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0x87,0x8b,0x1e}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc7,0x66,0x0a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xc8,0xcd,0x1e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x6a,0x11}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x6c,0x15}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x80,0x23}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xee,0x7c,0x29}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xf2,0x00,0xf5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x4c,0x7b,0x6e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x52,0xdd,0x6c,0x1b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x89,0x29,0x03}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x8e,0xc5,0xa8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x8f,0x82,0x13}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0x96,0x09,0xc4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa2,0xc4,0xc0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xa2,0xea,0xe0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xaa,0x68,0x5b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xb7,0x11,0xbf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xe3,0xad,0x53}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xe6,0x05,0x0f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xe9,0x69,0x97}, 443}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xf6,0x4b,0x08}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xfa,0x85,0x9e}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x53,0xff,0x42,0x76}, 8334}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x02,0x22,0x68}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2d,0x62,0x5b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2f,0xa1,0x96}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd4,0xc0,0x83}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd7,0xa9,0x65}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xee,0x8c,0xb0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xf5,0x47,0x1f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x11,0x04,0xd4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x18,0x45,0x3b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2a,0xc1,0x06}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x2d,0x62,0x57}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0x36,0x80,0x0b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd4,0xc8,0x18}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xd7,0xc6,0x6d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x54,0xe6,0x04,0xb1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x5f,0xe4,0x53}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x5f,0xe4,0x7b}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x72,0x80,0x86}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0x9f,0xed,0xbf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xa6,0x82,0xbd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xc7,0x04,0xe4}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x42,0xa8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0xc3,0xd2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xe5,0x00,0x49}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x15,0x60,0x2d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x30,0x2a,0xc7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x51,0x8f,0x52}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x51,0xfb,0x48}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x68,0x18,0xb9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x68,0xa8,0x68}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x75,0xea,0x47}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x76,0x60,0xc5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x91,0x0c,0x39}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x9f,0xaa,0xbe}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x96,0xa8,0xa0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x00,0x4f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd0,0x00,0x95}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xd6,0x93,0xa2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x55,0xf3,0xa8,0x04}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x56,0x01,0x00,0x12}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x4f,0x4d,0x6a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0x5b,0x9c,0x6e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x57,0xec,0xc4,0xde}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x55,0x4b,0x98}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x57,0x01,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x57,0x5c,0x66}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x59,0x45,0xca}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0x61,0x48,0xe5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xa4,0x75,0x63}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xc6,0x20,0x83}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xca,0xe6,0x57}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd6,0xc1,0x9a}, 8343}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x58,0xd6,0xc2,0xe2}, 8343}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x01,0x0b,0x20}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x24,0xeb,0x6c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x43,0x60,0x02}, 15321}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x62,0x10,0x29}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x6c,0x48,0xc3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x9c,0x23,0x9d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xa3,0xe3,0x1c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xd4,0x21,0xed}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xd4,0xa0,0xa5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xe7,0x60,0x53}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xf8,0xa4,0x40}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5a,0x95,0xc1,0xc7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x4d,0xef,0xf5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x6a,0xc2,0x61}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x0a,0x9b,0x58}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0x2e,0x65,0x2c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xa3,0xe0,0xd4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xae,0xf8,0x14}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xca,0xe7,0xc6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x59,0xd4,0x4b,0x06}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5a,0x95,0x26,0xac}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5a,0xa9,0x6a,0x8b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x40,0x65,0x96}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x41,0xc4,0xb3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x79,0x50,0x11}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x7e,0x4d,0x4d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x86,0x26,0xc3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x9c,0x61,0xb5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x91,0x4c,0x9c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0x98,0x96,0x23}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc0,0x89,0x11}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc4,0xaa,0x6e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xc5,0x2c,0x85}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xcf,0x44,0x90}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd1,0x4d,0x65}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd2,0x69,0x1c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd3,0x66,0x65}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd3,0x6a,0x22}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xd6,0xc8,0xcd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdc,0x83,0xf2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdc,0xa3,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe9,0x17,0x23}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x0d,0x60,0x5d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x0e,0x4a,0x72}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xdc,0x2b,0x92}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xde,0x47,0x59}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe0,0x8c,0xf2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5b,0xe5,0x4c,0x0e}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x1b,0x07,0xd1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xdd,0xe4,0x0d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xff,0xcf,0x49}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x48,0xa7,0x94}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x4a,0xa3,0xea}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x7b,0xae,0x42}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x98,0xa6,0x1d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xb5,0x2d,0xbc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x13,0x0c,0xf4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0x33,0xa7,0x58}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5c,0xf7,0xe5,0xa3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x54,0x72,0x6a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0x71,0x24,0xac}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5d,0xbc,0xe0,0xfd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0x4b,0xef,0x45}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xbe,0xe3,0x70}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xc6,0x87,0x1d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xd6,0x02,0x4a}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xe0,0xa2,0x41}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xe2,0x6b,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf2,0xc6,0xa1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x1f,0x0a,0xd1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x41,0x48,0xf4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x54,0xa2,0x5f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x5a,0x8b,0x2e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xb7,0x31,0x1b}, 8005}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd7,0x2f,0x85}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x17,0x43,0x55}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x2c,0xa6,0xbe}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x5d,0xe1,0x4a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x1a,0x00,0x22}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0x1b,0xe1,0x66}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xe5,0x75,0xe5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xf9,0x44,0x7d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xff,0x05,0x9b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0x65,0xf0,0x72}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xec,0xc6,0xfd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5e,0xf2,0xe5,0x9e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x54,0x8a,0x63}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x5f,0xa8,0x57}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x6e,0xea,0x5d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0x82,0x09,0xc8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xa5,0xa8,0xa8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xaa,0xeb,0xfe}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd3,0x82,0x9a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x2e,0x44,0x68}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x60,0x7f,0xca,0x94}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x61,0x4c,0xab,0x23}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x62,0xa0,0xa0,0x43}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0x7e,0xc5,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x63,0xc6,0xad,0x01}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x65,0x64,0xae,0x8a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x65,0xfb,0xcb,0x06}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x03,0x3c,0x3d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0x1e,0x2a,0xbd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x65,0xa4,0xc9,0xd0}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x67,0xe0,0xa5,0x30}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x24,0x53,0xe9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x25,0x81,0x16}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x36,0xc0,0xfb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x80,0xe1,0xdf}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x80,0xe4,0xfc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x80,0xe6,0xb9}, 8334}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x82,0xa1,0x2f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x83,0x21,0x3c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x8f,0x00,0x9c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x9c,0x6f,0x48}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xa7,0x6f,0x54}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xc1,0x28,0xf8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xc5,0x07,0xae}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xc5,0x08,0xfa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xdf,0x01,0x85}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xec,0x61,0x8c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x83,0xc0,0x5e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0x9b,0x2d,0xc9}, 8334}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xc2,0x1c,0xc3}, 8663}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xd3,0x01,0x1b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xdd,0x26,0xb1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xec,0x09,0x4f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xec,0x81,0xb2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xec,0xba,0xf9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xec,0xc2,0x0f}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xee,0x80,0xd6}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x68,0xee,0x82,0xb6}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0x26,0xea,0x54}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xb9,0x24,0xcc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6a,0xb9,0x26,0x43}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x06,0x04,0x91}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x02,0x06}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x96,0x28,0xea}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0x9b,0x6c,0x82}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xa1,0xb6,0x73}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0x42,0xe7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xbe,0x80,0xe2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xaa,0x0d,0xb8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xb5,0xfa,0xd8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xbf,0x65,0x6f}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6b,0xbf,0x6a,0x73}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x10,0x02,0x3d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0x46,0x04,0xa8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xa2,0x23,0xc4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xa3,0xeb,0xef}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xbe,0xc4,0xdc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xbf,0x27,0x3c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0x3b,0x0c,0xa3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6c,0xa1,0x81,0xf7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xc1,0xa0,0x8c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xc5,0x0d,0x36}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xe6,0x07,0xf8}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xea,0x6a,0xbf}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xee,0x51,0x52}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x72,0x4c,0x93,0x1b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x1c,0xe0,0x7f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x44,0x6e,0x52}, 18333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x61,0x4f,0xda}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0xbd,0xcf,0xc5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xe4,0x60,0xe9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x78,0x93,0xb2,0x51}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0x29,0x7b,0x05}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x79,0x43,0x05,0xe6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7a,0x6b,0x8f,0x6e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0x02,0xaa,0x62}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0x6e,0x41,0x5e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xc1,0x8b,0x13}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7d,0xef,0xa0,0x29}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x65,0xa2,0xc1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xec,0x89,0x50}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x6d,0xfb,0xa1,0x79}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x70,0x41,0xe7,0xe2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x46,0xa6,0x39}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x73,0x9f,0x2a,0x50}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x75,0x12,0x49,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x43,0xc9,0x28}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x64,0x56,0xf6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x76,0x6e,0x68,0x98}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x77,0xe0,0x40,0x8d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x78,0x37,0xc1,0x88}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7a,0x6a,0xa9,0xb2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xcb,0xae,0x0f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7b,0xff,0xe8,0x5e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7c,0x94,0xa5,0xa5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x7c,0xe8,0x8d,0x1f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x1e,0x5c,0x45}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x27,0x8d,0xb6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x54,0xa7,0x14}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x6f,0x49,0x0a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x8c,0xe5,0x49}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xaf,0xc3,0x1f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0x6b,0x3f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0xc0,0x99}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x7f,0x26,0xc3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x8c,0xe0,0xa2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xc7,0x65,0x68}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xe9,0xe0,0x23}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0xfd,0x03,0xc1}, 20020}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x81,0x7b,0x07,0x07}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0x59,0xa0,0xea}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0x48,0x8b,0xa4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x83,0xbf,0x70,0x62}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x85,0x01,0x86,0xa2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0x13,0x84,0x35}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0xe2,0x22,0x2a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x29,0x02,0xac}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0xff,0x80,0xcc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8e,0xd9,0x0c,0x6a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8f,0xd7,0x81,0x7e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xb4,0xe4,0x8a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xb9,0x90,0xd5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x82,0xff,0x49,0xcf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x85,0xda,0xe9,0x0b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x86,0xf9,0x80,0x17}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x88,0x9f,0xea,0xea}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x89,0x74,0xa0,0xb0}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0xa2,0x02,0x91}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8b,0xa2,0x17,0x75}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0x86,0x45,0xfd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x8d,0xff,0xa2,0xd7}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x90,0x7a,0xa3,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x91,0x83,0x03,0x36}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x91,0xff,0x04,0x5e}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x92,0x00,0x20,0x65}, 8337}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x93,0xe5,0x0d,0xc7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0x85,0xf4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0xa2,0xbb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x93,0x53,0x48,0x5b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x94,0x67,0x1c,0x44}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0x05,0x20,0x66}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x95,0xd2,0xa4,0xc3}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x96,0x65,0xa3,0xf1}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x97,0xec,0x0b,0xbd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x99,0x79,0x42,0xd3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9a,0x14,0x02,0x8b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0xfd,0x17,0x84}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x98,0x03,0x88,0x38}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9a,0x14,0xd0,0x19}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9e,0xb5,0x68,0x95}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9f,0xfd,0x60,0xe2}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa0,0x24,0x82,0xb4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x01,0xe9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x04,0x7d}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd1,0x6a,0x7b}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xd2,0xc6,0xb8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xda,0x41,0x79}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xde,0xa1,0x31}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x84,0x06}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf3,0x84,0x3a}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf8,0x63,0xa4}, 53011}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xf8,0x66,0x75}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa3,0x9e,0x23,0x6e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa4,0x0f,0x0a,0xbd}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa4,0x28,0x86,0xab}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa2,0xfb,0x6c,0x35}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa3,0x2c,0x02,0x30}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa3,0x9e,0x24,0x11}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa6,0xe6,0x47,0x43}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0xa0,0xa1,0xc7}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x67,0xc3,0xfa}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x90,0x1b,0x70}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x9e,0x81,0x1d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaa,0x4b,0xa2,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0x5a,0x63,0xae}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0xf5,0x05,0x9c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x17,0xa6,0x2f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0xa0,0x24,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa7,0xa0,0xa9,0x5c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa8,0x5d,0x81,0xdc}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa9,0x37,0x63,0x54}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa9,0xe4,0x42,0x2b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xac,0x09,0xa9,0xf2}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x20,0x0b,0xc2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0x22,0xcb,0x4c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xab,0x01,0x34}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xaf,0x88,0x0d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xe6,0xe4,0x8b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf7,0xc1,0x46}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x31,0x84,0x1c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x34,0xca,0x48}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x35,0x4c,0x57}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x6d,0x21,0x1c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x1c,0x0c,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x23,0xb6,0xd6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x21,0x71}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x21,0x79}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x3a,0x60,0xad}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x79,0x4c,0x54}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xe6,0xe4,0x88}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xf6,0x6b,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xad,0xfe,0xeb,0x22}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x00,0x80,0xde}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x19,0x82,0x94}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xae,0x32,0x40,0x65}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xaf,0x8c,0xe8,0x8d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x24,0x25,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x2e,0x09,0x60}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb0,0x7c,0x6e,0x1b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb1,0x27,0x10,0x66}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x11,0xad,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x05,0xf8}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x46,0x10}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0x6f,0x1a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4c,0xa9,0x3b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4f,0x83,0x20}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa2,0xc7,0xd8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xaf,0x86,0x23}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xf8,0x6f,0x04}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x01,0xaa}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x3e,0xcb,0xb9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0x4f,0xa0,0x76}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xa9,0xce,0xf4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xc1,0xea,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xc7,0x60,0x6c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x12,0x60}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xfe,0x22,0xa1}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb3,0x2b,0x8f,0x78}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb3,0xd0,0x9c,0xc6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb4,0xc8,0x80,0x3a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb7,0x4e,0xa9,0x6c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb7,0x60,0x60,0x98}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x44,0x02,0x2e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x49,0xa0,0xa0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x5e,0xe3,0x3a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x98,0x44,0xa3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x07,0x23,0x72}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x1c,0x4c,0xb3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x1f,0xa0,0xca}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x2d,0xc0,0x81}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x42,0x8c,0x0f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xba,0x02,0xa7,0x17}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xba,0xdc,0x65,0x8e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x1a,0x05,0x21}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x4b,0x88,0x92}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x78,0xc2,0x8c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x79,0x05,0x96}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x00,0x72}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb2,0xff,0x29,0x7b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb4,0xd2,0x22,0x3a}, 9801}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb6,0x5c,0xe2,0xd4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb6,0xab,0xf6,0x8e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x17,0x08,0x09}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x3a,0xa2,0x23}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb8,0x9a,0x09,0xaa}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x08,0xee,0xa5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x18,0x61,0x0b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x1f,0x89,0x8b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x26,0x2c,0x40}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x35,0x80,0xb4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x35,0x81,0xf4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x4d,0x81,0x77}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x4d,0x81,0x9c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xb9,0x52,0xcb,0x5c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x14,0x61,0x12}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x7e,0x08,0x0e}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x8a,0x21,0xef}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa6,0x00,0x52}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0x9b,0x88,0x46}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xa6,0xe5,0x70}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xb6,0x6c,0x81}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xbf,0x61,0xd0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xe2,0xc6,0x66}, 8001}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x09,0xd9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x4b,0x8f,0x90}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x8b,0x66,0x92}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbf,0xed,0x40,0x1c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x03,0x83,0x3d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x63,0xe1,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x6e,0xa0,0x7a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xe2,0xe1,0xae}, 8010}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xf2,0xab,0x08}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbc,0xf3,0x04,0x8b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x09,0xea}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x0a,0x0a,0x93}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x51,0xa0,0xb8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xbe,0x55,0xc9,0x25}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x22,0xe3,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x4d,0xbd,0xc8}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x7c,0xe0,0x07}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0x92,0x89,0x01}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xb7,0xc6,0xcc}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xcb,0xe4,0x47}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc0,0xce,0xca,0x14}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x00,0x6d,0x03}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x0c,0xee,0xcc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x5b,0xc8,0x55}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xea,0xe1,0x9c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x06,0xe9,0x26}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x3f,0x8f,0x88}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x7e,0x64,0xf6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x86,0x63,0xc3}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9f,0x6f,0x62}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x9f,0xe2,0x8b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x29,0xe5,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x29,0xe5,0x9c}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x31,0x2b,0xdb}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0x93,0x47,0x78}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xb3,0x41,0xe9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xb7,0x63,0x2e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xc0,0x25,0x87}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc1,0xea,0xe0,0xc3}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0x3a,0x6c,0xd5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0xbb,0x60,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc2,0xff,0x1f,0x3b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x24,0x06,0x65}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0x3a,0xee,0xf3}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xc5,0xaf,0xbe}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x30,0xc7,0x6c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x39,0xd0,0x86}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc3,0xef,0x01,0x42}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x30,0xc4,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x32,0xc0,0xa0}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x39,0xd2,0x1b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x3e,0x6d,0xdf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0x54,0xc3,0xb3}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xa7,0x8c,0x08}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xa7,0x8c,0x12}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x5b,0xad,0xea}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc6,0xcc,0xe0,0x6a}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0x7f,0xe2,0xf5}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xb4,0x86,0x74}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc8,0x07,0x60,0x63}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc9,0xa0,0x6a,0x56}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x37,0x57,0x2d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x44,0xf2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x45,0xe8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x7c,0x6d,0x67}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0x1e,0xc5,0x4d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0x58,0xa0,0x2b}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xc9,0x6e,0x08}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc7,0xe9,0xea,0x5a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xc8,0x74,0x62,0xb9}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xca,0x3c,0x46,0x12}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0x97,0x8c,0x0e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcb,0xdb,0x0e,0xcc}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcd,0x93,0x28,0x3e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xeb,0x27,0xd6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xf4,0x49,0x08}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x0c,0x40,0xe1}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcc,0x70,0xcb,0x34}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcd,0xc8,0xf7,0x95}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xe2,0x8d,0xfd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xcf,0xff,0x2a,0xca}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x35,0xa4,0x13}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x42,0x44,0x7f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x42,0x44,0x82}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x47,0xab,0xe8}, 8341}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x4c,0xc8,0xc8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x28,0x60,0x79}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x7e,0x6b,0xb0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x8d,0x28,0x95}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xbe,0x4b,0x3b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xd0,0x6f,0x8e}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd2,0x36,0x22,0xa4}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd3,0x48,0x42,0xe5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x52,0x62,0xbd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x55,0xc1,0x1f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x6f,0x30,0x29}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd0,0x6f,0x30,0x2d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x22,0xe8,0x48}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x51,0x09,0xdf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x5a,0xe0,0x02}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x5a,0xe0,0x04}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x7e,0x62,0xae}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0x88,0x48,0x45}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xc3,0x04,0x4a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd1,0xc5,0x0d,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd3,0x48,0xe3,0x08}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x33,0x90,0x2a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x70,0x21,0x9d}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x74,0x48,0x3f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x47,0xe9,0x7f}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x7e,0x0e,0x7a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd4,0x9f,0x2c,0x32}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x05,0x24,0x3a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x39,0x21,0x0a}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x42,0xcd,0xc2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x6f,0xc4,0x15}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x7a,0x6b,0x66}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x88,0x4b,0xaf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x88,0x49,0x7d}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x9b,0x03,0xd8}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0x9b,0x07,0x18}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa3,0x40,0x1f}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa3,0x40,0xd0}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa5,0x56,0x88}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xb8,0x08,0x16}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xa7,0x11,0x06}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd5,0xdf,0x8a,0x0d}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x0f,0x4e,0xb6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x37,0x8f,0x9a}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x73,0xeb,0x20}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x7e,0xe2,0xa6}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x91,0x43,0x57}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x26,0x81,0xa4}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0x30,0xa8,0x08}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xa9,0x8d,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xf9,0x5c,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xf5,0xce,0xb5}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xf9,0xcc,0xa1}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd8,0xfa,0x8a,0xe6}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x0b,0xe1,0xbd}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x0c,0x22,0x9e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x0c,0xca,0x21}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x14,0xab,0x2b}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x02,0x47}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x02,0xf2}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x19,0x09,0x4c}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x28,0xe2,0xa9}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x7b,0x62,0x09}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x9b,0x24,0x3e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x01,0x7e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x17,0x0b,0x8a}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x6f,0x42,0x4f}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x9b,0xca,0xbf}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0x9e,0x09,0x66}, 8333}, {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xd9,0xac,0x20,0x12}, 20993}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0x3d,0xc4,0xca}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xda,0xe7,0xcd,0x29}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdc,0xe9,0x4d,0xc8}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0x12,0xe2,0x55}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0xc5,0xcb,0x52}, 8333}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdf,0xff,0xa6,0x8e}, 8333}, + {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xdc,0xf5,0xc4,0x25}, 8333}, {{0x20,0x01,0x12,0x91,0x02,0xbf,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00}, 8333}, - {{0x20,0x01,0x14,0x18,0x01,0x00,0x05,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x16,0xd8,0xdd,0x24,0x00,0x00,0x86,0xc9,0x68,0x1e,0xf9,0x31,0x02,0x56}, 8333}, - {{0x20,0x01,0x19,0xf0,0x16,0x24,0x00,0xe6,0x00,0x00,0x00,0x00,0x57,0x9d,0x94,0x28}, 8333}, - {{0x20,0x01,0x19,0xf0,0x03,0x00,0x13,0x40,0x02,0x25,0x90,0xff,0xfe,0xc9,0x2b,0x6d}, 8333}, - {{0x20,0x01,0x19,0xf0,0x40,0x09,0x14,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64}, 8333}, - {{0x20,0x01,0x1b,0x40,0x50,0x00,0x00,0x2e,0x00,0x00,0x00,0x00,0x3f,0xb0,0x65,0x71}, 8333}, + {{0x20,0x01,0x16,0x20,0x0f,0x00,0x02,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x16,0x20,0x0f,0x00,0x82,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x19,0xf0,0x50,0x00,0x8d,0xe8,0x54,0x00,0x00,0xff,0xfe,0x12,0x55,0xe4}, 8333}, + {{0x20,0x01,0x19,0xf0,0x6c,0x00,0x91,0x03,0x54,0x00,0x00,0xff,0xfe,0x10,0xa8,0xd3}, 8333}, + {{0x20,0x01,0x1b,0x60,0x00,0x03,0x01,0x72,0x14,0x2b,0x6d,0xff,0xfe,0x7a,0x01,0x17}, 8333}, {{0x20,0x01,0x04,0x10,0xa0,0x00,0x40,0x50,0x84,0x63,0x90,0xb0,0xff,0xfb,0x4e,0x58}, 8333}, - {{0x20,0x01,0x04,0x10,0xa0,0x02,0xca,0xfe,0x84,0x63,0x90,0xb0,0xff,0xfb,0x4e,0x58}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0x54,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0x6a,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, + {{0x20,0x01,0x41,0x28,0x61,0x35,0x20,0x10,0x02,0x1e,0x0b,0xff,0xfe,0xe8,0xa3,0xc0}, 8333}, + {{0x20,0x01,0x41,0xd0,0x10,0x08,0x07,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x7c}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0x45,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x01,0x6c,0xd3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x01,0x8b,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0xa3,0x3d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0xb8,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0xaf,0xda,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8200}, + {{0x20,0x01,0x41,0xd0,0x00,0x01,0xb2,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x01,0xc1,0x39,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x01,0xc8,0xd7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0xdd,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0xe2,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x01,0xf5,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x01,0xf7,0xcc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x01,0xff,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0x2f,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x10,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x02,0x37,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8200}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0x3e,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0x86,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x47,0x97,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x53,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x02,0x9c,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x9d,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x02,0xa2,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0xad,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0xb7,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0xee,0x52,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0xa3,0x5a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0xb2,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0xc1,0xd9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0x0c,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x02,0xc9,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x02,0xf1,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x02,0xfa,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x51,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x36}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xa1}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x5f}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0c,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0xf5}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xc0}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0xf2}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x08,0x10,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x08,0x4a,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x7c}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x52,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0xe2}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0x3e,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0x62,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x08,0x67,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x08,0xb7,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x08,0xc3,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x08,0xd2,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x08,0xd5,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xb3,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xbc,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xbe,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x08,0xd9,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x08,0xeb,0x8b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x16,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x13,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x2b,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x3a,0x9c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x49,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x05,0x7b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x5c,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x2d,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x45,0x58,0x00,0x00,0x00,0x00,0x1d,0xf2,0x76,0xd3}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x4a,0xaa,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x63,0x5b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x63,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x41,0xd0,0x00,0x0a,0x6c,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0a,0xf4,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0b,0x08,0x54,0x0b,0x7c,0x0b,0x7c,0x0b,0x7c,0x0b,0x7c}, 8333}, - {{0x20,0x01,0x41,0xd0,0x00,0x0d,0x11,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x20,0x01,0x44,0xb8,0x41,0x16,0x78,0x01,0x42,0x16,0x7e,0xff,0xfe,0x78,0x3f,0xe4}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x08,0x08,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x08,0x0c,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x09,0x0b,0xca,0x02,0x18,0x7d,0xff,0xfe,0x10,0xbe,0x33}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x0f,0x02,0x2d,0x00,0x00,0x00,0x00,0x02,0x12,0x00,0x26}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0a,0xf9,0xcd,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0d,0x20,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x20,0x01,0x41,0xd0,0x00,0x0e,0x02,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x41,0xd0,0xfc,0x8c,0xa2,0x00,0x7a,0x24,0xaf,0xff,0xfe,0x9d,0xc6,0x9b}, 8333}, + {{0x20,0x01,0x41,0xf0,0x00,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07}, 8333}, + {{0x20,0x01,0x41,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x44,0xb8,0x41,0xbd,0x61,0x01,0x14,0x8e,0x40,0x22,0x49,0x50,0xe8,0x61}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x01,0x02,0xf9,0x00,0x00,0x00,0x01,0x10,0x7a,0xa3,0x01}, 8333}, + {{0x20,0x01,0x04,0x70,0x1f,0x0b,0x0a,0xd6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x20,0x01,0x04,0x70,0x1f,0x11,0x12,0xd5,0x00,0x00,0x00,0x00,0x0a,0xe1,0x56,0x11}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x14,0x05,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x20,0x01,0x04,0x70,0x1f,0x14,0x00,0x7d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x15,0x05,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x01,0x04,0x70,0x1f,0x15,0x0d,0xda,0x3d,0x9a,0x3f,0x11,0x9a,0x56,0xed,0x64}, 8333}, - {{0x20,0x01,0x04,0x70,0x00,0x25,0x04,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x04,0x70,0x00,0x25,0x00,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x04,0x70,0x00,0x04,0x02,0x6b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x27,0x00,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x41,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x04,0x70,0x50,0x7d,0x00,0x00,0x6a,0xb5,0x99,0xff,0xfe,0x73,0xac,0x18}, 8333}, + {{0x20,0x01,0x04,0x70,0x58,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2a}, 8333}, {{0x20,0x01,0x04,0x70,0x00,0x5f,0x00,0x5f,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x32}, 8333}, {{0x20,0x01,0x04,0x70,0x00,0x66,0x01,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x04,0x70,0x00,0x67,0x03,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x71}, 8333}, {{0x20,0x01,0x04,0x70,0x6c,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xca,0xfe}, 8333}, - {{0x20,0x01,0x04,0x70,0x00,0x08,0x02,0xe1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43}, 8333}, - {{0x20,0x01,0x04,0x70,0x90,0xa7,0x00,0x96,0x00,0x00,0x00,0x00,0x0a,0xfe,0x60,0x21}, 8333}, + {{0x20,0x01,0x04,0x70,0x00,0x6f,0x03,0x27,0x91,0x3b,0x07,0xfe,0x85,0x45,0xa4,0xf5}, 8333}, + {{0x20,0x01,0x04,0x70,0x7d,0xda,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x04,0x70,0x95,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x20,0x01,0x04,0x70,0xb1,0xd0,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00}, 8333}, - {{0x20,0x01,0x04,0x70,0xc1,0xf2,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01}, 8333}, {{0x20,0x01,0x04,0x70,0xd0,0x0d,0x00,0x00,0x36,0x64,0xa9,0xff,0xfe,0x9a,0x51,0x50}, 8333}, - {{0x20,0x01,0x04,0x70,0xe2,0x50,0x00,0x00,0x02,0x11,0x11,0xff,0xfe,0xb9,0x92,0x4c}, 8333}, - {{0x20,0x01,0x48,0x00,0x78,0x17,0x01,0x01,0xbe,0x76,0x4e,0xff,0xfe,0x04,0xdc,0x52}, 8333}, - {{0x20,0x01,0x48,0x00,0x78,0x19,0x01,0x04,0xbe,0x76,0x4e,0xff,0xfe,0x04,0x78,0x09}, 8333}, + {{0x20,0x01,0x04,0x70,0xfa,0xb7,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x48,0x00,0x78,0x19,0x01,0x04,0xbe,0x76,0x4e,0xff,0xfe,0x05,0xc8,0x28}, 8333}, + {{0x20,0x01,0x48,0x00,0x78,0x19,0x01,0x04,0xbe,0x76,0x4e,0xff,0xfe,0x05,0xc9,0xa0}, 8333}, + {{0x20,0x01,0x48,0x01,0x78,0x19,0x00,0x74,0xb7,0x45,0xb9,0xd5,0xff,0x10,0xa6,0x1a}, 8333}, + {{0x20,0x01,0x48,0x01,0x78,0x19,0x00,0x74,0xb7,0x45,0xb9,0xd5,0xff,0x10,0xaa,0xec}, 8333}, + {{0x20,0x01,0x48,0x01,0x78,0x28,0x01,0x04,0xbe,0x76,0x4e,0xff,0xfe,0x10,0x13,0x25}, 8333}, + {{0x20,0x01,0x48,0x02,0x78,0x00,0x00,0x01,0xbe,0x76,0x4e,0xff,0xfe,0x20,0xf0,0x23}, 8333}, {{0x20,0x01,0x48,0x02,0x78,0x00,0x00,0x02,0x30,0xd7,0x17,0x75,0xff,0x20,0x18,0x58}, 8333}, + {{0x20,0x01,0x48,0x02,0x78,0x00,0x00,0x02,0xbe,0x76,0x4e,0xff,0xfe,0x20,0x6c,0x26}, 8333}, {{0x20,0x01,0x48,0x02,0x78,0x02,0x01,0x01,0xbe,0x76,0x4e,0xff,0xfe,0x20,0x02,0x56}, 8333}, {{0x20,0x01,0x48,0x02,0x78,0x02,0x01,0x03,0xbe,0x76,0x4e,0xff,0xfe,0x20,0x2d,0xe8}, 8333}, {{0x20,0x01,0x48,0x30,0x11,0x00,0x02,0xe8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x4b,0xa0,0xff,0xf7,0x01,0x81,0xde,0xad,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x4b,0x98,0x0d,0xc2,0x00,0x41,0x02,0x16,0x3e,0xff,0xfe,0x56,0xf6,0x59}, 8333}, {{0x20,0x01,0x4b,0xa0,0xff,0xfa,0x00,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x93}, 8333}, - {{0x20,0x01,0x4b,0xa0,0xff,0xff,0x01,0xbe,0x00,0x01,0x10,0x05,0x00,0x00,0x00,0x01}, 8335}, - {{0x20,0x01,0x4c,0x48,0x01,0x10,0x01,0x01,0x02,0x16,0x3e,0xff,0xfe,0x24,0x11,0x62}, 8333}, - {{0x20,0x01,0x4d,0xd0,0xf1,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32}, 8333}, + {{0x20,0x01,0x4b,0xa0,0xff,0xff,0x01,0xbe,0x00,0x01,0x10,0x05,0x00,0x00,0x00,0x01}, 8333}, {{0x20,0x01,0x4d,0xd0,0xff,0x00,0x86,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, {{0x20,0x01,0x4d,0xd0,0xff,0x00,0x9a,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09}, 8333}, - {{0x20,0x01,0x4d,0xd0,0xff,0x00,0x9c,0x55,0xc2,0x3f,0xd5,0xff,0xfe,0x6c,0x7e,0xe9}, 8333}, {{0x20,0x01,0x05,0xc0,0x14,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0xc7}, 8333}, - {{0x20,0x01,0x05,0xc0,0x14,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0x01}, 8333}, - {{0x20,0x01,0x05,0xc0,0x14,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xdf}, 8333}, - {{0x20,0x01,0x05,0xc0,0x15,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, {{0x20,0x01,0x06,0x10,0x1b,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, - {{0x20,0x01,0x06,0x20,0x05,0x00,0xff,0xf0,0xf2,0x1f,0xaf,0xff,0xfe,0xcf,0x91,0xcc}, 8333}, - {{0x20,0x01,0x06,0x7c,0x12,0x20,0x08,0x0c,0x00,0xad,0x8d,0xe2,0xf7,0xe2,0xc7,0x84}, 8333}, - {{0x20,0x01,0x06,0x7c,0x21,0xec,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0b}, 8333}, - {{0x20,0x01,0x06,0xf8,0x12,0x96,0x00,0x00,0x76,0xd4,0x35,0xff,0xfe,0xba,0x1d,0x26}, 8333}, - {{0x20,0x01,0x08,0x40,0xf0,0x00,0x42,0x50,0x3e,0x4a,0x92,0xff,0xfe,0x6d,0x14,0x5f}, 8333}, + {{0x20,0x01,0x06,0x10,0x06,0x00,0x0a,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x20,0x01,0x06,0x7c,0x26,0xb4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, {{0x20,0x01,0x08,0xd8,0x08,0x40,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x39,0x01,0xae}, 8333}, - {{0x20,0x01,0x09,0x80,0xef,0xd8,0x00,0x00,0x00,0x21,0xde,0x4a,0x27,0x09,0x09,0x12}, 8333}, - {{0x20,0x01,0x09,0x81,0x00,0x46,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, - {{0x20,0x01,0x09,0x81,0x93,0x19,0x00,0x02,0x00,0xc0,0x00,0xa8,0x00,0xc8,0x00,0x08}, 8333}, - {{0x20,0x01,0x09,0xd8,0xca,0xfe,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x91}, 8333}, - {{0x20,0x01,0x0a,0xd0,0x00,0x01,0x00,0x01,0x26,0xbe,0x05,0xff,0xfe,0x25,0x95,0x9d}, 8333}, + {{0x20,0x01,0x08,0xd8,0x09,0x65,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x93,0x43}, 8333}, + {{0x20,0x01,0x09,0x80,0x46,0x50,0x00,0x01,0x02,0xe0,0x53,0xff,0xfe,0x13,0x24,0x49}, 8333}, + {{0x20,0x01,0x09,0x81,0x00,0x46,0x00,0x01,0xba,0x27,0xeb,0xff,0xfe,0x5b,0xed,0xee}, 8333}, + {{0x20,0x01,0x09,0xc8,0x53,0xe9,0x36,0x9a,0x02,0x26,0x2d,0xff,0xfe,0x1b,0x74,0x72}, 8333}, + {{0x20,0x01,0x09,0xd8,0xca,0xfe,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x87}, 8333}, + {{0x20,0x01,0x0b,0x10,0x00,0x11,0x00,0x21,0x3e,0x07,0x54,0xff,0xfe,0x48,0x72,0x48}, 8333}, {{0x20,0x01,0x0b,0xa8,0x01,0xf1,0xf3,0x4c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x20,0x01,0x0b,0xc8,0x38,0x1c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x20,0x02,0x17,0x5c,0x4c,0xaa,0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x5c,0x4c,0xaa}, 8333}, - {{0x20,0x02,0x44,0x04,0x82,0xf1,0x00,0x00,0x8d,0x55,0x8f,0xbb,0x15,0xfa,0xf4,0xe0}, 8333}, - {{0x20,0x02,0x44,0x75,0x22,0x33,0x00,0x00,0x02,0x1f,0x5b,0xff,0xfe,0x33,0x9f,0x70}, 8333}, - {{0x20,0x02,0x59,0x6c,0x48,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x59,0x6c,0x48,0xc3}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x23,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x34,0x27,0x01,0x01,0x7a,0x4f,0x08,0xbe,0x26,0x11,0x6e,0x79}, 8333}, + {{0x20,0x01,0x0b,0xc8,0x35,0x05,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x20,0x01,0x0c,0xc0,0xa0,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x1d}, 8333}, + {{0x20,0x01,0x0e,0x42,0x01,0x02,0x12,0x09,0x01,0x53,0x01,0x21,0x00,0x76,0x01,0x71}, 8333}, + {{0x20,0x02,0x17,0xea,0x14,0xeb,0x00,0x00,0x00,0x00,0x00,0x00,0x17,0xea,0x14,0xeb}, 8333}, + {{0x20,0x02,0x02,0xf8,0x2b,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xf8,0x2b,0xc5}, 8333}, + {{0x20,0x02,0x40,0x47,0x48,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x47,0x48,0x2c}, 8333}, + {{0x20,0x02,0x45,0xc3,0x8c,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x45,0xc3,0x8c,0xca}, 8333}, + {{0x20,0x02,0x46,0xbb,0x8a,0x41,0x00,0x00,0x02,0x26,0xb0,0xff,0xfe,0xed,0x5f,0x12}, 8888}, + {{0x20,0x02,0x46,0xbb,0x8c,0x3c,0x00,0x00,0x8d,0x55,0x8f,0xbb,0x15,0xfa,0xf4,0xe0}, 8765}, + {{0x20,0x02,0x4c,0x48,0xa0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x4c,0x48,0xa0,0xfe}, 8333}, + {{0x20,0x02,0x4d,0x44,0x25,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x4d,0x44,0x25,0xc8}, 8333}, + {{0x20,0x02,0x50,0x5f,0xaa,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x5f,0xaa,0xa2}, 8333}, + {{0x20,0x02,0x5b,0xc1,0x79,0x9d,0x00,0x00,0x00,0x00,0x00,0x00,0x5b,0xc1,0x79,0x9d}, 8333}, + {{0x20,0x02,0x6d,0xec,0x54,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x6d,0xec,0x54,0x72}, 8333}, {{0x20,0x02,0x8c,0x6d,0x65,0x21,0x96,0x17,0x12,0xbf,0x48,0xff,0xfe,0xd8,0x17,0x24}, 8333}, - {{0x20,0x02,0xa6,0x46,0x5e,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02}, 8333}, + {{0x20,0x02,0xac,0x52,0x94,0xe2,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x52,0x94,0xe2}, 8333}, + {{0x20,0x02,0xaf,0x7e,0x3e,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x7e,0x3e,0xca}, 8333}, {{0x20,0x02,0xb0,0x09,0x20,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x09,0x20,0xc5}, 8333}, + {{0x20,0x02,0xc0,0x6f,0x39,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x6f,0x39,0xa0}, 8333}, + {{0x20,0x02,0xc2,0x3a,0x73,0x8a,0x00,0x00,0x00,0x00,0x00,0x00,0xc2,0x3a,0x73,0x8a}, 8333}, + {{0x20,0x02,0xc7,0x0f,0x74,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0xc7,0x0f,0x74,0x42}, 8333}, + {{0x20,0x02,0xce,0xc5,0xbe,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0xce,0xc5,0xbe,0x4f}, 8333}, + {{0x20,0x02,0xd1,0x49,0x9e,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0xd1,0x49,0x9e,0x3a}, 8333}, + {{0x20,0x02,0xd9,0x17,0x0c,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0xd9,0x17,0x0c,0xa5}, 8333}, + {{0x24,0x00,0x89,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x50,0x15,0x3f}, 8333}, {{0x24,0x00,0x89,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x82,0x3e}, 8333}, - {{0x24,0x00,0x89,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x70,0xd1,0x64}, 8333}, - {{0x24,0x00,0x89,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x37,0x97,0x61}, 8333}, - {{0x24,0x03,0x42,0x00,0x04,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff}, 8333}, - {{0x24,0x03,0xb8,0x00,0x10,0x00,0x00,0x64,0x04,0x0a,0xe9,0xff,0xfe,0x5f,0x94,0xc1}, 8333}, - {{0x24,0x03,0xb8,0x00,0x10,0x00,0x00,0x64,0x98,0x79,0x17,0xff,0xfe,0x6a,0xa5,0x9f}, 8333}, + {{0x24,0x00,0x89,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xa8,0x19,0x34}, 8333}, + {{0x24,0x00,0x89,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0xc4,0xd6}, 8333}, + {{0x24,0x00,0x89,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xc8,0x42,0x80}, 8333}, + {{0x24,0x00,0x89,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xc8,0x66,0x0f}, 8333}, + {{0x24,0x01,0x18,0x00,0x78,0x00,0x01,0x02,0xbe,0x76,0x4e,0xff,0xfe,0x1c,0x05,0x59}, 8333}, + {{0x24,0x01,0x18,0x00,0x78,0x00,0x01,0x02,0xbe,0x76,0x4e,0xff,0xfe,0x1c,0x0a,0x7d}, 8333}, + {{0x24,0x05,0xaa,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40}, 8333}, {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x59,0xb2}, 8333}, - {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x37,0xa4,0xb1}, 8333}, - {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x56,0x29,0x73}, 8333}, + {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0xbf,0xb6}, 8333}, + {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x88,0xe3}, 8333}, {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x72,0x97}, 8333}, {{0x26,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x84,0x8a,0x6e}, 8333}, {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x6a,0xdf}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0xe2,0x17}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x1b,0x31}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x2f,0xe1}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0xa0,0x3f}, 8333}, + {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0xc4,0xb8}, 8333}, + {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x3b,0x1f,0x76}, 8333}, {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x50,0x5e,0x06}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x56,0xd6,0x45}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0xa3,0xdc}, 8333}, - {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x89,0xa6,0x59}, 8333}, - {{0x26,0x00,0x3c,0x02,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x6f,0x0b}, 8333}, - {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0xf6,0xfb}, 8333}, + {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x61,0x28,0x9b}, 8333}, + {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x69,0x89,0xe9}, 8333}, + {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x84,0xac,0x15}, 8333}, + {{0x26,0x00,0x3c,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x98,0x68,0xbb}, 8333}, + {{0x26,0x00,0x3c,0x02,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0x07,0x13}, 8333}, + {{0x26,0x00,0x3c,0x02,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0xc4,0x9e}, 8333}, + {{0x26,0x00,0x3c,0x02,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x84,0x97,0xd8}, 8333}, + {{0x26,0x00,0x3c,0x02,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xc8,0x8f,0xeb}, 8333}, + {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0xda,0x80}, 8333}, + {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0xc4,0x9b}, 8333}, {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x50,0x5f,0xa7}, 8333}, + {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x67,0x0d,0x2e}, 8333}, {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x18,0x03}, 8333}, - {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x4a,0xc0}, 8333}, - {{0x26,0x01,0x00,0x06,0x48,0x00,0x04,0x7f,0x1e,0x4e,0x1f,0x4d,0x33,0x2c,0x3b,0xf6}, 8333}, - {{0x26,0x01,0x00,0x0d,0x54,0x00,0x0f,0xed,0x8d,0x54,0xc1,0xe8,0x7e,0xd7,0xd4,0x5e}, 8333}, - {{0x26,0x02,0x01,0x00,0x4b,0x8f,0x6d,0x2a,0x02,0x0c,0x29,0xff,0xfe,0xaf,0xc4,0xc2}, 8333}, + {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xc8,0x4b,0xbe}, 8333}, + {{0x26,0x00,0x3c,0x03,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xe4,0x4e,0x16}, 8333}, + {{0x26,0x01,0x01,0x8d,0x83,0x00,0x58,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xe4}, 8333}, + {{0x26,0x01,0x02,0x40,0x46,0x00,0x40,0xc0,0x02,0x50,0x56,0xff,0xfe,0xa4,0x63,0x05}, 8333}, + {{0x26,0x01,0x05,0x81,0xc2,0x00,0xa7,0x19,0x54,0x2c,0x9c,0xd5,0x48,0x52,0xf7,0xd9}, 8333}, + {{0x26,0x01,0x06,0x47,0x49,0x00,0x85,0xf1,0xca,0x2a,0x14,0xff,0xfe,0x51,0xbb,0x35}, 8333}, + {{0x26,0x01,0x00,0xc2,0xc0,0x02,0xb3,0x00,0x54,0xa0,0x15,0xb5,0x19,0xf7,0x53,0x0d}, 8333}, + {{0x26,0x02,0x03,0x06,0xcc,0xff,0xad,0x7f,0xb1,0x16,0x52,0xbe,0x64,0xba,0xdb,0x3a}, 8333}, + {{0x26,0x02,0x00,0xae,0x19,0x82,0x94,0x00,0x08,0x46,0xf7,0x8c,0x0f,0xec,0x4d,0x57}, 8333}, {{0x26,0x02,0xff,0xc5,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x2d,0x61}, 8333}, {{0x26,0x02,0xff,0xc5,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x92,0x11}, 8333}, + {{0x26,0x02,0xff,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x75,0xd5,0xc1,0xc3}, 8333}, {{0x26,0x02,0xff,0xc5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc5,0xb8,0x44}, 8333}, {{0x26,0x02,0xff,0xe8,0x01,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x04,0x57,0x93,0x6b}, 8333}, - {{0x26,0x02,0xff,0xea,0x10,0x01,0x01,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x2a,0xd4}, 8333}, - {{0x26,0x02,0xff,0xea,0x10,0x01,0x06,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x7d}, 8333}, + {{0x26,0x02,0xff,0xe8,0x01,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x9d,0x20,0x2e,0x3c}, 8333}, {{0x26,0x02,0xff,0xea,0x10,0x01,0x07,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0x57,0x8b}, 8333}, - {{0x26,0x02,0xff,0xea,0x10,0x01,0x07,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x9c,0xae}, 8333}, - {{0x26,0x02,0xff,0xea,0x00,0x01,0x02,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x6b,0xc8}, 8333}, - {{0x26,0x02,0xff,0xea,0x00,0x01,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x79,0x68}, 8333}, - {{0x26,0x02,0xff,0xea,0x00,0x01,0x07,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0xec}, 8333}, - {{0x26,0x02,0xff,0xea,0x00,0x01,0x09,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xe9,0x57}, 8333}, - {{0x26,0x02,0xff,0xea,0x00,0x01,0x0a,0x5d,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0xcb}, 8333}, {{0x26,0x02,0xff,0xea,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0xc4,0xd9,0xfd}, 8333}, - {{0x26,0x02,0xff,0xea,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x06,0xae,0x32}, 8333}, {{0x26,0x04,0x00,0x00,0x00,0xc1,0x01,0x00,0x1e,0xc1,0xde,0xff,0xfe,0x54,0x22,0x35}, 8333}, {{0x26,0x04,0x01,0x80,0x00,0x01,0x01,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xa9}, 8333}, - {{0x26,0x04,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb2,0x08,0x03,0x98}, 8333}, - {{0x26,0x04,0x28,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x72,0x0a,0xed}, 8333}, + {{0x26,0x04,0x01,0x80,0x00,0x03,0x07,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0xde}, 8333}, {{0x26,0x04,0x40,0x80,0x11,0x14,0x00,0x00,0x32,0x85,0xa9,0xff,0xfe,0x93,0x85,0x0c}, 8333}, - {{0x26,0x04,0x7c,0x00,0x00,0x17,0x03,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x5a,0x4d}, 8333}, - {{0x26,0x04,0x9a,0x00,0x21,0x00,0xa0,0x09,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x26,0x04,0xa8,0x80,0x00,0x01,0x00,0x20,0x00,0x00,0x00,0x00,0x02,0x2a,0x40,0x01}, 8333}, - {{0x26,0x04,0xa8,0x80,0x08,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x07,0x52,0xf0,0x01}, 8333}, - {{0x26,0x04,0x0c,0x00,0x00,0x88,0x00,0x32,0x02,0x16,0x3e,0xff,0xfe,0xe4,0xfc,0xca}, 8333}, - {{0x26,0x04,0x0c,0x00,0x00,0x88,0x00,0x32,0x02,0x16,0x3e,0xff,0xfe,0xf5,0xbc,0x21}, 8333}, - {{0x26,0x05,0x79,0x80,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x17,0x61,0x3d,0x4e}, 8333}, - {{0x26,0x05,0xe0,0x00,0x14,0x17,0x40,0x68,0x02,0x23,0x32,0xff,0xfe,0x96,0x0e,0x2d}, 8333}, + {{0x26,0x04,0x60,0x00,0xff,0xc0,0x00,0x3c,0x64,0xa3,0x94,0xd0,0x4f,0x1d,0x1d,0xa8}, 8333}, + {{0x26,0x05,0x60,0x00,0xf3,0x80,0x9a,0x01,0xba,0x09,0x8a,0xff,0xfe,0xd4,0x35,0x11}, 8333}, + {{0x26,0x05,0x60,0x01,0xe0,0x0f,0x7b,0x00,0xc5,0x87,0x6d,0x91,0x6e,0xff,0xee,0xba}, 8333}, + {{0x26,0x05,0xf7,0x00,0x00,0xc0,0x00,0x01,0x00,0x00,0x00,0x00,0x25,0xc3,0x2a,0x3e}, 8333}, {{0x26,0x06,0x60,0x00,0xa4,0x41,0x99,0x03,0x50,0x54,0x00,0xff,0xfe,0x78,0x66,0xff}, 8333}, - {{0x26,0x06,0xdf,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0xae,0x85,0x8f,0xc6}, 8333}, - {{0x26,0x07,0x53,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x7f}, 8333}, + {{0x26,0x07,0x53,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1c,0x83}, 9334}, {{0x26,0x07,0x53,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa1}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x11,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x15,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x1b,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x23,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x1c,0x2f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x26,0x07,0x53,0x00,0x00,0x60,0x2b,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x2d,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x03,0xcb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x33,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x03,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, {{0x26,0x07,0x53,0x00,0x00,0x60,0x4a,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x51,0x12,0x00,0x00,0x00,0x02,0x4a,0xf5,0x63,0xfe}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x6d,0xd5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, - {{0x26,0x07,0x53,0x00,0x00,0x60,0x0a,0x91,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x26,0x07,0xf1,0xc0,0x08,0x20,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x3f,0x44}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x65,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x69,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x71,0x1a,0x00,0x78,0x00,0x00,0x00,0x00,0xa7,0xb5}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x07,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x08,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x26,0x07,0x53,0x00,0x00,0x60,0x95,0x2e,0x37,0x33,0x00,0x00,0x00,0x00,0x14,0x14}, 8333}, {{0x26,0x07,0xf1,0xc0,0x08,0x48,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x94,0x3c}, 8333}, + {{0x26,0x07,0xf2,0xe0,0x00,0x0f,0x05,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x26,0x07,0xf7,0x48,0x12,0x00,0x00,0xf8,0x02,0x1e,0x67,0xff,0xfe,0x99,0x8f,0x07}, 8333}, {{0x26,0x07,0xf9,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07}, 8333}, - {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x04,0xad,0xe5,0x94}, 8333}, - {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x65,0x9e,0x9c,0xb3}, 8333}, - {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0xc7,0x4b,0xa8,0xae}, 8333}, - {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x0d,0x82,0xd8,0xc2}, 8333}, - {{0x26,0x07,0xfc,0xd0,0x01,0x00,0x43,0x00,0x00,0x00,0x00,0x00,0x87,0x95,0x2f,0xa8}, 8333}, - {{0x26,0x07,0xfc,0xd0,0xda,0xaa,0x09,0x01,0x00,0x00,0x00,0x00,0x95,0x61,0xe0,0x43}, 8333}, + {{0x26,0x07,0xff,0x68,0x01,0x00,0x00,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x31}, 8333}, + {{0x28,0x03,0x69,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x17}, 8333}, + {{0x2a,0x00,0x10,0x98,0x00,0x00,0x00,0x80,0x10,0x00,0x00,0x25,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x00,0x11,0x78,0x00,0x02,0x00,0x43,0x50,0x54,0x00,0xff,0xfe,0x84,0xf8,0x6f}, 8333}, {{0x2a,0x00,0x11,0x78,0x00,0x02,0x00,0x43,0x50,0x54,0x00,0xff,0xfe,0xe7,0x2e,0xb6}, 8333}, - {{0x2a,0x00,0x13,0x28,0xe1,0x00,0xcc,0x42,0x02,0x30,0x48,0xff,0xfe,0x92,0x05,0x5d}, 8333}, + {{0x2a,0x00,0x11,0x78,0x00,0x02,0x00,0x43,0x89,0x83,0xcc,0x27,0x0d,0x72,0xd9,0x7a}, 8333}, + {{0x2a,0x00,0x13,0x28,0xe1,0x00,0xcc,0x42,0x02,0x30,0x48,0xff,0xfe,0x92,0x05,0x5c}, 8333}, {{0x2a,0x00,0x14,0xf0,0xe0,0x00,0x80,0xd2,0xcd,0x1a,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x00,0x16,0xd8,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x5b,0x6a,0xc2,0x61}, 8333}, - {{0x2a,0x00,0x61,0xe0,0x40,0x83,0x6d,0x01,0x68,0x52,0x13,0x76,0xe9,0x72,0x20,0x91}, 8333}, - {{0x2a,0x00,0x0c,0x98,0x20,0x30,0xa0,0x2f,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x00,0x16,0x30,0x00,0x02,0x18,0x02,0x01,0x88,0x01,0x22,0x00,0x91,0x00,0x11}, 8333}, + {{0x2a,0x00,0x18,0xe0,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x00,0x18,0xe0,0x00,0x00,0xdc,0xc5,0x01,0x09,0x02,0x34,0x01,0x06,0x01,0x91}, 8333}, + {{0x2a,0x00,0x1a,0x28,0x11,0x57,0x00,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0xc7}, 8333}, + {{0x2a,0x00,0x1c,0xa8,0x00,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0xfc,0x40,0xd1}, 8333}, + {{0x2a,0x00,0x1c,0xa8,0x00,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0xab,0x6d,0xce,0x2c}, 8333}, + {{0x2a,0x00,0x71,0x43,0x01,0x00,0x00,0x00,0x02,0x16,0x3e,0xff,0xfe,0x2e,0x74,0xa3}, 8333}, + {{0x2a,0x00,0x71,0x43,0x01,0x00,0x00,0x00,0x02,0x16,0x3e,0xff,0xfe,0xd3,0x5c,0x21}, 8333}, + {{0x2a,0x00,0x7c,0x80,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x23}, 8333}, + {{0x2a,0x00,0xdc,0xc0,0x0e,0xda,0x00,0x98,0x01,0x83,0x01,0x93,0xc3,0x82,0x6b,0xdb}, 8333}, + {{0x2a,0x00,0xdc,0xc0,0x0e,0xda,0x00,0x98,0x01,0x83,0x01,0x93,0xf7,0x2e,0xd9,0x43}, 8333}, + {{0x2a,0x00,0xf8,0x20,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xaf,0x00,0x01}, 8333}, + {{0x2a,0x00,0xf9,0x40,0x00,0x02,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x10,0x1d}, 8333}, + {{0x2a,0x00,0xf9,0x40,0x00,0x02,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x06,0xac}, 8333}, {{0x2a,0x01,0x01,0xb0,0x79,0x99,0x04,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x31}, 8333}, - {{0x2a,0x01,0x01,0xe8,0xe1,0x00,0x81,0x1c,0x70,0x0f,0x65,0xf0,0xf7,0x2a,0x10,0x84}, 8333}, - {{0x2a,0x01,0x02,0x38,0x42,0xda,0xc5,0x00,0x65,0x46,0x12,0x93,0x54,0x22,0xab,0x40}, 8333}, - {{0x2a,0x01,0x03,0x48,0x00,0x06,0x04,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x03,0x68,0xe0,0x10,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0x30,0x00,0x17,0x00,0x01,0x00,0x00,0x00,0x00,0xff,0xff,0x05,0x49}, 8333}, - {{0x2a,0x01,0x04,0x30,0x00,0x17,0x00,0x01,0x00,0x00,0x00,0x00,0xff,0xff,0x08,0x30}, 8333}, - {{0x2a,0x01,0x04,0x88,0x00,0x66,0x10,0x00,0x53,0xa9,0x0d,0x04,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x01,0x04,0x88,0x00,0x66,0x10,0x00,0x57,0xe6,0x57,0x8c,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x01,0x02,0x38,0x42,0xdd,0xf9,0x00,0x7a,0x6c,0x2b,0xc6,0x40,0x41,0x0c,0x43}, 8333}, + {{0x2a,0x01,0x02,0x38,0x43,0x13,0x63,0x00,0x21,0x89,0x1c,0x97,0x69,0x6b,0x05,0xea}, 8333}, + {{0x2a,0x01,0x04,0x88,0x00,0x66,0x10,0x00,0x5c,0x33,0x91,0xf9,0x00,0x00,0x00,0x01}, 8333}, {{0x2a,0x01,0x04,0x88,0x00,0x66,0x10,0x00,0xb0,0x1c,0x17,0x8d,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x01,0x04,0x88,0x00,0x67,0x10,0x00,0x05,0x23,0xfd,0xce,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x01,0x04,0x88,0x00,0x67,0x10,0x00,0xb0,0x1c,0x30,0xab,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x24,0xaa,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x34,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x34,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x44,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x51,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x51,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x00,0x84,0xa7,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x10,0x51,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x10,0x51,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x10,0x53,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x43,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x62,0xe6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x70,0x2e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x80,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x82,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x20,0x84,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x21,0x11,0xeb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x21,0x23,0x4d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x21,0x02,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x24,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x24,0x2b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x24,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x11,0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x33,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x40,0xab,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x63,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x63,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x64,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x30,0x93,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x31,0x20,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x31,0x54,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x40,0x80,0xad,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x31,0x33,0xad,0xfe,0xa1,0x00,0x00,0x00,0x00,0x06,0x66}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x40,0x21,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x40,0x63,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x40,0x93,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x40,0x93,0xb0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x41,0x11,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x41,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x21,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x22,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x23,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x61,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x70,0x88,0x50,0x54,0x00,0xff,0xfe,0x45,0xbf,0xf2}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x41,0x53,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x33,0x6a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x72,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x50,0x83,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 9001}, - {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x01,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x21,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x41,0xc2,0x00,0x00,0x54,0x04,0xa6,0x7e,0xf2,0x50}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x51,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x52,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x54}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x51,0x63,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 9001}, - {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x52,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x93,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x23,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x43,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x73,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x73,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x74,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x60,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x63,0x49,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x60,0x51,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x60,0x72,0xc5,0x00,0x00,0x00,0x00,0x28,0x58,0xe1,0xc5}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x60,0x72,0xc5,0x00,0x00,0x00,0x00,0x59,0x3b,0x60,0xd5}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x60,0x81,0x4f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x13,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x22,0x8f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x51,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x60,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x70,0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x61,0x91,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x21,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x21,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x44,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x62,0x51,0xa3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x71,0x0b,0x93,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x14,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x44,0x95,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x64,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x90,0x91,0xce,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x21,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x40,0xa1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x04,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x63,0xb4,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x71,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x40,0xe8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x44,0xb4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x82,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x83,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x91,0x93,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x60,0xa9,0x00,0x00,0x00,0x01,0x00,0x05,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x73,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x80,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x11,0xb2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x21,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x22,0xb3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x44,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x01,0x92,0x00,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x10,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x22,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x41,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x63,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x22}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x23,0xd1,0x00,0x00,0x00,0x00,0xde,0xad,0xbe,0xef}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x50,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x51,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x53,0x89,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x53,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x63,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x63,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x63,0xaf,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x19}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x00,0x71,0xe3,0x78,0xb4,0xf3,0xff,0xfe,0xad,0xe8,0xcf}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x51,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x21,0x4c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x02,0x33,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x03,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x60,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x01,0x60,0xd5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x02,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x31,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x31,0xe3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x31,0xef,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x33,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x53,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x63,0xf4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x02,0x72,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x10,0x22,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x10,0x24,0xaa,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x10,0x50,0x2f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x14,0xcf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x1a,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x2a,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x0c,0xca,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x22,0xa5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x50,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x11,0x18,0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x12,0x28,0x9e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x02,0x12,0x33,0xdb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 18333}, + {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x11,0x2f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x31,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x32,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x52,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x74,0xc8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x82,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x00,0xa0,0x82,0x2d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x01,0x04,0xf8,0x0d,0x13,0x21,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x19,0xb9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x1a,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x1a,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x02,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x04,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x07,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0c,0x17,0x0b,0x54,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x01,0x04,0xf8,0x0d,0x16,0x93,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, {{0x2a,0x01,0x06,0x08,0xff,0xff,0xa0,0x09,0x8b,0xf5,0x87,0x9d,0xe5,0x1a,0xf8,0x37}, 8333}, - {{0x2a,0x01,0x07,0x9d,0x46,0x9e,0xed,0x94,0xc2,0x3f,0xd5,0xff,0xfe,0x65,0x20,0xc5}, 8333}, - {{0x2a,0x01,0x07,0xc8,0xaa,0xb5,0x03,0xe6,0x50,0x54,0x00,0xff,0xfe,0xd7,0x4e,0x54}, 8333}, + {{0x2a,0x01,0x06,0x80,0x00,0x10,0x00,0x10,0xf2,0xde,0xf1,0xff,0xfe,0xc9,0x0d,0xc0}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xac,0x01,0xf6,0x50,0x54,0x00,0xff,0xfe,0x30,0xe5,0x85}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xac,0x02,0x0b,0x50,0x54,0x00,0xff,0xfe,0x24,0x43,0x5e}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xac,0x04,0x3d,0x50,0x54,0x00,0xff,0xfe,0x4e,0x3d,0xd4}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xad,0x02,0x56,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xb6,0x00,0xea,0x50,0x54,0x00,0xff,0xfe,0xff,0xea,0xc3}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xb9,0x00,0x5a,0x50,0x54,0x00,0xff,0xfe,0x89,0x7b,0x26}, 8333}, + {{0x2a,0x01,0x07,0xc8,0xaa,0xbc,0x02,0xc8,0x50,0x54,0x00,0xff,0xfe,0x35,0x65,0x81}, 8333}, {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x30,0x1e}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x77,0x49}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x2d,0x67}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0x34,0x7c}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x33,0xae,0x50}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x56,0x6b,0x5c}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x56,0xbe,0xe6}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x69,0x48,0x95}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x69,0x99,0x12}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x6e,0x26,0xee}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x73,0x42,0xf1}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x18,0x39,0x42}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x26,0x8c,0x87}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x50,0x62,0x06}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x67,0x55,0x9d}, 8333}, {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x84,0x43,0x4f}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x84,0xb3,0x6b}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x89,0x1f,0xaa}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x98,0x08,0x16}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x89,0x11,0x43}, 8333}, + {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0x98,0x25,0x05}, 8333}, {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xdb,0x35,0x2e}, 8333}, - {{0x2a,0x01,0x7e,0x00,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xdb,0x4a,0x1d}, 8333}, - {{0x2a,0x01,0x0e,0x34,0xed,0xbb,0x67,0x50,0x02,0x24,0x1d,0xff,0xfe,0x89,0x38,0x97}, 8333}, - {{0x2a,0x01,0x0e,0x35,0x2f,0x1d,0x3f,0xb0,0x71,0x87,0xc7,0xba,0xbc,0xfc,0x80,0xce}, 8333}, - {{0x2a,0x01,0x0e,0x35,0x87,0x87,0x96,0xf0,0x90,0x32,0x92,0x97,0x39,0xae,0x49,0x6d}, 8333}, + {{0x2a,0x01,0x7e,0x01,0x00,0x00,0x00,0x00,0xf0,0x3c,0x91,0xff,0xfe,0xc8,0xd7,0xb5}, 8333}, + {{0x2a,0x01,0x0e,0x34,0xee,0x33,0x16,0x40,0xc5,0x04,0xf6,0x77,0xb2,0x8a,0xba,0x42}, 8333}, + {{0x2a,0x01,0x0e,0x35,0x2e,0x7e,0x0b,0xc0,0xe0,0x79,0xf5,0x5e,0xce,0xf3,0xb5,0xd7}, 8333}, + {{0x2a,0x01,0x0e,0x35,0x2e,0xe5,0x06,0x10,0x02,0x1f,0xd0,0xff,0xfe,0x4e,0x74,0x60}, 8333}, {{0x2a,0x01,0x0e,0x35,0x8a,0x3f,0x47,0xc0,0xc6,0x17,0xfe,0xff,0xfe,0x3c,0x9f,0xbd}, 8333}, - {{0x2a,0x01,0x0e,0x35,0x8b,0x66,0x06,0xa0,0x49,0x00,0x9d,0xfd,0xd8,0x41,0xd0,0x25}, 8333}, - {{0x2a,0x02,0x01,0x68,0x4a,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x39}, 8333}, - {{0x2a,0x02,0x01,0x68,0x54,0x04,0x00,0x02,0xc2,0x3f,0xd5,0xff,0xfe,0x6a,0x51,0x2e}, 8333}, - {{0x2a,0x02,0x01,0x80,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x5b,0x8f,0x53,0x8c}, 8333}, - {{0x2a,0x02,0x20,0x28,0x10,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, - {{0x2a,0x02,0x25,0x28,0x05,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14}, 8333}, + {{0x2a,0x01,0x0e,0x35,0x8a,0xca,0x06,0xa0,0x02,0x11,0x0a,0xff,0xfe,0x5e,0x29,0x5e}, 8333}, + {{0x2a,0x02,0x01,0x80,0x00,0x0a,0x00,0x18,0x00,0x81,0x00,0x07,0x00,0x11,0x00,0x50}, 8333}, + {{0x2a,0x02,0x18,0x10,0x1d,0x87,0x6a,0x00,0x56,0x04,0xa6,0xff,0xfe,0x60,0xd8,0x7d}, 8333}, + {{0x2a,0x02,0x21,0x68,0x11,0x44,0x5c,0x01,0xd6,0x3d,0x7e,0xff,0xfe,0xdd,0x4f,0x8e}, 8333}, + {{0x2a,0x02,0x24,0x98,0x6d,0x7b,0x70,0x01,0xb5,0x08,0xb3,0x9d,0x2c,0xea,0x5b,0x7a}, 8333}, {{0x2a,0x02,0x25,0x28,0x05,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15}, 8333}, - {{0x2a,0x02,0x25,0x28,0xff,0x00,0x81,0xa6,0x02,0x1e,0xc5,0xff,0xfe,0x8d,0xf9,0xa5}, 8333}, - {{0x2a,0x02,0x27,0x70,0x00,0x05,0x00,0x00,0x02,0x1a,0x4a,0xff,0xfe,0xe4,0xc7,0xdb}, 8333}, - {{0x2a,0x02,0x27,0x70,0x00,0x08,0x00,0x00,0x02,0x1a,0x4a,0xff,0xfe,0x7b,0x3d,0xcd}, 8333}, - {{0x2a,0x02,0x03,0x48,0x00,0x5e,0x5a,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x02,0x7a,0xa0,0x16,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x2f,0xc0,0x6a}, 8333}, - {{0x2a,0x02,0x81,0x09,0x8e,0x40,0x35,0xfc,0xba,0x27,0xeb,0xff,0xfe,0xae,0xcf,0x16}, 8333}, - {{0x2a,0x02,0x0a,0xf8,0x00,0x06,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x30}, 8333}, - {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x01,0x00,0x00,0x63,0x14,0x22,0x22}, 8333}, - {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x02,0x00,0x03,0x32,0x95,0x00,0x01}, 8332}, - {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x03,0x00,0x00,0x54,0x49,0x00,0x01}, 8333}, - {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x02,0x00,0x03,0x58,0x99,0x00,0x01}, 8333}, - {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x00,0x00,0x00,0x27,0x05,0x00,0x01}, 8333}, - {{0x2a,0x02,0xce,0x80,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, - {{0x2a,0x02,0x0f,0xe0,0xc3,0x21,0x27,0xe0,0x6e,0xf0,0x49,0xff,0xfe,0x11,0xa6,0x1d}, 8333}, + {{0x2a,0x02,0x25,0x28,0x00,0xfa,0x1a,0x56,0x02,0x16,0x44,0xff,0xfe,0x6a,0xd1,0x12}, 8333}, + {{0x2a,0x02,0x27,0xf8,0x20,0x12,0x00,0x00,0xe9,0xf7,0x26,0x8f,0xc4,0x41,0x61,0x29}, 8333}, + {{0x2a,0x02,0x03,0x48,0x00,0x86,0x30,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x02,0x47,0x80,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x8a,0x01}, 8333}, + {{0x2a,0x02,0x05,0x78,0x50,0x02,0x01,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x02,0x60,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x19,0x0b,0x69,0xe3}, 8333}, + {{0x2a,0x02,0x60,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe8,0x93,0xd9,0xd6}, 8333}, + {{0x2a,0x02,0x07,0x70,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x39}, 8333}, + {{0x2a,0x02,0x7a,0xa0,0x12,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xde,0xb3,0x81,0xa2}, 8333}, + {{0x2a,0x02,0x80,0x10,0xb0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x60,0x59,0xb5}, 8333}, + {{0x2a,0x02,0x81,0x0d,0x21,0xc0,0x0f,0x00,0xa2,0x48,0x1c,0xff,0xfe,0xb8,0x53,0x48}, 8333}, + {{0x2a,0x02,0x0a,0x50,0x00,0x00,0x00,0x00,0x02,0x1b,0x24,0xff,0xfe,0x93,0x4e,0x39}, 8333}, + {{0x2a,0x02,0x0a,0x80,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x02,0x00,0x01,0x58,0x30,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x02,0x00,0x05,0x46,0x92,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x03,0x00,0x00,0x71,0x58,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x22,0x44,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x02,0x00,0x03,0x33,0x39,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x02,0x00,0x03,0x78,0x44,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x02,0x00,0x05,0x62,0x88,0x00,0x01}, 8333}, + {{0x2a,0x02,0xc2,0x00,0x00,0x01,0x00,0x10,0x00,0x03,0x00,0x00,0x59,0x12,0x00,0x01}, 8333}, {{0x2a,0x03,0x40,0x00,0x00,0x02,0x04,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08}, 8333}, - {{0x2a,0x03,0xb0,0xc0,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x62,0xf0,0x01}, 8333}, + {{0x2a,0x03,0x40,0x00,0x00,0x06,0x80,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, 8333}, + {{0x2a,0x03,0x40,0x00,0x00,0x06,0x80,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0xbc,0xd0}, 8333}, + {{0x2a,0x03,0x49,0x00,0xff,0xfc,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}, 8333}, + {{0x2a,0x03,0xb0,0xc0,0x00,0x01,0x00,0xd0,0x00,0x00,0x00,0x00,0x00,0x0d,0x50,0x01}, 8333}, + {{0x2a,0x03,0x0f,0x80,0xed,0x15,0x01,0x49,0x01,0x54,0x01,0x55,0x02,0x35,0x00,0x01}, 8333}, + {{0x2a,0x03,0x0f,0x80,0xed,0x15,0x01,0x49,0x01,0x54,0x01,0x55,0x02,0x41,0x00,0x01}, 8333}, {{0x2a,0x03,0x0f,0x80,0xed,0x16,0x0c,0xa7,0xea,0x75,0xb1,0x2d,0x02,0xaf,0x9e,0x2a}, 8333}, + {{0x2a,0x04,0x19,0x80,0x31,0x00,0x1a,0xab,0x02,0x90,0xfa,0xff,0xfe,0x70,0xa3,0xd8}, 8333}, + {{0x2a,0x04,0x19,0x80,0x31,0x00,0x1a,0xab,0xe6,0x1d,0x2d,0xff,0xfe,0x29,0xf5,0x90}, 8333}, + {{0x2a,0x04,0x2f,0x80,0x00,0x06,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x89}, 8333}, + {{0x2a,0x04,0xac,0x00,0x00,0x01,0x4a,0x0b,0x50,0x54,0x00,0xff,0xfe,0x00,0x5a,0xf5}, 8333}, + {{0x2a,0x04,0xad,0x80,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0xda}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd9,0x4a,0xaf,0xa2,0x8c,0x9d,0xf6,0x22,0x18,0x28}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xd9,0xe4,0x70,0x01,0xb3,0xa7,0x9d,0x3e,0x51,0xf9}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe7,0x45,0xd5,0x8b,0xff,0x81,0x9e,0x85,0x00,0xb8}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xdb,0x58,0x10,0x81,0x48,0x69,0x2c,0xb3,0x0d,0x6d}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe2,0x7f,0xf3,0x20,0xef,0x72,0xaf,0x4d,0x29,0x3c}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xef,0x3c,0x49,0x0b,0xc1,0x74,0xc2,0x92,0x86,0xe1}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xe8,0x27,0xf9,0x43,0xad,0x67,0xfd,0x74,0x25,0x43}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xff,0xd9,0x7d,0x26,0x57,0x03,0xb0,0x49,0x67,0x4f}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xf9,0xbe,0x9e,0xf0,0x33,0x40,0x2e,0x79,0xc9,0x18}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0f,0x8b,0x1f,0x8d,0x61,0xa6,0x94,0xf4,0x62,0x45}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0x26,0x27,0x21,0xa2,0x2c,0x05,0x29,0x20,0xdd}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x07,0x9c,0x11,0x9b,0x2d,0xf7,0xd7,0xf2,0x5e,0x9b}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x00,0x7d,0xc3,0xfd,0xcb,0x7a,0xff,0x07,0xdc,0x48}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x03,0x34,0x0e,0x44,0x07,0x5c,0xcb,0x4b,0xe7,0xcb}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x06,0x69,0x75,0xcb,0x88,0x3c,0x63,0xa6,0x11,0xff}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0x26,0x27,0x21,0xbf,0x0a,0x38,0xe7,0xfe,0xc1}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0x26,0x27,0x21,0xae,0x94,0xd5,0xc2,0x72,0x24}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0a,0xbf,0x87,0xf8,0x8f,0x6b,0x04,0xb5,0xc3,0xfa}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x0b,0x29,0x34,0x96,0x29,0xe8,0x67,0x22,0x0c,0x61}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x1c,0x5f,0xc7,0xd4,0x89,0xc0,0x6f,0xa2,0x24,0x71}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x32,0x2e,0xda,0xf7,0xc3,0xf6,0xc3,0x4c,0x3c,0x0d}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x11,0x08,0x94,0x72,0x0f,0x2c,0xb6,0xc9,0x6f,0x22}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x12,0xc9,0x76,0x66,0x08,0x77,0xf0,0x71,0x81,0xdc}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x30,0x7b,0x87,0xc2,0x7e,0xd8,0xe9,0xbb,0x14,0xed}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x3e,0xaa,0xb7,0xd0,0x79,0x79,0xf3,0x0b,0xd2,0x63}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x39,0xd1,0x5e,0xbd,0xb7,0x23,0x6a,0x12,0xf0,0x0c}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x5e,0x6e,0xf5,0x37,0xcf,0x9b,0xf6,0xe3,0x9f,0xdb}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x64,0x9e,0x79,0x18,0xa8,0x81,0x61,0xd9,0x4d,0xa4}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x6f,0x34,0x7f,0xc7,0xce,0xa3,0x04,0x59,0x06,0x32}, 4176}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x68,0xac,0xad,0xae,0x93,0x23,0x0a,0x51,0x3c,0x5c}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x72,0x87,0x94,0x82,0x36,0x22,0x83,0x23,0xb5,0xc5}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x92,0x46,0xe6,0x23,0x98,0x0e,0x87,0x65,0x24,0x22}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa5,0x6c,0xec,0xda,0xeb,0x41,0xdb,0x34,0x18,0x21}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xaf,0xb0,0xbc,0xf3,0xa3,0x6f,0x70,0x17,0xab,0x83}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x7a,0x4c,0x71,0x22,0xb9,0x53,0x89,0x19,0x12,0x43}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0x8d,0xbe,0xe1,0x25,0x73,0x45,0xf5,0xe6,0x10,0xad}, 8333}, + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xa5,0xa5,0xf4,0x4c,0x8f,0xfb,0xb7,0x84,0x36,0xee}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xaa,0xb7,0x04,0x8c,0x87,0xc6,0x38,0x3b,0x0a,0xf6}, 8333}, {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xac,0x1f,0x82,0x69,0x5d,0x88,0xa1,0x54,0xf5,0x90}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xbd,0x06,0xa7,0x66,0x63,0x2c,0x65,0x4c,0x61,0xd4}, 8333}, - {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xcf,0x7b,0x5e,0x3a,0x53,0x21,0x5b,0x62,0xe3,0x7a}, 8333} + {{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0xb3,0xd1,0xf8,0xbe,0xa7,0x6b,0x46,0xbe,0xe8,0x84}, 8333} }; static SeedSpec6 pnSeed6_test[] = { diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index a9822eed8..aefddce46 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/checkpoints.h b/src/checkpoints.h index 5fce6fa81..cd25ea537 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/checkqueue.h b/src/checkqueue.h index 20ba25bb4..32e25d5c8 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/clientversion.h b/src/clientversion.h index 6157423f0..6f255d69c 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,7 +15,7 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 0 -#define CLIENT_VERSION_MINOR 11 +#define CLIENT_VERSION_MINOR 12 #define CLIENT_VERSION_REVISION 99 #define CLIENT_VERSION_BUILD 0 @@ -26,7 +26,7 @@ * Copyright year (2009-this) * Todo: update this when changing our copyright comments in the source */ -#define COPYRIGHT_YEAR 2015 +#define COPYRIGHT_YEAR 2016 #endif //HAVE_CONFIG_H diff --git a/src/coincontrol.h b/src/coincontrol.h index bc965f9e1..9626ad2c5 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -16,6 +16,8 @@ public: bool fAllowOtherInputs; //! Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria bool fAllowWatchOnly; + //! Minimum absolute fee (not per kilobyte) + CAmount nMinimumTotalFee; CCoinControl() { @@ -28,6 +30,7 @@ public: fAllowOtherInputs = false; fAllowWatchOnly = false; setSelected.clear(); + nMinimumTotalFee = 0; } bool HasSelected() const diff --git a/src/coins.cpp b/src/coins.cpp index 96b336ce7..877fb8b26 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -117,11 +117,17 @@ CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) { return CCoinsModifier(*this, ret.first, cachedCoinUsage); } -CCoinsModifier CCoinsViewCache::ModifyNewCoins(const uint256 &txid) { +// ModifyNewCoins has to know whether the new outputs its creating are for a +// coinbase or not. If they are for a coinbase, it can not mark them as fresh. +// This is to ensure that the historical duplicate coinbases before BIP30 was +// in effect will still be properly overwritten when spent. +CCoinsModifier CCoinsViewCache::ModifyNewCoins(const uint256 &txid, bool coinbase) { assert(!hasModifier); std::pair ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())); ret.first->second.coins.Clear(); - ret.first->second.flags = CCoinsCacheEntry::FRESH; + if (!coinbase) { + ret.first->second.flags = CCoinsCacheEntry::FRESH; + } ret.first->second.flags |= CCoinsCacheEntry::DIRTY; return CCoinsModifier(*this, ret.first, 0); } @@ -144,6 +150,11 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) const { return (it != cacheCoins.end() && !it->second.coins.vout.empty()); } +bool CCoinsViewCache::HaveCoinsInCache(const uint256 &txid) const { + CCoinsMap::const_iterator it = cacheCoins.find(txid); + return it != cacheCoins.end(); +} + uint256 CCoinsViewCache::GetBestBlock() const { if (hashBlock.IsNull()) hashBlock = base->GetBestBlock(); @@ -160,18 +171,23 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization). CCoinsMap::iterator itUs = cacheCoins.find(it->first); if (itUs == cacheCoins.end()) { - if (!it->second.coins.IsPruned()) { - // The parent cache does not have an entry, while the child - // cache does have (a non-pruned) one. Move the data up, and - // mark it as fresh (if the grandparent did have it, we - // would have pulled it in at first GetCoins). - assert(it->second.flags & CCoinsCacheEntry::FRESH); + // The parent cache does not have an entry, while the child does + // We can ignore it if it's both FRESH and pruned in the child + if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coins.IsPruned())) { + // Otherwise we will need to create it in the parent + // and move the data up and mark it as dirty CCoinsCacheEntry& entry = cacheCoins[it->first]; entry.coins.swap(it->second.coins); cachedCoinsUsage += entry.coins.DynamicMemoryUsage(); - entry.flags = CCoinsCacheEntry::DIRTY | CCoinsCacheEntry::FRESH; + entry.flags = CCoinsCacheEntry::DIRTY; + // We can mark it FRESH in the parent if it was FRESH in the child + // Otherwise it might have just been flushed from the parent's cache + // and already exist in the grandparent + if (it->second.flags & CCoinsCacheEntry::FRESH) + entry.flags |= CCoinsCacheEntry::FRESH; } } else { + // Found the entry in the parent cache if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) { // The grandparent does not have an entry, and the child is // modified and being pruned. This means we can just delete @@ -201,6 +217,15 @@ bool CCoinsViewCache::Flush() { return fOk; } +void CCoinsViewCache::Uncache(const uint256& hash) +{ + CCoinsMap::iterator it = cacheCoins.find(hash); + if (it != cacheCoins.end() && it->second.flags == 0) { + cachedCoinsUsage -= it->second.coins.DynamicMemoryUsage(); + cacheCoins.erase(it); + } +} + unsigned int CCoinsViewCache::GetCacheSize() const { return cacheCoins.size(); } @@ -238,8 +263,9 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const return true; } -double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const +double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight, CAmount &inChainInputValue) const { + inChainInputValue = 0; if (tx.IsCoinBase()) return 0.0; double dResult = 0.0; @@ -248,8 +274,9 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const const CCoins* coins = AccessCoins(txin.prevout.hash); assert(coins); if (!coins->IsAvailable(txin.prevout.n)) continue; - if (coins->nHeight < nHeight) { + if (coins->nHeight <= nHeight) { dResult += coins->vout[txin.prevout.n].nValue * (nHeight-coins->nHeight); + inChainInputValue += coins->vout[txin.prevout.n].nValue; } } return tx.ComputePriority(dResult); diff --git a/src/coins.h b/src/coins.h index 3b45cb0a3..d297cae1a 100644 --- a/src/coins.h +++ b/src/coins.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -29,11 +29,11 @@ * - VARINT(nHeight) * * The nCode value consists of: - * - bit 1: IsCoinBase() - * - bit 2: vout[0] is not spent - * - bit 4: vout[1] is not spent + * - bit 0: IsCoinBase() + * - bit 1: vout[0] is not spent + * - bit 2: vout[1] is not spent * - The higher bits encode N, the number of non-zero bytes in the following bitvector. - * - In case both bit 2 and bit 4 are unset, they encode N-1, as there must be at + * - In case both bit 1 and bit 2 are unset, they encode N-1, as there must be at * least one non-spent output). * * Example: 0104835800816115944e077fe7c803cfa57f29b36bf87c1d358bb85e @@ -58,7 +58,7 @@ * * - version = 1 * - code = 9 (coinbase, neither vout[0] or vout[1] are unspent, - * 2 (1, +1 because both bit 2 and bit 4 are unset) non-zero bitvector bytes follow) + * 2 (1, +1 because both bit 1 and bit 2 are unset) non-zero bitvector bytes follow) * - unspentness bitvector: bits 2 (0x04) and 14 (0x4000) are set, so vout[2+2] and vout[14+2] are unspent * - vout[4]: 86ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4ee * * 86ef97d579: compact amount representation for 234925952 (2.35 BTC) @@ -405,6 +405,13 @@ public: void SetBestBlock(const uint256 &hashBlock); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); + /** + * Check if we have the given tx already loaded in this cache. + * The semantics are the same as HaveCoins(), but no calls to + * the backing CCoinsView are made. + */ + bool HaveCoinsInCache(const uint256 &txid) const; + /** * Return a pointer to CCoins in the cache, or NULL if not found. This is * more efficient than GetCoins. Modifications to other cache entries are @@ -428,7 +435,7 @@ public: * would not properly overwrite the first coinbase of the pair. Simultaneous modifications * are not allowed. */ - CCoinsModifier ModifyNewCoins(const uint256 &txid); + CCoinsModifier ModifyNewCoins(const uint256 &txid, bool coinbase); /** * Push the modifications applied to this cache to its base. @@ -437,6 +444,12 @@ public: */ bool Flush(); + /** + * Removes the transaction with the given hash from the cache, if it is + * not modified. + */ + void Uncache(const uint256 &txid); + //! Calculate the size of the cache (in number of transactions) unsigned int GetCacheSize() const; @@ -456,8 +469,12 @@ public: //! Check whether all prevouts of the transaction are present in the UTXO set represented by this view bool HaveInputs(const CTransaction& tx) const; - //! Return priority of tx at height nHeight - double GetPriority(const CTransaction &tx, int nHeight) const; + /** + * Return priority of tx at height nHeight. Also calculate the sum of the values of the inputs + * that are already in the chain. These are the inputs that will age and increase priority as + * new blocks are added to the chain. + */ + double GetPriority(const CTransaction &tx, int nHeight, CAmount &inChainInputValue) const; const CTxOut &GetOutputFor(const CTxIn& input) const; diff --git a/src/compat.h b/src/compat.h index 20c2a2514..1225ea18e 100644 --- a/src/compat.h +++ b/src/compat.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/compat/endian.h b/src/compat/endian.h index 9fec2a07f..6bfae42c7 100644 --- a/src/compat/endian.h +++ b/src/compat/endian.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin developers +// Copyright (c) 2014-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index 6d6ce7e09..5a099cf53 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/consensus/merkle.cpp b/src/consensus/merkle.cpp new file mode 100644 index 000000000..22eb7159a --- /dev/null +++ b/src/consensus/merkle.cpp @@ -0,0 +1,176 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "merkle.h" +#include "hash.h" +#include "utilstrencodings.h" + +/* WARNING! If you're reading this because you're learning about crypto + and/or designing a new system that will use merkle trees, keep in mind + that the following merkle tree algorithm has a serious flaw related to + duplicate txids, resulting in a vulnerability (CVE-2012-2459). + + The reason is that if the number of hashes in the list at a given time + is odd, the last one is duplicated before computing the next level (which + is unusual in Merkle trees). This results in certain sequences of + transactions leading to the same merkle root. For example, these two + trees: + + A A + / \ / \ + B C B C + / \ | / \ / \ + D E F D E F F + / \ / \ / \ / \ / \ / \ / \ + 1 2 3 4 5 6 1 2 3 4 5 6 5 6 + + for transaction lists [1,2,3,4,5,6] and [1,2,3,4,5,6,5,6] (where 5 and + 6 are repeated) result in the same root hash A (because the hash of both + of (F) and (F,F) is C). + + The vulnerability results from being able to send a block with such a + transaction list, with the same merkle root, and the same block hash as + the original without duplication, resulting in failed validation. If the + receiving node proceeds to mark that block as permanently invalid + however, it will fail to accept further unmodified (and thus potentially + valid) versions of the same block. We defend against this by detecting + the case where we would hash two identical hashes at the end of the list + together, and treating that identically to the block having an invalid + merkle root. Assuming no double-SHA256 collisions, this will detect all + known ways of changing the transactions without affecting the merkle + root. +*/ + +/* This implements a constant-space merkle root/path calculator, limited to 2^32 leaves. */ +static void MerkleComputation(const std::vector& leaves, uint256* proot, bool* pmutated, uint32_t branchpos, std::vector* pbranch) { + if (pbranch) pbranch->clear(); + if (leaves.size() == 0) { + if (pmutated) *pmutated = false; + if (proot) *proot = uint256(); + return; + } + bool mutated = false; + // count is the number of leaves processed so far. + uint32_t count = 0; + // inner is an array of eagerly computed subtree hashes, indexed by tree + // level (0 being the leaves). + // For example, when count is 25 (11001 in binary), inner[4] is the hash of + // the first 16 leaves, inner[3] of the next 8 leaves, and inner[0] equal to + // the last leaf. The other inner entries are undefined. + uint256 inner[32]; + // Which position in inner is a hash that depends on the matching leaf. + int matchlevel = -1; + // First process all leaves into 'inner' values. + while (count < leaves.size()) { + uint256 h = leaves[count]; + bool matchh = count == branchpos; + count++; + int level; + // For each of the lower bits in count that are 0, do 1 step. Each + // corresponds to an inner value that existed before processing the + // current leaf, and each needs a hash to combine it. + for (level = 0; !(count & (((uint32_t)1) << level)); level++) { + if (pbranch) { + if (matchh) { + pbranch->push_back(inner[level]); + } else if (matchlevel == level) { + pbranch->push_back(h); + matchh = true; + } + } + mutated |= (inner[level] == h); + CHash256().Write(inner[level].begin(), 32).Write(h.begin(), 32).Finalize(h.begin()); + } + // Store the resulting hash at inner position level. + inner[level] = h; + if (matchh) { + matchlevel = level; + } + } + // Do a final 'sweep' over the rightmost branch of the tree to process + // odd levels, and reduce everything to a single top value. + // Level is the level (counted from the bottom) up to which we've sweeped. + int level = 0; + // As long as bit number level in count is zero, skip it. It means there + // is nothing left at this level. + while (!(count & (((uint32_t)1) << level))) { + level++; + } + uint256 h = inner[level]; + bool matchh = matchlevel == level; + while (count != (((uint32_t)1) << level)) { + // If we reach this point, h is an inner value that is not the top. + // We combine it with itself (Bitcoin's special rule for odd levels in + // the tree) to produce a higher level one. + if (pbranch && matchh) { + pbranch->push_back(h); + } + CHash256().Write(h.begin(), 32).Write(h.begin(), 32).Finalize(h.begin()); + // Increment count to the value it would have if two entries at this + // level had existed. + count += (((uint32_t)1) << level); + level++; + // And propagate the result upwards accordingly. + while (!(count & (((uint32_t)1) << level))) { + if (pbranch) { + if (matchh) { + pbranch->push_back(inner[level]); + } else if (matchlevel == level) { + pbranch->push_back(h); + matchh = true; + } + } + CHash256().Write(inner[level].begin(), 32).Write(h.begin(), 32).Finalize(h.begin()); + level++; + } + } + // Return result. + if (pmutated) *pmutated = mutated; + if (proot) *proot = h; +} + +uint256 ComputeMerkleRoot(const std::vector& leaves, bool* mutated) { + uint256 hash; + MerkleComputation(leaves, &hash, mutated, -1, NULL); + return hash; +} + +std::vector ComputeMerkleBranch(const std::vector& leaves, uint32_t position) { + std::vector ret; + MerkleComputation(leaves, NULL, NULL, position, &ret); + return ret; +} + +uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector& vMerkleBranch, uint32_t nIndex) { + uint256 hash = leaf; + for (std::vector::const_iterator it = vMerkleBranch.begin(); it != vMerkleBranch.end(); ++it) { + if (nIndex & 1) { + hash = Hash(BEGIN(*it), END(*it), BEGIN(hash), END(hash)); + } else { + hash = Hash(BEGIN(hash), END(hash), BEGIN(*it), END(*it)); + } + nIndex >>= 1; + } + return hash; +} + +uint256 BlockMerkleRoot(const CBlock& block, bool* mutated) +{ + std::vector leaves; + leaves.resize(block.vtx.size()); + for (size_t s = 0; s < block.vtx.size(); s++) { + leaves[s] = block.vtx[s].GetHash(); + } + return ComputeMerkleRoot(leaves, mutated); +} + +std::vector BlockMerkleBranch(const CBlock& block, uint32_t position) +{ + std::vector leaves; + leaves.resize(block.vtx.size()); + for (size_t s = 0; s < block.vtx.size(); s++) { + leaves[s] = block.vtx[s].GetHash(); + } + return ComputeMerkleBranch(leaves, position); +} diff --git a/src/consensus/merkle.h b/src/consensus/merkle.h new file mode 100644 index 000000000..6ef59745a --- /dev/null +++ b/src/consensus/merkle.h @@ -0,0 +1,32 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_MERKLE +#define BITCOIN_MERKLE + +#include +#include + +#include "primitives/transaction.h" +#include "primitives/block.h" +#include "uint256.h" + +uint256 ComputeMerkleRoot(const std::vector& leaves, bool* mutated = NULL); +std::vector ComputeMerkleBranch(const std::vector& leaves, uint32_t position); +uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector& branch, uint32_t position); + +/* + * Compute the Merkle root of the transactions in a block. + * *mutated is set to true if a duplicated subtree was found. + */ +uint256 BlockMerkleRoot(const CBlock& block, bool* mutated = NULL); + +/* + * Compute the Merkle branch for the tree of transactions in a block, for a + * given position. + * This can be verified using ComputeMerkleRootFromBranch. + */ +std::vector BlockMerkleBranch(const CBlock& block, uint32_t position); + +#endif diff --git a/src/consensus/params.h b/src/consensus/params.h index 5ebc48a8d..335750fe8 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/consensus/validation.h b/src/consensus/validation.h index d6051edc3..d7e57f5b5 100644 --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/core_io.h b/src/core_io.h index ba5b4e648..e8c0c49e8 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/core_memusage.h b/src/core_memusage.h index a05f59ee0..450537d05 100644 --- a/src/core_memusage.h +++ b/src/core_memusage.h @@ -10,7 +10,7 @@ #include "memusage.h" static inline size_t RecursiveDynamicUsage(const CScript& script) { - return memusage::DynamicUsage(*static_cast*>(&script)); + return memusage::DynamicUsage(*static_cast(&script)); } static inline size_t RecursiveDynamicUsage(const COutPoint& out) { diff --git a/src/core_read.cpp b/src/core_read.cpp index 4be24f8e0..444a4c7eb 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/core_write.cpp b/src/core_write.cpp index 533fedfe7..b660e86c3 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index b6307cf0b..1907e2fa7 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/dbwrapper.h b/src/dbwrapper.h index 1d31ab8ae..5e7313f7e 100644 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/hash.cpp b/src/hash.cpp index 9711293e3..7f3cf1a1f 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2014 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/hash.h b/src/hash.h index 077155562..97955c8d5 100644 --- a/src/hash.h +++ b/src/hash.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -8,6 +8,7 @@ #include "crypto/ripemd160.h" #include "crypto/sha256.h" +#include "prevector.h" #include "serialize.h" #include "uint256.h" #include "version.h" @@ -118,6 +119,13 @@ inline uint160 Hash160(const std::vector& vch) return Hash160(vch.begin(), vch.end()); } +/** Compute the 160-bit hash of a vector. */ +template +inline uint160 Hash160(const prevector& vch) +{ + return Hash160(vch.begin(), vch.end()); +} + /** A writer stream (for serialization) that computes a 256-bit hash. */ class CHashWriter { diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 98ac750bb..432a5c079 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -1,17 +1,25 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "httprpc.h" #include "base58.h" #include "chainparams.h" #include "httpserver.h" -#include "rpcprotocol.h" -#include "rpcserver.h" +#include "rpc/protocol.h" +#include "rpc/server.h" #include "random.h" #include "sync.h" #include "util.h" #include "utilstrencodings.h" #include "ui_interface.h" +#include "crypto/hmac_sha256.h" +#include +#include "utilstrencodings.h" #include // boost::trim +#include //BOOST_FOREACH /** Simple one-shot callback timer to be used by the RPC mechanism to e.g. * re-lock the wellet. @@ -72,6 +80,50 @@ static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const Uni req->WriteReply(nStatus, strReply); } +//This function checks username and password against -rpcauth +//entries from config file. +static bool multiUserAuthorized(std::string strUserPass) +{ + if (strUserPass.find(":") == std::string::npos) { + return false; + } + std::string strUser = strUserPass.substr(0, strUserPass.find(":")); + std::string strPass = strUserPass.substr(strUserPass.find(":") + 1); + + if (mapMultiArgs.count("-rpcauth") > 0) { + //Search for multi-user login/pass "rpcauth" from config + BOOST_FOREACH(std::string strRPCAuth, mapMultiArgs["-rpcauth"]) + { + std::vector vFields; + boost::split(vFields, strRPCAuth, boost::is_any_of(":$")); + if (vFields.size() != 3) { + //Incorrect formatting in config file + continue; + } + + std::string strName = vFields[0]; + if (!TimingResistantEqual(strName, strUser)) { + continue; + } + + std::string strSalt = vFields[1]; + std::string strHash = vFields[2]; + + unsigned int KEY_SIZE = 32; + unsigned char *out = new unsigned char[KEY_SIZE]; + + CHMAC_SHA256(reinterpret_cast(strSalt.c_str()), strSalt.size()).Write(reinterpret_cast(strPass.c_str()), strPass.size()).Finalize(out); + std::vector hexvec(out, out+KEY_SIZE); + std::string strHashFromPass = HexStr(hexvec); + + if (TimingResistantEqual(strHashFromPass, strHash)) { + return true; + } + } + } + return false; +} + static bool RPCAuthorized(const std::string& strAuth) { if (strRPCUserColonPass.empty()) // Belt-and-suspenders measure if InitRPCAuthentication was not called @@ -81,7 +133,12 @@ static bool RPCAuthorized(const std::string& strAuth) std::string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64); std::string strUserPass = DecodeBase64(strUserPass64); - return TimingResistantEqual(strUserPass, strRPCUserColonPass); + + //Check if authorized under single-user field + if (TimingResistantEqual(strUserPass, strRPCUserColonPass)) { + return true; + } + return multiUserAuthorized(strUserPass); } static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) @@ -157,6 +214,7 @@ static bool InitRPCAuthentication() return false; } } else { + LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcuser for rpcauth auth generation."); strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; } return true; @@ -172,7 +230,7 @@ bool StartHTTPRPC() assert(EventBase()); httpRPCTimerInterface = new HTTPRPCTimerInterface(EventBase()); - RPCRegisterTimerInterface(httpRPCTimerInterface); + RPCSetTimerInterface(httpRPCTimerInterface); return true; } @@ -186,7 +244,7 @@ void StopHTTPRPC() LogPrint("rpc", "Stopping HTTP RPC server\n"); UnregisterHTTPHandler("/", true); if (httpRPCTimerInterface) { - RPCUnregisterTimerInterface(httpRPCTimerInterface); + RPCUnsetTimerInterface(httpRPCTimerInterface); delete httpRPCTimerInterface; httpRPCTimerInterface = 0; } diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 91518d7c5..ce1accb04 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -8,7 +8,7 @@ #include "compat.h" #include "util.h" #include "netbase.h" -#include "rpcprotocol.h" // For HTTP status codes +#include "rpc/protocol.h" // For HTTP status codes #include "sync.h" #include "ui_interface.h" diff --git a/src/init.cpp b/src/init.cpp index 5746fb512..4680c8f21 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -23,7 +23,7 @@ #include "miner.h" #include "net.h" #include "policy/policy.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "script/standard.h" #include "script/sigcache.h" #include "scheduler.h" @@ -65,6 +65,10 @@ using namespace std; CWallet* pwalletMain = NULL; #endif bool fFeeEstimatesInitialized = false; +static const bool DEFAULT_PROXYRANDOMIZE = true; +static const bool DEFAULT_REST_ENABLE = false; +static const bool DEFAULT_DISABLE_SAFEMODE = false; +static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; #if ENABLE_ZMQ static CZMQNotificationInterface* pzmqNotificationInterface = NULL; @@ -295,7 +299,7 @@ void OnRPCPreCommand(const CRPCCommand& cmd) { // Observe safe mode string strWarning = GetWarnings("rpc"); - if (strWarning != "" && !GetBoolArg("-disablesafemode", false) && + if (strWarning != "" && !GetBoolArg("-disablesafemode", DEFAULT_DISABLE_SAFEMODE) && !cmd.okSafeMode) throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning); } @@ -307,7 +311,8 @@ std::string HelpMessage(HelpMessageMode mode) // When adding new options to the categories, please keep and ensure alphabetical ordering. // Do not translate _(...) -help-debug options, Many technical terms, and only a very small audience, so is unnecessary stress to translators. string strUsage = HelpMessageGroup(_("Options:")); - strUsage += HelpMessageOpt("-?", _("This help message")); + strUsage += HelpMessageOpt("-?", _("Print this help message and exit")); + strUsage += HelpMessageOpt("-version", _("Print version and exit")); strUsage += HelpMessageOpt("-alerts", strprintf(_("Receive and display P2P network alerts (default: %u)"), DEFAULT_ALERTS)); strUsage += HelpMessageOpt("-alertnotify=", _("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=", _("Execute command when the best block changes (%s in cmd is replaced by block hash)")); @@ -315,7 +320,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-blocksonly", strprintf(_("Whether to operate in a blocks only mode (default: %u)"), DEFAULT_BLOCKSONLY)); strUsage += HelpMessageOpt("-checkblocks=", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), DEFAULT_CHECKBLOCKS)); strUsage += HelpMessageOpt("-checklevel=", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), DEFAULT_CHECKLEVEL)); - strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf")); + strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME)); if (mode == HMM_BITCOIND) { #ifndef WIN32 @@ -331,7 +336,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-par=", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS)); #ifndef WIN32 - strUsage += HelpMessageOpt("-pid=", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid")); + strUsage += HelpMessageOpt("-pid=", strprintf(_("Specify pid file (default: %s)"), BITCOIN_PID_FILENAME)); #endif strUsage += HelpMessageOpt("-prune=", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. " "Warning: Reverting this setting requires re-downloading the entire blockchain. " @@ -340,30 +345,34 @@ std::string HelpMessage(HelpMessageMode mode) #ifndef WIN32 strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)")); #endif - strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0)); + strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), DEFAULT_TXINDEX)); strUsage += HelpMessageGroup(_("Connection options:")); strUsage += HelpMessageOpt("-addnode=", _("Add a node to connect to and attempt to keep the connection open")); - strUsage += HelpMessageOpt("-banscore=", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100)); - strUsage += HelpMessageOpt("-bantime=", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400)); + strUsage += HelpMessageOpt("-banscore=", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), DEFAULT_BANSCORE_THRESHOLD)); + strUsage += HelpMessageOpt("-bantime=", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), DEFAULT_MISBEHAVING_BANTIME)); strUsage += HelpMessageOpt("-bind=", _("Bind to given address and always listen on it. Use [host]:port notation for IPv6")); strUsage += HelpMessageOpt("-connect=", _("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("-dns", _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + strprintf(_("(default: %u)"), DEFAULT_NAME_LOOKUP)); strUsage += HelpMessageOpt("-dnsseed", _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)")); strUsage += HelpMessageOpt("-externalip=", _("Specify your own public address")); - strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0)); + strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), DEFAULT_FORCEDNSSEED)); strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)")); strUsage += HelpMessageOpt("-listenonion", strprintf(_("Automatically create Tor hidden service (default: %d)"), DEFAULT_LISTEN_ONION)); strUsage += HelpMessageOpt("-maxconnections=", strprintf(_("Maintain at most connections to peers (default: %u)"), DEFAULT_MAX_PEER_CONNECTIONS)); - strUsage += HelpMessageOpt("-maxreceivebuffer=", strprintf(_("Maximum per-connection receive buffer, *1000 bytes (default: %u)"), 5000)); - strUsage += HelpMessageOpt("-maxsendbuffer=", strprintf(_("Maximum per-connection send buffer, *1000 bytes (default: %u)"), 1000)); + strUsage += HelpMessageOpt("-maxreceivebuffer=", strprintf(_("Maximum per-connection receive buffer, *1000 bytes (default: %u)"), DEFAULT_MAXRECEIVEBUFFER)); + strUsage += HelpMessageOpt("-maxsendbuffer=", strprintf(_("Maximum per-connection send buffer, *1000 bytes (default: %u)"), DEFAULT_MAXSENDBUFFER)); strUsage += HelpMessageOpt("-onion=", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy")); strUsage += HelpMessageOpt("-onlynet=", _("Only connect to nodes in network (ipv4, ipv6 or onion)")); - strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), 1)); - strUsage += HelpMessageOpt("-port=", strprintf(_("Listen for connections on (default: %u or testnet: %u)"), 8333, 18333)); + strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG)); + strUsage += HelpMessageOpt("-permitrbf", strprintf(_("Permit transaction replacements in the memory pool (default: %u)"), DEFAULT_PERMIT_REPLACEMENT)); + strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with bloom filters (default: %u)"), 1)); + if (showDebug) + strUsage += HelpMessageOpt("-enforcenodebloom", strprintf("Enforce minimum protocol version to limit use of bloom filters (default: %u)", 0)); + strUsage += HelpMessageOpt("-port=", strprintf(_("Listen for connections on (default: %u or testnet: %u)"), Params(CBaseChainParams::MAIN).GetDefaultPort(), Params(CBaseChainParams::TESTNET).GetDefaultPort())); strUsage += HelpMessageOpt("-proxy=", _("Connect through SOCKS5 proxy")); - strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), 1)); + strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), DEFAULT_PROXYRANDOMIZE)); strUsage += HelpMessageOpt("-seednode=", _("Connect to a node to retrieve peer addresses, and disconnect")); strUsage += HelpMessageOpt("-timeout=", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT)); strUsage += HelpMessageOpt("-torcontrol=:", strprintf(_("Tor control port to use if onion listening enabled (default: %s)"), DEFAULT_TOR_CONTROL)); @@ -378,28 +387,28 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-whitebind=", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6")); strUsage += HelpMessageOpt("-whitelist=", _("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")); - strUsage += HelpMessageOpt("-whitelistalwaysrelay", strprintf(_("Always relay transactions received from whitelisted peers (default: %d)"), DEFAULT_WHITELISTALWAYSRELAY)); + strUsage += HelpMessageOpt("-whitelistrelay", strprintf(_("Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)"), DEFAULT_WHITELISTRELAY)); + strUsage += HelpMessageOpt("-whitelistforcerelay", strprintf(_("Force relay of transactions from whitelisted peers even they violate local relay policy (default: %d)"), DEFAULT_WHITELISTFORCERELAY)); strUsage += HelpMessageOpt("-maxuploadtarget=", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET)); #ifdef ENABLE_WALLET strUsage += HelpMessageGroup(_("Wallet options:")); strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); - strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), 100)); - if (showDebug) - strUsage += HelpMessageOpt("-mintxfee=", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)", + strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), DEFAULT_KEYPOOL_SIZE)); + strUsage += HelpMessageOpt("-fallbackfee=", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE))); + strUsage += HelpMessageOpt("-mintxfee=", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"), CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE))); strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, 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("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); + strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); - strUsage += HelpMessageOpt("-maxtxfee=", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"), - CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE))); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat")); - strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), true)); + strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); strUsage += HelpMessageOpt("-walletnotify=", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); strUsage += HelpMessageOpt("-zapwallettxes=", _("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)")); @@ -408,55 +417,66 @@ std::string HelpMessage(HelpMessageMode mode) #if ENABLE_ZMQ strUsage += HelpMessageGroup(_("ZeroMQ notification options:")); strUsage += HelpMessageOpt("-zmqpubhashblock=
", _("Enable publish hash block in
")); - strUsage += HelpMessageOpt("-zmqpubhashtransaction=
", _("Enable publish hash transaction in
")); + strUsage += HelpMessageOpt("-zmqpubhashtx=
", _("Enable publish hash transaction in
")); strUsage += HelpMessageOpt("-zmqpubrawblock=
", _("Enable publish raw block in
")); - strUsage += HelpMessageOpt("-zmqpubrawtransaction=
", _("Enable publish raw transaction in
")); + strUsage += HelpMessageOpt("-zmqpubrawtx=
", _("Enable publish raw transaction in
")); #endif strUsage += HelpMessageGroup(_("Debugging/Testing options:")); + strUsage += HelpMessageOpt("-uacomment=", _("Append comment to the user agent string")); if (showDebug) { - strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", 1)); + strUsage += HelpMessageOpt("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. Also sets -checkmempool (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks())); + strUsage += HelpMessageOpt("-checkmempool=", strprintf("Run checks every transactions (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks())); + strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED)); #ifdef ENABLE_WALLET strUsage += HelpMessageOpt("-dblogsize=", strprintf("Flush wallet database activity from memory to disk log every megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); #endif - 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("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", DEFAULT_DISABLE_SAFEMODE)); + strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", DEFAULT_TESTSAFEMODE)); strUsage += HelpMessageOpt("-dropmessagestest=", "Randomly drop 1 of every network messages"); strUsage += HelpMessageOpt("-fuzzmessagestest=", "Randomly fuzz 1 of every network messages"); #ifdef ENABLE_WALLET - strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", 1)); + strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET)); #endif - strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0)); + strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", DEFAULT_STOPAFTERBLOCKIMPORT)); strUsage += HelpMessageOpt("-limitancestorcount=", strprintf("Do not accept transactions if number of in-mempool ancestors is or more (default: %u)", DEFAULT_ANCESTOR_LIMIT)); strUsage += HelpMessageOpt("-limitancestorsize=", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT)); strUsage += HelpMessageOpt("-limitdescendantcount=", strprintf("Do not accept transactions if any ancestor would have or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT)); strUsage += HelpMessageOpt("-limitdescendantsize=", strprintf("Do not accept transactions if any ancestor would have more than kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT)); } - string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, mempoolrej, net, proxy, prune, http, libevent"; // Don't translate these and qt below + string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, mempoolrej, net, proxy, prune, http, libevent, tor, zmq"; // Don't translate these and qt below if (mode == HMM_BITCOIN_QT) debugCategories += ", qt"; strUsage += HelpMessageOpt("-debug=", strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + ". " + _("If is not supplied or if = 1, output all debugging information.") + _(" can be:") + " " + debugCategories + "."); - strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0)); + if (showDebug) + strUsage += HelpMessageOpt("-nodebug", "Turn off debugging messages, same as -debug=0"); + strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), DEFAULT_GENERATE)); strUsage += HelpMessageOpt("-genproclimit=", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), DEFAULT_GENERATE_THREADS)); 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)); + strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), DEFAULT_LOGIPS)); + strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), DEFAULT_LOGTIMESTAMPS)); if (showDebug) { strUsage += HelpMessageOpt("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS)); - strUsage += HelpMessageOpt("-limitfreerelay=", strprintf("Continuously rate-limit free transactions to *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("-mocktime=", "Replace actual time with seconds since epoch (default: 0)"); + strUsage += HelpMessageOpt("-limitfreerelay=", strprintf("Continuously rate-limit free transactions to *1000 bytes per minute (default: %u)", DEFAULT_LIMITFREERELAY)); + strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", DEFAULT_RELAYPRIORITY)); strUsage += HelpMessageOpt("-maxsigcachesize=", strprintf("Limit size of signature cache to MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE)); + strUsage += HelpMessageOpt("-maxtipage=", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE)); } strUsage += HelpMessageOpt("-minrelaytxfee=", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)"), CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE))); + strUsage += HelpMessageOpt("-maxtxfee=", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE))); strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file")); if (showDebug) { - 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("-printpriority", strprintf("Log transaction priority and fee per kB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY)); +#ifdef ENABLE_WALLET + strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB)); +#endif } strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)")); @@ -465,11 +485,12 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageGroup(_("Node relay options:")); if (showDebug) strUsage += HelpMessageOpt("-acceptnonstdtxn", strprintf("Relay and mine \"non-standard\" transactions (%sdefault: %u)", "testnet/regtest only; ", !Params(CBaseChainParams::TESTNET).RequireStandard())); - strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1)); + strUsage += HelpMessageOpt("-bytespersigop", strprintf(_("Minimum bytes per sigop in transactions we relay and mine (default: %u)"), DEFAULT_BYTES_PER_SIGOP)); + strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), DEFAULT_ACCEPT_DATACARRIER)); strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY)); strUsage += HelpMessageGroup(_("Block creation options:")); - strUsage += HelpMessageOpt("-blockminsize=", strprintf(_("Set minimum block size in bytes (default: %u)"), 0)); + strUsage += HelpMessageOpt("-blockminsize=", strprintf(_("Set minimum block size in bytes (default: %u)"), DEFAULT_BLOCK_MIN_SIZE)); strUsage += HelpMessageOpt("-blockmaxsize=", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockprioritysize=", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); if (showDebug) @@ -477,11 +498,13 @@ std::string HelpMessage(HelpMessageMode mode) 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("-rest", strprintf(_("Accept public REST requests (default: %u)"), DEFAULT_REST_ENABLE)); strUsage += HelpMessageOpt("-rpcbind=", _("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("-rpccookiefile=", _("Location of the auth cookie (default: data dir)")); strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcpassword=", _("Password for JSON-RPC connections")); - strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), 8332, 18332)); + strUsage += HelpMessageOpt("-rpcauth=", _("Username and hashed password for JSON-RPC connections. The field comes in the format: :$. A canonical python script is included in share/rpcuser. This option can be specified multiple times")); + strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), BaseParams(CBaseChainParams::MAIN).RPCPort(), BaseParams(CBaseChainParams::TESTNET).RPCPort())); strUsage += HelpMessageOpt("-rpcallowip=", _("Allow JSON-RPC connections from specified source. Valid for 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=", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS)); if (showDebug) { @@ -489,23 +512,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-rpcservertimeout=", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT)); } - if (mode == HMM_BITCOIN_QT) - { - strUsage += HelpMessageGroup(_("UI Options:")); - if (showDebug) { - strUsage += HelpMessageOpt("-allowselfsignedrootcertificates", "Allow self signed root certificates (default: 0)"); - } - strUsage += HelpMessageOpt("-choosedatadir", _("Choose data directory on startup (default: 0)")); - strUsage += HelpMessageOpt("-lang=", _("Set language, for example \"de_DE\" (default: system locale)")); - strUsage += HelpMessageOpt("-min", _("Start minimized")); - strUsage += HelpMessageOpt("-rootcertificates=", _("Set SSL root certificates for payment request (default: -system-)")); - strUsage += HelpMessageOpt("-splash", _("Show splash screen on startup (default: 1)")); - strUsage += HelpMessageOpt("-resetguisettings", _("Reset all settings changes made over the GUI")); - if (showDebug) { - strUsage += HelpMessageOpt("-uiplatform", "Select platform to customize UI for (one of windows, macosx, other; default: platform compiled on)"); - } - } - return strUsage; } @@ -522,11 +528,14 @@ std::string LicenseInfo() "\n"; } -static void BlockNotifyCallback(const uint256& hashNewTip) +static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex) { + if (initialSync || !pBlockIndex) + return; + std::string strCmd = GetArg("-blocknotify", ""); - boost::replace_all(strCmd, "%s", hashNewTip.GetHex()); + boost::replace_all(strCmd, "%s", pBlockIndex->GetBlockHash().GetHex()); boost::thread t(runCommand, strCmd); // thread runs free } @@ -588,6 +597,7 @@ void CleanupBlockRevFiles() void ThreadImport(std::vector vImportFiles) { + const CChainParams& chainparams = Params(); RenameThread("bitcoin-loadblk"); // -reindex if (fReindex) { @@ -601,14 +611,14 @@ void ThreadImport(std::vector vImportFiles) if (!file) break; // This error is logged in OpenBlockFile LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile); - LoadExternalBlockFile(file, &pos); + LoadExternalBlockFile(chainparams, file, &pos); nFile++; } pblocktree->WriteReindexing(false); fReindex = false; LogPrintf("Reindexing finished\n"); // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked): - InitBlockIndex(); + InitBlockIndex(chainparams); } // hardcoded $DATADIR/bootstrap.dat @@ -619,7 +629,7 @@ void ThreadImport(std::vector vImportFiles) CImportingNow imp; boost::filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old"; LogPrintf("Importing bootstrap.dat...\n"); - LoadExternalBlockFile(file); + LoadExternalBlockFile(chainparams, file); RenameOver(pathBootstrap, pathBootstrapOld); } else { LogPrintf("Warning: Could not open bootstrap file %s\n", pathBootstrap.string()); @@ -632,13 +642,13 @@ void ThreadImport(std::vector vImportFiles) if (file) { CImportingNow imp; LogPrintf("Importing blocks file %s...\n", path.string()); - LoadExternalBlockFile(file); + LoadExternalBlockFile(chainparams, file); } else { LogPrintf("Warning: Could not open blocks file %s\n", path.string()); } } - if (GetBoolArg("-stopafterblockimport", false)) { + if (GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) { LogPrintf("Stopping after block import\n"); StartShutdown(); } @@ -670,13 +680,114 @@ bool AppInitServers(boost::thread_group& threadGroup) return false; if (!StartHTTPRPC()) return false; - if (GetBoolArg("-rest", false) && !StartREST()) + if (GetBoolArg("-rest", DEFAULT_REST_ENABLE) && !StartREST()) return false; if (!StartHTTPServer()) return false; return true; } +// Parameter interaction based on rules +void InitParameterInteraction() +{ + // when specifying an explicit binding address, you want to listen on it + // even when -connect or -proxy is specified + if (mapArgs.count("-bind")) { + if (SoftSetBoolArg("-listen", true)) + LogPrintf("%s: parameter interaction: -bind set -> setting -listen=1\n", __func__); + } + if (mapArgs.count("-whitebind")) { + if (SoftSetBoolArg("-listen", true)) + LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__); + } + + if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) { + // when only connecting to trusted nodes, do not seed via DNS, or listen by default + if (SoftSetBoolArg("-dnsseed", false)) + LogPrintf("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__); + if (SoftSetBoolArg("-listen", false)) + LogPrintf("%s: parameter interaction: -connect set -> setting -listen=0\n", __func__); + } + + if (mapArgs.count("-proxy")) { + // to protect privacy, do not listen by default if a default proxy server is specified + if (SoftSetBoolArg("-listen", false)) + LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__); + // to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1 + // to listen locally, so don't rely on this happening through -listen below. + if (SoftSetBoolArg("-upnp", false)) + LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__); + // to protect privacy, do not discover addresses by default + if (SoftSetBoolArg("-discover", false)) + LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__); + } + + if (!GetBoolArg("-listen", DEFAULT_LISTEN)) { + // do not map ports or try to retrieve public IP when not listening (pointless) + if (SoftSetBoolArg("-upnp", false)) + LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__); + if (SoftSetBoolArg("-discover", false)) + LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__); + if (SoftSetBoolArg("-listenonion", false)) + LogPrintf("%s: parameter interaction: -listen=0 -> setting -listenonion=0\n", __func__); + } + + if (mapArgs.count("-externalip")) { + // if an explicit public IP is specified, do not try to find others + if (SoftSetBoolArg("-discover", false)) + LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__); + } + + if (GetBoolArg("-salvagewallet", false)) { + // Rewrite just private keys: rescan to find transactions + if (SoftSetBoolArg("-rescan", true)) + LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); + } + + // -zapwallettx implies a rescan + if (GetBoolArg("-zapwallettxes", false)) { + if (SoftSetBoolArg("-rescan", true)) + LogPrintf("%s: parameter interaction: -zapwallettxes= -> setting -rescan=1\n", __func__); + } + + // disable walletbroadcast and whitelistrelay in blocksonly mode + if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) { + if (SoftSetBoolArg("-whitelistrelay", false)) + LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistrelay=0\n", __func__); +#ifdef ENABLE_WALLET + if (SoftSetBoolArg("-walletbroadcast", false)) + LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__); +#endif + } + + // Forcing relay from whitelisted hosts implies we will accept relays from them in the first place. + if (GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) { + if (SoftSetBoolArg("-whitelistrelay", true)) + LogPrintf("%s: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1\n", __func__); + } +} + +static std::string ResolveErrMsg(const char * const optname, const std::string& strBind) +{ + return strprintf(_("Cannot resolve -%s address: '%s'"), optname, strBind); +} + +static std::string AmountErrMsg(const char * const optname, const std::string& strValue) +{ + return strprintf(_("Invalid amount for -%s=: '%s'"), optname, strValue); +} + +void InitLogging() +{ + fPrintToConsole = GetBoolArg("-printtoconsole", false); + fLogTimestamps = GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); + fLogTimeMicros = GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); + fLogIPs = GetBoolArg("-logips", DEFAULT_LOGIPS); + + LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + LogPrintf("Bitcoin version %s (%s)\n", FormatFullVersion(), CLIENT_DATE); +} + /** Initialize bitcoin. * @pre Parameters should be parsed and config file should be read. */ @@ -741,78 +852,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 2: parameter interactions const CChainParams& chainparams = Params(); - // Set this early so that parameter interactions go to console - fPrintToConsole = GetBoolArg("-printtoconsole", false); - fLogTimestamps = GetBoolArg("-logtimestamps", true); - fLogTimeMicros = GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); - fLogIPs = GetBoolArg("-logips", false); - - LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - LogPrintf("Bitcoin version %s (%s)\n", FormatFullVersion(), CLIENT_DATE); - - // when specifying an explicit binding address, you want to listen on it - // even when -connect or -proxy is specified - if (mapArgs.count("-bind")) { - if (SoftSetBoolArg("-listen", true)) - LogPrintf("%s: parameter interaction: -bind set -> setting -listen=1\n", __func__); - } - if (mapArgs.count("-whitebind")) { - if (SoftSetBoolArg("-listen", true)) - LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__); - } - - if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) { - // when only connecting to trusted nodes, do not seed via DNS, or listen by default - if (SoftSetBoolArg("-dnsseed", false)) - LogPrintf("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__); - if (SoftSetBoolArg("-listen", false)) - LogPrintf("%s: parameter interaction: -connect set -> setting -listen=0\n", __func__); - } - - if (mapArgs.count("-proxy")) { - // to protect privacy, do not listen by default if a default proxy server is specified - if (SoftSetBoolArg("-listen", false)) - LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__); - // to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1 - // to listen locally, so don't rely on this happening through -listen below. - if (SoftSetBoolArg("-upnp", false)) - LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__); - // to protect privacy, do not discover addresses by default - if (SoftSetBoolArg("-discover", false)) - LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__); - } - - if (!GetBoolArg("-listen", DEFAULT_LISTEN)) { - // do not map ports or try to retrieve public IP when not listening (pointless) - if (SoftSetBoolArg("-upnp", false)) - LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__); - if (SoftSetBoolArg("-discover", false)) - LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__); - if (SoftSetBoolArg("-listenonion", false)) - LogPrintf("%s: parameter interaction: -listen=0 -> setting -listenonion=0\n", __func__); - } - - if (mapArgs.count("-externalip")) { - // if an explicit public IP is specified, do not try to find others - if (SoftSetBoolArg("-discover", false)) - LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__); - } - - if (GetBoolArg("-salvagewallet", false)) { - // Rewrite just private keys: rescan to find transactions - if (SoftSetBoolArg("-rescan", true)) - LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); - } - - // -zapwallettx implies a rescan - if (GetBoolArg("-zapwallettxes", false)) { - if (SoftSetBoolArg("-rescan", true)) - LogPrintf("%s: parameter interaction: -zapwallettxes= -> setting -rescan=1\n", __func__); - } + // also see: InitParameterInteraction() // if using block pruning, then disable txindex if (GetArg("-prune", 0)) { - if (GetBoolArg("-txindex", false)) + if (GetBoolArg("-txindex", DEFAULT_TXINDEX)) return InitError(_("Prune mode is incompatible with -txindex.")); #ifdef ENABLE_WALLET if (GetBoolArg("-rescan", false)) { @@ -821,16 +865,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) #endif } - // disable walletbroadcast and whitelistalwaysrelay in blocksonly mode - if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) { - if (SoftSetBoolArg("-whitelistalwaysrelay", false)) - LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistalwaysrelay=0\n", __func__); -#ifdef ENABLE_WALLET - if (SoftSetBoolArg("-walletbroadcast", false)) - LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__); -#endif - } - // Make sure enough file descriptors are available int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1); int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); @@ -867,19 +901,22 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (GetBoolArg("-benchmark", false)) InitWarning(_("Unsupported argument -benchmark ignored, use -debug=bench.")); + if (GetBoolArg("-whitelistalwaysrelay", false)) + InitWarning(_("Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay.")); + // Checkmempool and checkblockindex default to true in regtest mode int ratio = std::min(std::max(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); if (ratio != 0) { mempool.setSanityCheck(1.0 / ratio); } fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks()); - fCheckpointsEnabled = GetBoolArg("-checkpoints", true); + fCheckpointsEnabled = GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED); - // -mempoollimit limits - int64_t nMempoolSizeLimit = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; - int64_t nMempoolDescendantSizeLimit = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000; - if (nMempoolSizeLimit < 0 || nMempoolSizeLimit < nMempoolDescendantSizeLimit * 40) - return InitError(strprintf(_("-maxmempool must be at least %d MB"), GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) / 25)); + // mempool limits + int64_t nMempoolSizeMax = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; + int64_t nMempoolSizeMin = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000 * 40; + if (nMempoolSizeMax < 0 || nMempoolSizeMax < nMempoolSizeMin) + return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(nMempoolSizeMin / 1000000.0))); // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS); @@ -908,6 +945,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) #ifdef ENABLE_WALLET bool fDisableWallet = GetBoolArg("-disablewallet", false); + if (!fDisableWallet) + walletRegisterRPCCommands(); #endif nConnectTimeout = GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT); @@ -926,12 +965,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0) ::minRelayTxFee = CFeeRate(n); else - return InitError(strprintf(_("Invalid amount for -minrelaytxfee=: '%s'"), mapArgs["-minrelaytxfee"])); + return InitError(AmountErrMsg("minrelaytxfee", mapArgs["-minrelaytxfee"])); } fRequireStandard = !GetBoolArg("-acceptnonstdtxn", !Params().RequireStandard()); if (Params().RequireStandard() && !fRequireStandard) return InitError(strprintf("acceptnonstdtxn is not currently supported for %s chain", chainparams.NetworkIDString())); + nBytesPerSigOp = GetArg("-bytespersigop", nBytesPerSigOp); #ifdef ENABLE_WALLET if (mapArgs.count("-mintxfee")) @@ -940,14 +980,23 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0) CWallet::minTxFee = CFeeRate(n); else - return InitError(strprintf(_("Invalid amount for -mintxfee=: '%s'"), mapArgs["-mintxfee"])); + return InitError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"])); + } + if (mapArgs.count("-fallbackfee")) + { + CAmount nFeePerK = 0; + if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK)) + return InitError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), mapArgs["-fallbackfee"])); + if (nFeePerK > HIGH_TX_FEE_PER_KB) + InitWarning(_("-fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available.")); + CWallet::fallbackFee = CFeeRate(nFeePerK); } if (mapArgs.count("-paytxfee")) { CAmount nFeePerK = 0; if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK)) - return InitError(strprintf(_("Invalid amount for -paytxfee=: '%s'"), mapArgs["-paytxfee"])); - if (nFeePerK > nHighTransactionFeeWarning) + return InitError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"])); + if (nFeePerK > HIGH_TX_FEE_PER_KB) InitWarning(_("-paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); payTxFee = CFeeRate(nFeePerK, 1000); if (payTxFee < ::minRelayTxFee) @@ -960,8 +1009,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) { CAmount nMaxFee = 0; if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee)) - return InitError(strprintf(_("Invalid amount for -maxtxfee=: '%s'"), mapArgs["-maptxfee"])); - if (nMaxFee > nHighTransactionMaxFeeWarning) + return InitError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"])); + if (nMaxFee > HIGH_MAX_TX_FEE) InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); maxTxFee = nMaxFee; if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) @@ -971,13 +1020,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); - bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", true); - fSendFreeTransactions = GetBoolArg("-sendfreetransactions", false); + bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); + fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS); std::string strWalletFile = GetArg("-wallet", "wallet.dat"); #endif // ENABLE_WALLET - fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", true); + fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); + fAcceptDatacarrier = GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER); nMaxDatacarrierBytes = GetArg("-datacarriersize", nMaxDatacarrierBytes); fAlerts = GetBoolArg("-alerts", DEFAULT_ALERTS); @@ -988,6 +1038,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (GetBoolArg("-peerbloomfilters", true)) nLocalServices |= NODE_BLOOM; + nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); + fPermitReplacement = GetBoolArg("-permitrbf", DEFAULT_PERMIT_REPLACEMENT); + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // Initialize elliptic curve code @@ -1026,7 +1079,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (fPrintToDebugLog) OpenDebugLog(); +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); +#else + LogPrintf("Using OpenSSL version %s\n", OpenSSL_version(OPENSSL_VERSION)); +#endif + #ifdef ENABLE_WALLET LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0)); #endif @@ -1123,7 +1181,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } - bool proxyRandomize = GetBoolArg("-proxyrandomize", true); + bool proxyRandomize = GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE); // -proxy sets a proxy for all outgoing network traffic // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default std::string proxyArg = GetArg("-proxy", ""); @@ -1158,7 +1216,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // see Step 2: parameter interactions for more information about these fListen = GetBoolArg("-listen", DEFAULT_LISTEN); fDiscover = GetBoolArg("-discover", true); - fNameLookup = GetBoolArg("-dns", true); + fNameLookup = GetBoolArg("-dns", DEFAULT_NAME_LOOKUP); bool fBound = false; if (fListen) { @@ -1166,13 +1224,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-bind"]) { CService addrBind; if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) - return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind)); + return InitError(ResolveErrMsg("bind", strBind)); fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR)); } BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-whitebind"]) { CService addrBind; if (!Lookup(strBind.c_str(), addrBind, 0, false)) - return InitError(strprintf(_("Cannot resolve -whitebind address: '%s'"), strBind)); + return InitError(ResolveErrMsg("whitebind", strBind)); if (addrBind.GetPort() == 0) return InitError(strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind)); fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST)); @@ -1192,7 +1250,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-externalip"]) { CService addrLocal(strAddr, GetListenPort(), fNameLookup); if (!addrLocal.IsValid()) - return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr)); + return InitError(ResolveErrMsg("externalip", strAddr)); AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL); } } @@ -1247,7 +1305,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greated than nMaxDbcache int64_t nBlockTreeDBCache = nTotalCache / 8; - if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", false)) + if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", DEFAULT_TXINDEX)) nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB nTotalCache -= nBlockTreeDBCache; int64_t nCoinDBCache = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache @@ -1297,13 +1355,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?")); // Initialize the block index (no-op if non-empty database was already loaded) - if (!InitBlockIndex()) { + if (!InitBlockIndex(chainparams)) { strLoadError = _("Error initializing block database"); break; } // Check for changed -txindex state - if (fTxIndex != GetBoolArg("-txindex", false)) { + if (fTxIndex != GetBoolArg("-txindex", DEFAULT_TXINDEX)) { strLoadError = _("You need to rebuild the database using -reindex to change -txindex"); break; } @@ -1332,7 +1390,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } - if (!CVerifyDB().VerifyDB(pcoinsdbview, GetArg("-checklevel", DEFAULT_CHECKLEVEL), + if (!CVerifyDB().VerifyDB(chainparams, pcoinsdbview, GetArg("-checklevel", DEFAULT_CHECKLEVEL), GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) { strLoadError = _("Corrupted block database detected"); break; @@ -1529,7 +1587,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } } - pwalletMain->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", true)); + pwalletMain->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST)); } // (!fDisableWallet) #else // ENABLE_WALLET LogPrintf("No wallet support compiled in!\n"); @@ -1556,7 +1614,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) uiInterface.InitMessage(_("Activating best chain...")); // scan for better chains in the block chain database, that are not yet connected in the active best chain CValidationState state; - if (!ActivateBestChain(state)) + if (!ActivateBestChain(state, chainparams)) strErrors << "Failed to connect best block"; std::vector vImportFiles; @@ -1603,7 +1661,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) scheduler.scheduleEvery(f, nPowTargetSpacing); // Generate coins in the background - GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", DEFAULT_GENERATE_THREADS), chainparams); + GenerateBitcoins(GetBoolArg("-gen", DEFAULT_GENERATE), GetArg("-genproclimit", DEFAULT_GENERATE_THREADS), chainparams); // ********************************************************* Step 12: finished diff --git a/src/init.h b/src/init.h index 8cd51b028..af1b94b72 100644 --- a/src/init.h +++ b/src/init.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -23,6 +23,10 @@ bool ShutdownRequested(); /** Interrupt threads */ void Interrupt(boost::thread_group& threadGroup); void Shutdown(); +//!Initialize the logging infrastructure +void InitLogging(); +//!Parameter interaction: change current parameters depending on various rules +void InitParameterInteraction(); bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler); /** The help message mode determines what help message to show */ diff --git a/src/key.cpp b/src/key.cpp index a24fa8a4b..28ba5144e 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/key.h b/src/key.h index 021eac2a8..6c820d49c 100644 --- a/src/key.h +++ b/src/key.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/keystore.cpp b/src/keystore.cpp index cf49ba83a..cc8a57336 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/keystore.h b/src/keystore.h index b917bf20b..d9290722e 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/limitedmap.h b/src/limitedmap.h index 5456dfc7c..4d9bb4fa2 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/main.cpp b/src/main.cpp index 2579b642b..4d16b9f9a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,6 +12,7 @@ #include "checkpoints.h" #include "checkqueue.h" #include "consensus/consensus.h" +#include "consensus/merkle.h" #include "consensus/validation.h" #include "hash.h" #include "init.h" @@ -66,16 +67,19 @@ bool fReindex = false; bool fTxIndex = false; bool fHavePruned = false; bool fPruneMode = false; -bool fIsBareMultisigStd = true; +bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG; bool fRequireStandard = true; +unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP; bool fCheckBlockIndex = false; -bool fCheckpointsEnabled = true; +bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED; size_t nCoinCacheUsage = 5000 * 300; uint64_t nPruneTarget = 0; bool fAlerts = DEFAULT_ALERTS; +int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; +bool fPermitReplacement = DEFAULT_PERMIT_REPLACEMENT; -/** Fees smaller than this (in satoshi) are considered zero fee (for relaying, mining and transaction creation) */ CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); +CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; CTxMemPool mempool(::minRelayTxFee); @@ -83,8 +87,8 @@ struct COrphanTx { CTransaction tx; NodeId fromPeer; }; -map mapOrphanTransactions GUARDED_BY(cs_main);; -map > mapOrphanTransactionsByPrev GUARDED_BY(cs_main);; +map mapOrphanTransactions GUARDED_BY(cs_main); +map > mapOrphanTransactionsByPrev GUARDED_BY(cs_main); void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** @@ -133,9 +137,9 @@ namespace { set setBlockIndexCandidates; /** Number of nodes with fSyncStarted. */ int nSyncStarted = 0; - /** All pairs A->B, where A (or one if its ancestors) misses transactions, but B has transactions. - * Pruned nodes may have entries where B is missing data. - */ + /** All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions. + * Pruned nodes may have entries where B is missing data. + */ multimap mapBlocksUnlinked; CCriticalSection cs_LastBlockFile; @@ -180,7 +184,7 @@ namespace { * million to make it highly unlikely for users to have issues with this * filter. * - * Memory used: 1.7MB + * Memory used: 1.3 MB */ boost::scoped_ptr recentRejects; uint256 hashRecentRejectsChainTip; @@ -246,6 +250,8 @@ struct CNodeState { uint256 hashLastUnknownBlock; //! The last full block we both have. CBlockIndex *pindexLastCommonBlock; + //! The best header we have sent our peer. + CBlockIndex *pindexBestHeaderSent; //! Whether we've started headers synchronization with this peer. bool fSyncStarted; //! Since when we're stalling block download progress (in microseconds), or 0. @@ -255,6 +261,8 @@ struct CNodeState { int nBlocksInFlightValidHeaders; //! Whether we consider this a preferred download peer. bool fPreferredDownload; + //! Whether this peer wants invs or headers (when possible) for block announcements. + bool fPreferHeaders; CNodeState() { fCurrentlyConnected = false; @@ -263,11 +271,13 @@ struct CNodeState { pindexBestKnownBlock = NULL; hashLastUnknownBlock.SetNull(); pindexLastCommonBlock = NULL; + pindexBestHeaderSent = NULL; fSyncStarted = false; nStallingSince = 0; nBlocksInFlight = 0; nBlocksInFlightValidHeaders = 0; fPreferredDownload = false; + fPreferHeaders = false; } }; @@ -397,6 +407,22 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) { } } +// Requires cs_main +bool CanDirectFetch(const Consensus::Params &consensusParams) +{ + return chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - consensusParams.nPowTargetSpacing * 20; +} + +// Requires cs_main +bool PeerHasHeader(CNodeState *state, CBlockIndex *pindex) +{ + if (state->pindexBestKnownBlock && pindex == state->pindexBestKnownBlock->GetAncestor(pindex->nHeight)) + return true; + if (state->pindexBestHeaderSent && pindex == state->pindexBestHeaderSent->GetAncestor(pindex->nHeight)) + return true; + return false; +} + /** Find the last common ancestor two blocks have. * Both pa and pb must be non-NULL. */ CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) { @@ -766,34 +792,19 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) return true; } -CAmount GetMinRelayFee(const CTransaction& tx, const CTxMemPool& pool, unsigned int nBytes, bool fAllowFree) -{ - uint256 hash = tx.GetHash(); - double dPriorityDelta = 0; - CAmount nFeeDelta = 0; - pool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta); - if (dPriorityDelta > 0 || nFeeDelta > 0) - return 0; +void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age) { + int expired = pool.Expire(GetTime() - age); + if (expired != 0) + LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired); - CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes); - - if (fAllowFree) - { - // There is a free transaction area in blocks created by most miners, - // * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000 - // to be considered to fall into this category. We don't want to encourage sending - // multiple transactions instead of one big transaction to avoid fees. - if (nBytes < (DEFAULT_BLOCK_PRIORITY_SIZE - 1000)) - nMinFee = 0; - } - - if (!MoneyRange(nMinFee)) - nMinFee = MAX_MONEY; - return nMinFee; + std::vector vNoSpendsRemaining; + pool.TrimToSize(limit, &vNoSpendsRemaining); + BOOST_FOREACH(const uint256& removed, vNoSpendsRemaining) + pcoinsTip->Uncache(removed); } /** Convert CValidationState to a human-readable message for logging */ -static std::string FormatStateMessage(const CValidationState &state) +std::string FormatStateMessage(const CValidationState &state) { return strprintf("%s%s (code %i)", state.GetRejectReason(), @@ -801,15 +812,17 @@ static std::string FormatStateMessage(const CValidationState &state) state.GetRejectCode()); } -bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, - bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee) +bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, + bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee, + std::vector& vHashTxnToUncache) { + const uint256 hash = tx.GetHash(); AssertLockHeld(cs_main); if (pfMissingInputs) *pfMissingInputs = false; if (!CheckTransaction(tx, state)) - return false; + return error("%s: CheckTransaction: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) @@ -827,20 +840,49 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return state.DoS(0, false, REJECT_NONSTANDARD, "non-final"); // is it already in the memory pool? - uint256 hash = tx.GetHash(); if (pool.exists(hash)) return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-in-mempool"); // Check for conflicts with in-memory transactions + set setConflicts; { LOCK(pool.cs); // protect pool.mapNextTx - for (unsigned int i = 0; i < tx.vin.size(); i++) + BOOST_FOREACH(const CTxIn &txin, tx.vin) { - COutPoint outpoint = tx.vin[i].prevout; - if (pool.mapNextTx.count(outpoint)) + if (pool.mapNextTx.count(txin.prevout)) { - // Disable replacement feature for now - return state.Invalid(false, REJECT_CONFLICT, "txn-mempool-conflict"); + const CTransaction *ptxConflicting = pool.mapNextTx[txin.prevout].ptx; + if (!setConflicts.count(ptxConflicting->GetHash())) + { + // Allow opt-out of transaction replacement by setting + // nSequence >= maxint-1 on all inputs. + // + // maxint-1 is picked to still allow use of nLockTime by + // non-replacable transactions. All inputs rather than just one + // is for the sake of multi-party protocols, where we don't + // want a single party to be able to disable replacement. + // + // The opt-out ignores descendants as anyone relying on + // first-seen mempool behavior should be checking all + // unconfirmed ancestors anyway; doing otherwise is hopelessly + // insecure. + bool fReplacementOptOut = true; + if (fPermitReplacement) + { + BOOST_FOREACH(const CTxIn &txin, ptxConflicting->vin) + { + if (txin.nSequence < std::numeric_limits::max()-1) + { + fReplacementOptOut = false; + break; + } + } + } + if (fReplacementOptOut) + return state.Invalid(false, REJECT_CONFLICT, "txn-mempool-conflict"); + + setConflicts.insert(ptxConflicting->GetHash()); + } } } } @@ -856,13 +898,19 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa view.SetBackend(viewMemPool); // do we already have it? - if (view.HaveCoins(hash)) + bool fHadTxInCache = pcoinsTip->HaveCoinsInCache(hash); + if (view.HaveCoins(hash)) { + if (!fHadTxInCache) + vHashTxnToUncache.push_back(hash); return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-known"); + } // do all inputs exist? // Note that this does not check for the presence of actual outputs (see the next check for that), // and only helps with filling in pfMissingInputs (to determine missing vs spent). BOOST_FOREACH(const CTxIn txin, tx.vin) { + if (!pcoinsTip->HaveCoinsInCache(txin.prevout.hash)) + vHashTxnToUncache.push_back(txin.prevout.hash); if (!view.HaveCoins(txin.prevout.hash)) { if (pfMissingInputs) *pfMissingInputs = true; @@ -887,34 +935,46 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if (fRequireStandard && !AreInputsStandard(tx, view)) return state.Invalid(false, REJECT_NONSTANDARD, "bad-txns-nonstandard-inputs"); + unsigned int nSigOps = GetLegacySigOpCount(tx); + nSigOps += GetP2SHSigOpCount(tx, view); + + CAmount nValueOut = tx.GetValueOut(); + CAmount nFees = nValueIn-nValueOut; + // nModifiedFees includes any fee deltas from PrioritiseTransaction + CAmount nModifiedFees = nFees; + double nPriorityDummy = 0; + pool.ApplyDeltas(hash, nPriorityDummy, nModifiedFees); + + CAmount inChainInputValue; + double dPriority = view.GetPriority(tx, chainActive.Height(), inChainInputValue); + + // Keep track of transactions that spend a coinbase, which we re-scan + // during reorgs to ensure COINBASE_MATURITY is still met. + bool fSpendsCoinbase = false; + BOOST_FOREACH(const CTxIn &txin, tx.vin) { + const CCoins *coins = view.AccessCoins(txin.prevout.hash); + if (coins->IsCoinBase()) { + fSpendsCoinbase = true; + break; + } + } + + CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOps); + unsigned int nSize = entry.GetTxSize(); + // Check that the transaction doesn't have an excessive number of // sigops, making it impossible to mine. Since the coinbase transaction // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than // merely non-standard transaction. - unsigned int nSigOps = GetLegacySigOpCount(tx); - nSigOps += GetP2SHSigOpCount(tx, view); - if (nSigOps > MAX_STANDARD_TX_SIGOPS) + if ((nSigOps > MAX_STANDARD_TX_SIGOPS) || (nBytesPerSigOp && nSigOps > nSize / nBytesPerSigOp)) return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false, - strprintf("%d > %d", nSigOps, MAX_STANDARD_TX_SIGOPS)); - - CAmount nValueOut = tx.GetValueOut(); - CAmount nFees = nValueIn-nValueOut; - double dPriority = view.GetPriority(tx, chainActive.Height()); - - CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), pool.HasNoInputsOf(tx)); - unsigned int nSize = entry.GetTxSize(); - - // Don't accept it if it can't get into a block - CAmount txMinFee = GetMinRelayFee(tx, pool, nSize, true); - if (fLimitFree && nFees < txMinFee) - return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient fee", false, - strprintf("%d < %d", nFees, txMinFee)); + strprintf("%d", nSigOps)); CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize); - if (mempoolRejectFee > 0 && nFees < mempoolRejectFee) { + if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) { return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee)); - } else if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) { + } else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nModifiedFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) { // Require that free transactions have sufficient priority to be mined in the next block. return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority"); } @@ -922,7 +982,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // Continuously rate-limit free (really, very-low-fee) transactions // This mitigates 'penny-flooding' -- sending thousands of free transactions just to // be annoying or make others' transactions take longer to confirm. - if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize)) + if (fLimitFree && nModifiedFees < ::minRelayTxFee.GetFee(nSize)) { static CCriticalSection csFreeLimiter; static double dFreeCount; @@ -936,16 +996,16 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa nLastTime = nNow; // -limitfreerelay unit is thousand-bytes-per-minute // At default rate it would take over a month to fill 1GB - if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000) + if (dFreeCount + nSize >= GetArg("-limitfreerelay", DEFAULT_LIMITFREERELAY) * 10 * 1000) return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "rate limited free transaction"); LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); dFreeCount += nSize; } - if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000) + if (fRejectAbsurdFee && nFees > maxTxFee) return state.Invalid(false, REJECT_HIGHFEE, "absurdly-high-fee", - strprintf("%d > %d", nFees, ::minRelayTxFee.GetFee(nSize) * 10000)); + strprintf("%d > %d", nFees, maxTxFee)); // Calculate in-mempool ancestors, up to a limit. CTxMemPool::setEntries setAncestors; @@ -958,10 +1018,164 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return state.DoS(0, false, REJECT_NONSTANDARD, "too-long-mempool-chain", false, errString); } + // A transaction that spends outputs that would be replaced by it is invalid. Now + // that we have the set of all ancestors we can detect this + // pathological case by making sure setConflicts and setAncestors don't + // intersect. + BOOST_FOREACH(CTxMemPool::txiter ancestorIt, setAncestors) + { + const uint256 &hashAncestor = ancestorIt->GetTx().GetHash(); + if (setConflicts.count(hashAncestor)) + { + return state.DoS(10, error("AcceptToMemoryPool: %s spends conflicting transaction %s", + hash.ToString(), + hashAncestor.ToString()), + REJECT_INVALID, "bad-txns-spends-conflicting-tx"); + } + } + + // Check if it's economically rational to mine this transaction rather + // than the ones it replaces. + CAmount nConflictingFees = 0; + size_t nConflictingSize = 0; + uint64_t nConflictingCount = 0; + CTxMemPool::setEntries allConflicting; + + // If we don't hold the lock allConflicting might be incomplete; the + // subsequent RemoveStaged() and addUnchecked() calls don't guarantee + // mempool consistency for us. + LOCK(pool.cs); + if (setConflicts.size()) + { + CFeeRate newFeeRate(nModifiedFees, nSize); + set setConflictsParents; + const int maxDescendantsToVisit = 100; + CTxMemPool::setEntries setIterConflicting; + BOOST_FOREACH(const uint256 &hashConflicting, setConflicts) + { + CTxMemPool::txiter mi = pool.mapTx.find(hashConflicting); + if (mi == pool.mapTx.end()) + continue; + + // Save these to avoid repeated lookups + setIterConflicting.insert(mi); + + // If this entry is "dirty", then we don't have descendant + // state for this transaction, which means we probably have + // lots of in-mempool descendants. + // Don't allow replacements of dirty transactions, to ensure + // that we don't spend too much time walking descendants. + // This should be rare. + if (mi->IsDirty()) { + return state.DoS(0, + error("AcceptToMemoryPool: rejecting replacement %s; cannot replace tx %s with untracked descendants", + hash.ToString(), + mi->GetTx().GetHash().ToString()), + REJECT_NONSTANDARD, "too many potential replacements"); + } + + // Don't allow the replacement to reduce the feerate of the + // mempool. + // + // We usually don't want to accept replacements with lower + // feerates than what they replaced as that would lower the + // feerate of the next block. Requiring that the feerate always + // be increased is also an easy-to-reason about way to prevent + // DoS attacks via replacements. + // + // The mining code doesn't (currently) take children into + // account (CPFP) so we only consider the feerates of + // transactions being directly replaced, not their indirect + // descendants. While that does mean high feerate children are + // ignored when deciding whether or not to replace, we do + // require the replacement to pay more overall fees too, + // mitigating most cases. + CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize()); + if (newFeeRate <= oldFeeRate) + { + return state.DoS(0, + error("AcceptToMemoryPool: rejecting replacement %s; new feerate %s <= old feerate %s", + hash.ToString(), + newFeeRate.ToString(), + oldFeeRate.ToString()), + REJECT_INSUFFICIENTFEE, "insufficient fee"); + } + + BOOST_FOREACH(const CTxIn &txin, mi->GetTx().vin) + { + setConflictsParents.insert(txin.prevout.hash); + } + + nConflictingCount += mi->GetCountWithDescendants(); + } + // This potentially overestimates the number of actual descendants + // but we just want to be conservative to avoid doing too much + // work. + if (nConflictingCount <= maxDescendantsToVisit) { + // If not too many to replace, then calculate the set of + // transactions that would have to be evicted + BOOST_FOREACH(CTxMemPool::txiter it, setIterConflicting) { + pool.CalculateDescendants(it, allConflicting); + } + BOOST_FOREACH(CTxMemPool::txiter it, allConflicting) { + nConflictingFees += it->GetModifiedFee(); + nConflictingSize += it->GetTxSize(); + } + } else { + return state.DoS(0, + error("AcceptToMemoryPool: rejecting replacement %s; too many potential replacements (%d > %d)\n", + hash.ToString(), + nConflictingCount, + maxDescendantsToVisit), + REJECT_NONSTANDARD, "too many potential replacements"); + } + + for (unsigned int j = 0; j < tx.vin.size(); j++) + { + // We don't want to accept replacements that require low + // feerate junk to be mined first. Ideally we'd keep track of + // the ancestor feerates and make the decision based on that, + // but for now requiring all new inputs to be confirmed works. + if (!setConflictsParents.count(tx.vin[j].prevout.hash)) + { + // Rather than check the UTXO set - potentially expensive - + // it's cheaper to just check if the new input refers to a + // tx that's in the mempool. + if (pool.mapTx.find(tx.vin[j].prevout.hash) != pool.mapTx.end()) + return state.DoS(0, error("AcceptToMemoryPool: replacement %s adds unconfirmed input, idx %d", + hash.ToString(), j), + REJECT_NONSTANDARD, "replacement-adds-unconfirmed"); + } + } + + // The replacement must pay greater fees than the transactions it + // replaces - if we did the bandwidth used by those conflicting + // transactions would not be paid for. + if (nModifiedFees < nConflictingFees) + { + return state.DoS(0, error("AcceptToMemoryPool: rejecting replacement %s, less fees than conflicting txs; %s < %s", + hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees)), + REJECT_INSUFFICIENTFEE, "insufficient fee"); + } + + // Finally in addition to paying more fees than the conflicts the + // new transaction must pay for its own bandwidth. + CAmount nDeltaFees = nModifiedFees - nConflictingFees; + if (nDeltaFees < ::minRelayTxFee.GetFee(nSize)) + { + return state.DoS(0, + error("AcceptToMemoryPool: rejecting replacement %s, not enough additional fees to relay; %s < %s", + hash.ToString(), + FormatMoney(nDeltaFees), + FormatMoney(::minRelayTxFee.GetFee(nSize))), + REJECT_INSUFFICIENTFEE, "insufficient fee"); + } + } + // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true)) - return false; + return error("%s: CheckInputs: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); // Check again against just the consensus-critical mandatory script // verification flags, in case of bugs in the standard flags that cause @@ -978,17 +1192,24 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa __func__, hash.ToString(), FormatStateMessage(state)); } + // Remove conflicting transactions from the mempool + BOOST_FOREACH(const CTxMemPool::txiter it, allConflicting) + { + LogPrint("mempool", "replacing tx %s with %s for %s BTC additional fees, %d delta bytes\n", + it->GetTx().GetHash().ToString(), + hash.ToString(), + FormatMoney(nModifiedFees - nConflictingFees), + (int)nSize - (int)nConflictingSize); + } + pool.RemoveStaged(allConflicting); + // Store transaction in memory pool.addUnchecked(hash, entry, setAncestors, !IsInitialBlockDownload()); // trim mempool and check if tx was trimmed if (!fOverrideMempoolLimit) { - int expired = pool.Expire(GetTime() - GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); - if (expired != 0) - LogPrint("mempool", "Expired %i transactions from the memory pool\n", expired); - - pool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000); - if (!pool.exists(tx.GetHash())) + LimitMempoolSize(pool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); + if (!pool.exists(hash)) return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool full"); } } @@ -998,6 +1219,18 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return true; } +bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, + bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee) +{ + std::vector vHashTxToUncache; + bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, fOverrideMempoolLimit, fRejectAbsurdFee, vHashTxToUncache); + if (!res) { + BOOST_FOREACH(const uint256& hashTx, vHashTxToUncache) + pcoinsTip->Uncache(hashTx); + } + return res; +} + /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */ bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow) { @@ -1149,7 +1382,7 @@ bool IsInitialBlockDownload() if (lockIBDState) return false; bool state = (chainActive.Height() < pindexBestHeader->nHeight - 24 * 6 || - pindexBestHeader->GetBlockTime() < GetTime() - chainParams.MaxTipAge()); + pindexBestHeader->GetBlockTime() < GetTime() - nMaxTipAge); if (!state) lockIBDState = true; return state; @@ -1244,7 +1477,7 @@ void Misbehaving(NodeId pnode, int howmuch) return; state->nMisbehavior += howmuch; - int banscore = GetArg("-banscore", 100); + int banscore = GetArg("-banscore", DEFAULT_BANSCORE_THRESHOLD); if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore) { LogPrintf("%s: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", __func__, state->name, state->nMisbehavior-howmuch, state->nMisbehavior); @@ -1311,17 +1544,9 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach undo.nVersion = coins->nVersion; } } - // add outputs - inputs.ModifyNewCoins(tx.GetHash())->FromTx(tx, nHeight); - } - else { - // add outputs for coinbase tx - // In this case call the full ModifyCoins which will do a database - // lookup to be sure the coins do not already exist otherwise we do not - // know whether to mark them fresh or not. We want the duplicate coinbases - // before BIP30 to still be properly overwritten. - inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); } + // add outputs + inputs.ModifyNewCoins(tx.GetHash(), tx.IsCoinBase())->FromTx(tx, nHeight); } void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight) @@ -1405,9 +1630,12 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // Only if ALL inputs pass do we perform expensive ECDSA signature checks. // Helps prevent CPU exhaustion attacks. - // Skip ECDSA signature verification when connecting blocks - // before the last block chain checkpoint. This is safe because block merkle hashes are - // still computed and checked, and any change will be caught at the next checkpoint. + // Skip ECDSA signature verification when connecting blocks before the + // last block chain checkpoint. Assuming the checkpoints are valid this + // is safe because block merkle hashes are still computed and checked, + // and any change will be caught at the next checkpoint. Of course, if + // the checkpoint is for a chain that's invalid due to false scriptSigs + // this optimisation would allow an invalid chain to be accepted. if (fScriptChecks) { for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; @@ -1427,9 +1655,9 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // arguments; if so, don't trigger DoS protection to // avoid splitting the network between upgraded and // non-upgraded nodes. - CScriptCheck check(*coins, tx, i, + CScriptCheck check2(*coins, tx, i, flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore); - if (check()) + if (check2()) return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); } // Failures of other flags indicate a transaction that is @@ -1692,8 +1920,8 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const // How likely is it to find that many by chance? double p = boost::math::pdf(poisson, nBlocks); - LogPrint("partitioncheck", "%s : Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS); - LogPrint("partitioncheck", "%s : likelihood: %g\n", __func__, p); + LogPrint("partitioncheck", "%s: Found %d blocks in the last %d hours\n", __func__, nBlocks, SPAN_HOURS); + LogPrint("partitioncheck", "%s: likelihood: %g\n", __func__, p); // Aim for one false-positive about every fifty years of normal running: const int FIFTY_YEARS = 50*365*24*60*60; @@ -1736,7 +1964,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Check it again in case a previous version let a bad block in if (!CheckBlock(block, state, !fJustCheck, !fJustCheck)) - return false; + return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); // verify that the view's current state corresponds to the previous block uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash(); @@ -1947,6 +2175,7 @@ enum FlushStateMode { * or always and in all cases if we're in prune mode and are deleting files. */ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { + const CChainParams& chainparams = Params(); LOCK2(cs_main, cs_LastBlockFile); static int64_t nLastWrite = 0; static int64_t nLastFlush = 0; @@ -1955,7 +2184,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { bool fFlushForPrune = false; try { if (fPruneMode && fCheckForPruning && !fReindex) { - FindFilesToPrune(setFilesToPrune); + FindFilesToPrune(setFilesToPrune, chainparams.PruneAfterHeight()); fCheckForPruning = false; if (!setFilesToPrune.empty()) { fFlushForPrune = true; @@ -2093,12 +2322,11 @@ void static UpdateTip(CBlockIndex *pindexNew) { } } -/** Disconnect chainActive's tip. You want to manually re-limit mempool size after this */ +/** Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and manually re-limit mempool size after this, with cs_main held. */ bool static DisconnectTip(CValidationState& state, const Consensus::Params& consensusParams) { CBlockIndex *pindexDelete = chainActive.Tip(); assert(pindexDelete); - mempool.check(pcoinsTip); // Read block from disk. CBlock block; if (!ReadBlockFromDisk(block, pindexDelete, consensusParams)) @@ -2133,8 +2361,6 @@ bool static DisconnectTip(CValidationState& state, const Consensus::Params& cons // UpdateTransactionsFromBlock finds descendants of any transactions in this // block that were added back and cleans up the mempool state. mempool.UpdateTransactionsFromBlock(vHashUpdate); - mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight); - mempool.check(pcoinsTip); // Update chainActive and related variables. UpdateTip(pindexDelete->pprev); // Let wallets know transactions went from 1-confirmed to @@ -2155,10 +2381,9 @@ static int64_t nTimePostConnect = 0; * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock * corresponding to pindexNew, to bypass loading it again from disk. */ -bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, const CBlock *pblock) { - const CChainParams& chainparams = Params(); +bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const CBlock* pblock) +{ assert(pindexNew->pprev == chainActive.Tip()); - mempool.check(pcoinsTip); // Read block from disk. int64_t nTime1 = GetTimeMicros(); CBlock block; @@ -2195,7 +2420,6 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, const CB // Remove conflicting transactions from the mempool. list txConflicted; mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload()); - mempool.check(pcoinsTip); // Update chainActive & related variables. UpdateTip(pindexNew); // Tell wallet about transactions that went from mempool @@ -2288,8 +2512,8 @@ static void PruneBlockIndexCandidates() { * Try to make some progress towards making pindexMostWork the active block. * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. */ -static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, const CBlock *pblock) { - const CChainParams& chainparams = Params(); +static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const CBlock* pblock) +{ AssertLockHeld(cs_main); bool fInvalidFound = false; const CBlockIndex *pindexOldTip = chainActive.Tip(); @@ -2308,46 +2532,49 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo bool fContinue = true; int nHeight = pindexFork ? pindexFork->nHeight : -1; while (fContinue && nHeight != pindexMostWork->nHeight) { - // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need - // a few blocks along the way. - int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight); - vpindexToConnect.clear(); - vpindexToConnect.reserve(nTargetHeight - nHeight); - CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight); - while (pindexIter && pindexIter->nHeight != nHeight) { - vpindexToConnect.push_back(pindexIter); - pindexIter = pindexIter->pprev; - } - nHeight = nTargetHeight; + // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need + // a few blocks along the way. + int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight); + vpindexToConnect.clear(); + vpindexToConnect.reserve(nTargetHeight - nHeight); + CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight); + while (pindexIter && pindexIter->nHeight != nHeight) { + vpindexToConnect.push_back(pindexIter); + pindexIter = pindexIter->pprev; + } + nHeight = nTargetHeight; - // Connect new blocks. - BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { - if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) { - if (state.IsInvalid()) { - // The block violates a consensus rule. - if (!state.CorruptionPossible()) - InvalidChainFound(vpindexToConnect.back()); - state = CValidationState(); - fInvalidFound = true; - fContinue = false; - break; + // Connect new blocks. + BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { + if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) { + if (state.IsInvalid()) { + // The block violates a consensus rule. + if (!state.CorruptionPossible()) + InvalidChainFound(vpindexToConnect.back()); + state = CValidationState(); + fInvalidFound = true; + fContinue = false; + break; + } else { + // A system error occurred (disk space, database error, ...). + return false; + } } else { - // A system error occurred (disk space, database error, ...). - return false; - } - } else { - PruneBlockIndexCandidates(); - if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) { - // We're in a better position than we were. Return temporarily to release the lock. - fContinue = false; - break; + PruneBlockIndexCandidates(); + if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) { + // We're in a better position than we were. Return temporarily to release the lock. + fContinue = false; + break; + } } } } - } - if (fBlocksDisconnected) - mempool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000); + if (fBlocksDisconnected) { + mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); + LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); + } + mempool.check(pcoinsTip); // Callbacks/notifications for a new best chain. if (fInvalidFound) @@ -2363,46 +2590,69 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo * or an activated best chain. pblock is either NULL or a pointer to a block * that is already loaded (to avoid loading it again from disk). */ -bool ActivateBestChain(CValidationState &state, const CBlock *pblock) { - CBlockIndex *pindexNewTip = NULL; +bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, const CBlock *pblock) { CBlockIndex *pindexMostWork = NULL; - const CChainParams& chainparams = Params(); do { boost::this_thread::interruption_point(); + CBlockIndex *pindexNewTip = NULL; + const CBlockIndex *pindexFork; bool fInitialDownload; { LOCK(cs_main); + CBlockIndex *pindexOldTip = chainActive.Tip(); pindexMostWork = FindMostWorkChain(); // Whether we have anything to do at all. if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip()) return true; - if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL)) + if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL)) return false; pindexNewTip = chainActive.Tip(); + pindexFork = chainActive.FindFork(pindexOldTip); fInitialDownload = IsInitialBlockDownload(); } // When we reach this point, we switched to a new tip (stored in pindexNewTip). // Notifications/callbacks that can run without cs_main - if (!fInitialDownload) { - uint256 hashNewTip = pindexNewTip->GetBlockHash(); - // Relay inventory, but don't relay old inventory during initial block download. - int nBlockEstimate = 0; - if (fCheckpointsEnabled) - nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()); - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) - pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip)); + // Always notify the UI if a new block tip was connected + if (pindexFork != pindexNewTip) { + uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip); + + if (!fInitialDownload) { + // Find the hashes of all blocks that weren't previously in the best chain. + std::vector vHashes; + CBlockIndex *pindexToAnnounce = pindexNewTip; + while (pindexToAnnounce != pindexFork) { + vHashes.push_back(pindexToAnnounce->GetBlockHash()); + pindexToAnnounce = pindexToAnnounce->pprev; + if (vHashes.size() == MAX_BLOCKS_TO_ANNOUNCE) { + // Limit announcements in case of a huge reorganization. + // Rely on the peer's synchronization mechanism in that case. + break; + } + } + // Relay inventory, but don't relay old inventory during initial block download. + int nBlockEstimate = 0; + if (fCheckpointsEnabled) + nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()); + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) { + if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) { + BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) { + pnode->PushBlockHash(hash); + } + } + } + } + // Notify external listeners about the new tip. + if (!vHashes.empty()) { + GetMainSignals().UpdatedBlockTip(pindexNewTip); + } } - // Notify external listeners about the new tip. - GetMainSignals().UpdatedBlockTip(pindexNewTip); - uiInterface.NotifyBlockTip(hashNewTip); } } while(pindexMostWork != chainActive.Tip()); CheckBlockIndex(chainparams.GetConsensus()); @@ -2432,11 +2682,12 @@ bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensus // ActivateBestChain considers blocks already in chainActive // unconditionally valid already, so force disconnect away from it. if (!DisconnectTip(state, consensusParams)) { + mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); return false; } } - mempool.TrimToSize(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000); + LimitMempoolSize(mempool, GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60); // The resulting new best tip may not be in setBlockIndexCandidates anymore, so // add it again. @@ -2449,6 +2700,7 @@ bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensus } InvalidChainFound(pindex); + mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); return true; } @@ -2657,13 +2909,11 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f { // Check proof of work matches claimed amount if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) - return state.DoS(50, error("CheckBlockHeader(): proof of work failed"), - REJECT_INVALID, "high-hash"); + return state.DoS(50, false, REJECT_INVALID, "high-hash", false, "proof of work failed"); // Check timestamp if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60) - return state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"), - REJECT_INVALID, "time-too-new"); + return state.Invalid(false, REJECT_INVALID, "time-too-new", "block timestamp too far in the future"); return true; } @@ -2683,17 +2933,15 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // Check the merkle root. if (fCheckMerkleRoot) { bool mutated; - uint256 hashMerkleRoot2 = block.ComputeMerkleRoot(&mutated); + uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated); if (block.hashMerkleRoot != hashMerkleRoot2) - return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"), - REJECT_INVALID, "bad-txnmrklroot", true); + return state.DoS(100, false, REJECT_INVALID, "bad-txnmrklroot", true, "hashMerkleRoot mismatch"); // Check for merkle tree malleability (CVE-2012-2459): repeating sequences // of transactions in a block without affecting the merkle root of a block, // while still invalidating it. if (mutated) - return state.DoS(100, error("CheckBlock(): duplicate transaction"), - REJECT_INVALID, "bad-txns-duplicate", true); + return state.DoS(100, false, REJECT_INVALID, "bad-txns-duplicate", true, "duplicate transaction"); } // All potential-corruption validation must be done before we do any @@ -2702,24 +2950,20 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo // Size limits if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) - return state.DoS(100, error("CheckBlock(): size limits failed"), - REJECT_INVALID, "bad-blk-length"); + return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed"); // First transaction must be coinbase, the rest must not be if (block.vtx.empty() || !block.vtx[0].IsCoinBase()) - return state.DoS(100, error("CheckBlock(): first tx is not coinbase"), - REJECT_INVALID, "bad-cb-missing"); + return state.DoS(100, false, REJECT_INVALID, "bad-cb-missing", false, "first tx is not coinbase"); for (unsigned int i = 1; i < block.vtx.size(); i++) if (block.vtx[i].IsCoinBase()) - return state.DoS(100, error("CheckBlock(): more than one coinbase"), - REJECT_INVALID, "bad-cb-multiple"); + return state.DoS(100, false, REJECT_INVALID, "bad-cb-multiple", false, "more than one coinbase"); // Check transactions BOOST_FOREACH(const CTransaction& tx, block.vtx) if (!CheckTransaction(tx, state)) - return error("CheckBlock(): CheckTransaction of %s failed with %s", - tx.GetHash().ToString(), - FormatStateMessage(state)); + return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(), + strprintf("Transaction check failed (tx hash %s) %s", tx.GetHash().ToString(), state.GetDebugMessage())); unsigned int nSigOps = 0; BOOST_FOREACH(const CTransaction& tx, block.vtx) @@ -2727,8 +2971,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo nSigOps += GetLegacySigOpCount(tx); } if (nSigOps > MAX_BLOCK_SIGOPS) - return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"), - REJECT_INVALID, "bad-blk-sigops", true); + return state.DoS(100, false, REJECT_INVALID, "bad-blk-sigops", false, "out-of-bounds SigOpCount"); if (fCheckPOW && fCheckMerkleRoot) block.fChecked = true; @@ -2755,28 +2998,17 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta const Consensus::Params& consensusParams = Params().GetConsensus(); // Check proof of work if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) - return state.DoS(100, error("%s: incorrect proof of work", __func__), - REJECT_INVALID, "bad-diffbits"); + return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, "incorrect proof of work"); // Check timestamp against prev if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) - return state.Invalid(error("%s: block's timestamp is too early", __func__), - REJECT_INVALID, "time-too-old"); + return state.Invalid(false, REJECT_INVALID, "time-too-old", "block's timestamp is too early"); - // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) - return state.Invalid(error("%s: rejected nVersion=1 block", __func__), - REJECT_OBSOLETE, "bad-version"); - - // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) - return state.Invalid(error("%s : rejected nVersion=2 block", __func__), - REJECT_OBSOLETE, "bad-version"); - - // Reject block.nVersion=3 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 4 && IsSuperMajority(4, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) - return state.Invalid(error("%s : rejected nVersion=3 block", __func__), - REJECT_OBSOLETE, "bad-version"); + // Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded: + for (int32_t version = 2; version < 5; ++version) // check for version 2, 3 and 4 upgrades + if (block.nVersion < version && IsSuperMajority(version, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) + return state.Invalid(false, REJECT_OBSOLETE, strprintf("bad-version(v%d)", version - 1), + strprintf("rejected nVersion=%d block", version - 1)); return true; } @@ -2793,7 +3025,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn ? pindexPrev->GetMedianTimePast() : block.GetBlockTime(); if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) { - return state.DoS(10, error("%s: contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal"); + return state.DoS(10, false, REJECT_INVALID, "bad-txns-nonfinal", false, "non-final transaction"); } } @@ -2804,7 +3036,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn CScript expect = CScript() << nHeight; if (block.vtx[0].vin[0].scriptSig.size() < expect.size() || !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) { - return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height"); + return state.DoS(100, false, REJECT_INVALID, "bad-cb-height", false, "block height mismatch in coinbase"); } } @@ -2831,7 +3063,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state } if (!CheckBlockHeader(block, state)) - return false; + return error("%s: Consensus::CheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); // Get prev block index CBlockIndex* pindexPrev = NULL; @@ -2847,7 +3079,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str()); if (!ContextualCheckBlockHeader(block, state, pindexPrev)) - return false; + return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); } if (pindex == NULL) pindex = AddToBlockIndex(block); @@ -2858,9 +3090,9 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state return true; } -bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp) +/** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */ +static bool AcceptBlock(const CBlock& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp) { - const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); CBlockIndex *&pindex = *ppindex; @@ -2894,7 +3126,7 @@ bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex** ppi pindex->nStatus |= BLOCK_FAILED_VALID; setDirtyBlockIndex.insert(pindex); } - return false; + return error("%s: %s", __func__, FormatStateMessage(state)); } int nHeight = pindex->nHeight; @@ -2945,12 +3177,12 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c bool fRequested = MarkBlockAsReceived(pblock->GetHash()); fRequested |= fForceProcessing; if (!checked) { - return error("%s: CheckBlock FAILED", __func__); + return error("%s: CheckBlock FAILED %s", __func__, FormatStateMessage(state)); } // Store to disk CBlockIndex *pindex = NULL; - bool ret = AcceptBlock(*pblock, state, &pindex, fRequested, dbp); + bool ret = AcceptBlock(*pblock, state, chainparams, &pindex, fRequested, dbp); if (pindex && pfrom) { mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId(); } @@ -2959,7 +3191,7 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c return error("%s: AcceptBlock FAILED", __func__); } - if (!ActivateBestChain(state, pblock)) + if (!ActivateBestChain(state, chainparams, pblock)) return error("%s: ActivateBestChain failed", __func__); return true; @@ -2979,11 +3211,11 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, // NOTE: CheckBlockHeader is called by CheckBlock if (!ContextualCheckBlockHeader(block, state, pindexPrev)) - return false; + return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, FormatStateMessage(state)); if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot)) - return false; + return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); if (!ContextualCheckBlock(block, state, pindexPrev)) - return false; + return error("%s: Consensus::ContextualCheckBlock: %s", __func__, FormatStateMessage(state)); if (!ConnectBlock(block, state, &indexDummy, viewNew, true)) return false; assert(state.IsValid()); @@ -3049,13 +3281,13 @@ void UnlinkPrunedFiles(std::set& setFilesToPrune) } /* Calculate the block/rev files that should be deleted to remain under target*/ -void FindFilesToPrune(std::set& setFilesToPrune) +void FindFilesToPrune(std::set& setFilesToPrune, uint64_t nPruneAfterHeight) { LOCK2(cs_main, cs_LastBlockFile); if (chainActive.Tip() == NULL || nPruneTarget == 0) { return; } - if (chainActive.Tip()->nHeight <= Params().PruneAfterHeight()) { + if ((uint64_t)chainActive.Tip()->nHeight <= nPruneAfterHeight) { return; } @@ -3283,9 +3515,8 @@ CVerifyDB::~CVerifyDB() uiInterface.ShowProgress("", 100); } -bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth) +bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth) { - const CChainParams& chainparams = Params(); LOCK(cs_main); if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL) return true; @@ -3314,7 +3545,8 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 1: verify block validity if (nCheckLevel >= 1 && !CheckBlock(block, state)) - return error("VerifyDB(): *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); + return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__, + pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state)); // check level 2: verify undo validity if (nCheckLevel >= 2 && pindex) { CBlockUndo undo; @@ -3401,9 +3633,8 @@ bool LoadBlockIndex() return true; } - -bool InitBlockIndex() { - const CChainParams& chainparams = Params(); +bool InitBlockIndex(const CChainParams& chainparams) +{ LOCK(cs_main); // Initialize global variables that cannot be constructed at startup. @@ -3414,14 +3645,14 @@ bool InitBlockIndex() { return true; // Use the provided setting for -txindex in the new database - fTxIndex = GetBoolArg("-txindex", false); + fTxIndex = GetBoolArg("-txindex", DEFAULT_TXINDEX); pblocktree->WriteFlag("txindex", fTxIndex); LogPrintf("Initializing databases...\n"); // Only add the genesis block if not reindexing (in which case we reuse the one already on disk) if (!fReindex) { try { - CBlock &block = const_cast(Params().GenesisBlock()); + CBlock &block = const_cast(chainparams.GenesisBlock()); // Start new block file unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); CDiskBlockPos blockPos; @@ -3433,7 +3664,7 @@ bool InitBlockIndex() { CBlockIndex *pindex = AddToBlockIndex(block); if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) return error("LoadBlockIndex(): genesis block not accepted"); - if (!ActivateBestChain(state, &block)) + if (!ActivateBestChain(state, chainparams, &block)) return error("LoadBlockIndex(): genesis block cannot be activated"); // Force a chainstate write so that when we VerifyDB in a moment, it doesn't check stale data return FlushStateToDisk(state, FLUSH_STATE_ALWAYS); @@ -3445,11 +3676,8 @@ bool InitBlockIndex() { return true; } - - -bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) +bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskBlockPos *dbp) { - const CChainParams& chainparams = Params(); // Map of disk positions for blocks with unknown parent (only used for reindex) static std::multimap mapBlocksUnknownParent; int64_t nStart = GetTimeMillis(); @@ -3469,10 +3697,10 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) try { // locate a header unsigned char buf[MESSAGE_START_SIZE]; - blkdat.FindByte(Params().MessageStart()[0]); + blkdat.FindByte(chainparams.MessageStart()[0]); nRewind = blkdat.GetPos()+1; blkdat >> FLATDATA(buf); - if (memcmp(buf, Params().MessageStart(), MESSAGE_START_SIZE)) + if (memcmp(buf, chainparams.MessageStart(), MESSAGE_START_SIZE)) continue; // read size blkdat >> nSize; @@ -3744,29 +3972,34 @@ std::string GetWarnings(const std::string& strFor) int nPriority = 0; string strStatusBar; string strRPC; + string strGUI; - if (!CLIENT_VERSION_IS_RELEASE) - strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications"); + if (!CLIENT_VERSION_IS_RELEASE) { + strStatusBar = "This is a pre-release test build - use at your own risk - do not use for mining or merchant applications"; + strGUI = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications"); + } - if (GetBoolArg("-testsafemode", false)) - strStatusBar = strRPC = "testsafemode enabled"; + if (GetBoolArg("-testsafemode", DEFAULT_TESTSAFEMODE)) + strStatusBar = strRPC = strGUI = "testsafemode enabled"; // Misc warnings like out of disk space and clock is wrong if (strMiscWarning != "") { nPriority = 1000; - strStatusBar = strMiscWarning; + strStatusBar = strGUI = strMiscWarning; } if (fLargeWorkForkFound) { nPriority = 2000; - strStatusBar = strRPC = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."); + strStatusBar = strRPC = "Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."; + strGUI = _("Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues."); } else if (fLargeWorkInvalidChainFound) { nPriority = 2000; - strStatusBar = strRPC = _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."); + strStatusBar = strRPC = "Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."; + strGUI = _("Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade."); } // Alerts @@ -3778,12 +4011,14 @@ std::string GetWarnings(const std::string& strFor) if (alert.AppliesToMe() && alert.nPriority > nPriority) { nPriority = alert.nPriority; - strStatusBar = alert.strStatusBar; + strStatusBar = strGUI = alert.strStatusBar; } } } - if (strFor == "statusbar") + if (strFor == "gui") + return strGUI; + else if (strFor == "statusbar") return strStatusBar; else if (strFor == "rpc") return strRPC; @@ -3866,7 +4101,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // best equivalent proof of work) than the best header chain we know about. send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() < nOneMonth) && - (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, Params().GetConsensus()) < nOneMonth); + (GetBlockProofEquivalentTime(*pindexBestHeader, *mi->second, *pindexBestHeader, consensusParams) < nOneMonth); if (!send) { LogPrintf("%s: ignoring request from peer=%i for old block that isn't in the main chain\n", __func__, pfrom->GetId()); } @@ -3892,14 +4127,14 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam if (!ReadBlockFromDisk(block, (*mi).second, consensusParams)) assert(!"cannot load block from disk"); if (inv.type == MSG_BLOCK) - pfrom->PushMessage("block", block); + pfrom->PushMessage(NetMsgType::BLOCK, block); else // MSG_FILTERED_BLOCK) { LOCK(pfrom->cs_filter); if (pfrom->pfilter) { CMerkleBlock merkleBlock(block, *pfrom->pfilter); - pfrom->PushMessage("merkleblock", merkleBlock); + pfrom->PushMessage(NetMsgType::MERKLEBLOCK, merkleBlock); // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see // This avoids hurting performance by pointlessly requiring a round-trip // Note that there is currently no way for a node to request any single transactions we didn't send here - @@ -3908,8 +4143,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // however we MUST always provide at least what the remote peer needs typedef std::pair PairType; BOOST_FOREACH(PairType& pair, merkleBlock.vMatchedTxn) - if (!pfrom->setInventoryKnown.count(CInv(MSG_TX, pair.second))) - pfrom->PushMessage("tx", block.vtx[pair.first]); + pfrom->PushMessage(NetMsgType::TX, block.vtx[pair.first]); } // else // no response @@ -3923,7 +4157,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // wait for other stuff first. vector vInv; vInv.push_back(CInv(MSG_BLOCK, chainActive.Tip()->GetBlockHash())); - pfrom->PushMessage("inv", vInv); + pfrom->PushMessage(NetMsgType::INV, vInv); pfrom->hashContinue.SetNull(); } } @@ -3946,7 +4180,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss.reserve(1000); ss << tx; - pfrom->PushMessage("tx", ss); + pfrom->PushMessage(NetMsgType::TX, ss); pushed = true; } } @@ -3973,7 +4207,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // do that because they want to know about (and store and rebroadcast and // risk analyze) the dependencies of transactions relevant to them, without // having to download the entire memory pool. - pfrom->PushMessage("notfound", vNotFound); + pfrom->PushMessage(NetMsgType::NOTFOUND, vNotFound); } } @@ -3989,14 +4223,27 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } + if (!(nLocalServices & NODE_BLOOM) && + (strCommand == NetMsgType::FILTERLOAD || + strCommand == NetMsgType::FILTERADD || + strCommand == NetMsgType::FILTERCLEAR)) + { + if (pfrom->nVersion >= NO_BLOOM_VERSION) { + Misbehaving(pfrom->GetId(), 100); + return false; + } else if (GetBoolArg("-enforcenodebloom", false)) { + pfrom->fDisconnect = true; + return false; + } + } - if (strCommand == "version") + if (strCommand == NetMsgType::VERSION) { // Each connection can only send one version message if (pfrom->nVersion != 0) { - pfrom->PushMessage("reject", strCommand, REJECT_DUPLICATE, string("Duplicate version message")); + pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_DUPLICATE, string("Duplicate version message")); Misbehaving(pfrom->GetId(), 1); return false; } @@ -4010,7 +4257,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { // disconnect from peers older than this proto version LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion); - pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE, + pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, strprintf("Version must be %d or greater", MIN_PEER_PROTO_VERSION)); pfrom->fDisconnect = true; return false; @@ -4055,7 +4302,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, UpdatePreferredDownload(pfrom, State(pfrom->GetId())); // Change version - pfrom->PushMessage("verack"); + pfrom->PushMessage(NetMsgType::VERACK); pfrom->ssSend.SetVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); if (!pfrom->fInbound) @@ -4078,7 +4325,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Get recent addresses if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000) { - pfrom->PushMessage("getaddr"); + pfrom->PushMessage(NetMsgType::GETADDR); pfrom->fGetAddr = true; } addrman.Good(pfrom->addr); @@ -4122,7 +4369,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "verack") + else if (strCommand == NetMsgType::VERACK) { pfrom->SetRecvVersion(min(pfrom->nVersion, PROTOCOL_VERSION)); @@ -4131,10 +4378,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LOCK(cs_main); State(pfrom->GetId())->fCurrentlyConnected = true; } + + if (pfrom->nVersion >= SENDHEADERS_VERSION) { + // Tell our peer we prefer to receive headers rather than inv's + // We send this to non-NODE NETWORK peers as well, because even + // non-NODE NETWORK peers can announce blocks (such as pruning + // nodes) + pfrom->PushMessage(NetMsgType::SENDHEADERS); + } } - else if (strCommand == "addr") + else if (strCommand == NetMsgType::ADDR) { vector vAddr; vRecv >> vAddr; @@ -4200,8 +4455,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->fDisconnect = true; } + else if (strCommand == NetMsgType::SENDHEADERS) + { + LOCK(cs_main); + State(pfrom->GetId())->fPreferHeaders = true; + } - else if (strCommand == "inv") + + else if (strCommand == NetMsgType::INV) { vector vInv; vRecv >> vInv; @@ -4213,8 +4474,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, bool fBlocksOnly = GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY); - // Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistalwaysrelay is true - if (pfrom->fWhitelisted && GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY)) + // Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistrelay is true + if (pfrom->fWhitelisted && GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) fBlocksOnly = false; LOCK(cs_main); @@ -4242,9 +4503,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // time the block arrives, the header chain leading up to it is already validated. Not // doing this will result in the received block being rejected as an orphan in case it is // not a direct successor. - pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash); + pfrom->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), inv.hash); CNodeState *nodestate = State(pfrom->GetId()); - if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 && + if (CanDirectFetch(chainparams.GetConsensus()) && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { vToFetch.push_back(inv); // Mark block as in flight already, even though the actual "getdata" message only goes out @@ -4258,7 +4519,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, { if (fBlocksOnly) LogPrint("net", "transaction (%s) inv sent in violation of protocol peer=%d\n", inv.hash.ToString(), pfrom->id); - else if (!fAlreadyHave && !fImporting && !fReindex) + else if (!fAlreadyHave && !fImporting && !fReindex && !IsInitialBlockDownload()) pfrom->AskFor(inv); } @@ -4272,11 +4533,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } if (!vToFetch.empty()) - pfrom->PushMessage("getdata", vToFetch); + pfrom->PushMessage(NetMsgType::GETDATA, vToFetch); } - else if (strCommand == "getdata") + else if (strCommand == NetMsgType::GETDATA) { vector vInv; vRecv >> vInv; @@ -4297,7 +4558,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "getblocks") + else if (strCommand == NetMsgType::GETBLOCKS) { CBlockLocator locator; uint256 hashStop; @@ -4341,7 +4602,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "getheaders") + else if (strCommand == NetMsgType::GETHEADERS) { CBlockLocator locator; uint256 hashStop; @@ -4352,6 +4613,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("net", "Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom->id); return true; } + + CNodeState *nodestate = State(pfrom->GetId()); CBlockIndex* pindex = NULL; if (locator.IsNull()) { @@ -4379,15 +4642,20 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop) break; } - pfrom->PushMessage("headers", vHeaders); + // pindex can be NULL either if we sent chainActive.Tip() OR + // if our peer has chainActive.Tip() (and thus we are sending an empty + // headers message). In both cases it's safe to update + // pindexBestHeaderSent to be our tip. + nodestate->pindexBestHeaderSent = pindex ? pindex : chainActive.Tip(); + pfrom->PushMessage(NetMsgType::HEADERS, vHeaders); } - else if (strCommand == "tx") + else if (strCommand == NetMsgType::TX) { // Stop processing the transaction early if - // We are in blocks only mode and peer is either not whitelisted or whitelistalwaysrelay is off - if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY))) + // We are in blocks only mode and peer is either not whitelisted or whitelistrelay is off + if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY))) { LogPrint("net", "transaction sent in violation of protocol peer=%d\n", pfrom->id); return true; @@ -4406,13 +4674,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, bool fMissingInputs = false; CValidationState state; + pfrom->setAskFor.erase(inv.hash); mapAlreadyAskedFor.erase(inv); - // Check for recently rejected (and do other quick existence checks) - if (AlreadyHave(inv)) - return true; - - if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs)) + if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs)) { mempool.check(pcoinsTip); RelayTransaction(tx); @@ -4490,15 +4755,22 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, assert(recentRejects); recentRejects->insert(tx.GetHash()); - if (pfrom->fWhitelisted && GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY)) { + if (pfrom->fWhitelisted && GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) { // Always relay transactions received from whitelisted peers, even - // if they were rejected from the mempool, allowing the node to - // function as a gateway for nodes hidden behind it. + // if they were already in the mempool or rejected from it due + // to policy, allowing the node to function as a gateway for + // nodes hidden behind it. // - // FIXME: This includes invalid transactions, which means a - // whitelisted peer could get us banned! We may want to change - // that. - RelayTransaction(tx); + // Never relay transactions that we would assign a non-zero DoS + // score for, as we expect peers to do the same with us in that + // case. + int nDoS = 0; + if (!state.IsInvalid(nDoS) || nDoS == 0) { + LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id); + RelayTransaction(tx); + } else { + LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s)\n", tx.GetHash().ToString(), pfrom->id, FormatStateMessage(state)); + } } } int nDoS = 0; @@ -4508,15 +4780,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->id, FormatStateMessage(state)); if (state.GetRejectCode() < REJECT_INTERNAL) // Never send AcceptToMemoryPool's internal codes over P2P - pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), + pfrom->PushMessage(NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) Misbehaving(pfrom->GetId(), nDoS); } + FlushStateToDisk(state, FLUSH_STATE_PERIODIC); } - else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing + else if (strCommand == NetMsgType::HEADERS && !fImporting && !fReindex) // Ignore headers received while importing { std::vector headers; @@ -4564,13 +4837,60 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue // from there instead. LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight); - pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256()); + pfrom->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexLast), uint256()); + } + + bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus()); + CNodeState *nodestate = State(pfrom->GetId()); + // If this set of headers is valid and ends in a block with at least as + // much work as our tip, download as much as possible. + if (fCanDirectFetch && pindexLast->IsValid(BLOCK_VALID_TREE) && chainActive.Tip()->nChainWork <= pindexLast->nChainWork) { + vector vToFetch; + CBlockIndex *pindexWalk = pindexLast; + // Calculate all the blocks we'd need to switch to pindexLast, up to a limit. + while (pindexWalk && !chainActive.Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) { + if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) && + !mapBlocksInFlight.count(pindexWalk->GetBlockHash())) { + // We don't have this block, and it's not yet in flight. + vToFetch.push_back(pindexWalk); + } + pindexWalk = pindexWalk->pprev; + } + // If pindexWalk still isn't on our main chain, we're looking at a + // very large reorg at a time we think we're close to caught up to + // the main chain -- this shouldn't really happen. Bail out on the + // direct fetch and rely on parallel download instead. + if (!chainActive.Contains(pindexWalk)) { + LogPrint("net", "Large reorg, won't direct fetch to %s (%d)\n", + pindexLast->GetBlockHash().ToString(), + pindexLast->nHeight); + } else { + vector vGetData; + // Download as much as possible, from earliest to latest. + BOOST_REVERSE_FOREACH(CBlockIndex *pindex, vToFetch) { + if (nodestate->nBlocksInFlight >= MAX_BLOCKS_IN_TRANSIT_PER_PEER) { + // Can't download any more from this peer + break; + } + vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash())); + MarkBlockAsInFlight(pfrom->GetId(), pindex->GetBlockHash(), chainparams.GetConsensus(), pindex); + LogPrint("net", "Requesting block %s from peer=%d\n", + pindex->GetBlockHash().ToString(), pfrom->id); + } + if (vGetData.size() > 1) { + LogPrint("net", "Downloading blocks toward %s (%d) via headers direct fetch\n", + pindexLast->GetBlockHash().ToString(), pindexLast->nHeight); + } + if (vGetData.size() > 0) { + pfrom->PushMessage(NetMsgType::GETDATA, vGetData); + } + } } CheckBlockIndex(chainparams.GetConsensus()); } - else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing + else if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) // Ignore blocks received while importing { CBlock block; vRecv >> block; @@ -4590,7 +4910,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int nDoS; if (state.IsInvalid(nDoS)) { assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes - pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), + pfrom->PushMessage(NetMsgType::REJECT, strCommand, (unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); if (nDoS > 0) { LOCK(cs_main); @@ -4606,7 +4926,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // to users' AddrMan and later request them by sending getaddr messages. // Making nodes which are behind NAT and can only make outgoing connections ignore // the getaddr message mitigates the attack. - else if ((strCommand == "getaddr") && (pfrom->fInbound)) + else if ((strCommand == NetMsgType::GETADDR) && (pfrom->fInbound)) { pfrom->vAddrToSend.clear(); vector vAddr = addrman.GetAddr(); @@ -4615,8 +4935,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "mempool") + else if (strCommand == NetMsgType::MEMPOOL) { + if (CNode::OutboundTargetReached(false) && !pfrom->fWhitelisted) + { + LogPrint("net", "mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom->GetId()); + pfrom->fDisconnect = true; + return true; + } LOCK2(cs_main, pfrom->cs_filter); std::vector vtxid; @@ -4624,23 +4950,24 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vector vInv; BOOST_FOREACH(uint256& hash, vtxid) { CInv inv(MSG_TX, hash); - CTransaction tx; - bool fInMemPool = mempool.lookup(hash, tx); - if (!fInMemPool) continue; // another thread removed since queryHashes, maybe... - if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx)) || - (!pfrom->pfilter)) - vInv.push_back(inv); + if (pfrom->pfilter) { + CTransaction tx; + bool fInMemPool = mempool.lookup(hash, tx); + if (!fInMemPool) continue; // another thread removed since queryHashes, maybe... + if (!pfrom->pfilter->IsRelevantAndUpdate(tx)) continue; + } + vInv.push_back(inv); if (vInv.size() == MAX_INV_SZ) { - pfrom->PushMessage("inv", vInv); + pfrom->PushMessage(NetMsgType::INV, vInv); vInv.clear(); } } if (vInv.size() > 0) - pfrom->PushMessage("inv", vInv); + pfrom->PushMessage(NetMsgType::INV, vInv); } - else if (strCommand == "ping") + else if (strCommand == NetMsgType::PING) { if (pfrom->nVersion > BIP0031_VERSION) { @@ -4657,12 +4984,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // it, if the remote node sends a ping once per second and this node takes 5 // seconds to respond to each, the 5th ping the remote sends would appear to // return very quickly. - pfrom->PushMessage("pong", nonce); + pfrom->PushMessage(NetMsgType::PONG, nonce); } } - else if (strCommand == "pong") + else if (strCommand == NetMsgType::PONG) { int64_t pingUsecEnd = nTimeReceived; uint64_t nonce = 0; @@ -4719,7 +5046,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (fAlerts && strCommand == "alert") + else if (fAlerts && strCommand == NetMsgType::ALERT) { CAlert alert; vRecv >> alert; @@ -4727,7 +5054,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, uint256 alertHash = alert.GetHash(); if (pfrom->setKnown.count(alertHash) == 0) { - if (alert.ProcessAlert(Params().AlertKey())) + if (alert.ProcessAlert(chainparams.AlertKey())) { // Relay pfrom->setKnown.insert(alertHash); @@ -4750,22 +5077,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (!(nLocalServices & NODE_BLOOM) && - (strCommand == "filterload" || - strCommand == "filteradd" || - strCommand == "filterclear") && - //TODO: Remove this line after reasonable network upgrade - pfrom->nVersion >= NO_BLOOM_VERSION) - { - if (pfrom->nVersion >= NO_BLOOM_VERSION) - Misbehaving(pfrom->GetId(), 100); - //TODO: Enable this after reasonable network upgrade - //else - // pfrom->fDisconnect = true; - } - - - else if (strCommand == "filterload") + else if (strCommand == NetMsgType::FILTERLOAD) { CBloomFilter filter; vRecv >> filter; @@ -4784,7 +5096,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "filteradd") + else if (strCommand == NetMsgType::FILTERADD) { vector vData; vRecv >> vData; @@ -4804,7 +5116,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "filterclear") + else if (strCommand == NetMsgType::FILTERCLEAR) { LOCK(pfrom->cs_filter); delete pfrom->pfilter; @@ -4813,7 +5125,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "reject") + else if (strCommand == NetMsgType::REJECT) { if (fDebug) { try { @@ -4823,7 +5135,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, ostringstream ss; ss << strMsg << " code " << itostr(ccode) << ": " << strReason; - if (strMsg == "block" || strMsg == "tx") + if (strMsg == NetMsgType::BLOCK || strMsg == NetMsgType::TX) { uint256 hash; vRecv >> hash; @@ -4931,7 +5243,7 @@ bool ProcessMessages(CNode* pfrom) } catch (const std::ios_base::failure& e) { - pfrom->PushMessage("reject", strCommand, REJECT_MALFORMED, string("error parsing message")); + pfrom->PushMessage(NetMsgType::REJECT, strCommand, REJECT_MALFORMED, string("error parsing message")); if (strstr(e.what(), "end of data")) { // Allow exceptions from under-length message on vRecv @@ -4970,7 +5282,7 @@ bool ProcessMessages(CNode* pfrom) } -bool SendMessages(CNode* pto, bool fSendTrickle) +bool SendMessages(CNode* pto) { const Consensus::Params& consensusParams = Params().GetConsensus(); { @@ -4999,11 +5311,11 @@ bool SendMessages(CNode* pto, bool fSendTrickle) pto->nPingUsecStart = GetTimeMicros(); if (pto->nVersion > BIP0031_VERSION) { pto->nPingNonceSent = nonce; - pto->PushMessage("ping", nonce); + pto->PushMessage(NetMsgType::PING, nonce); } else { // Peer is too old to support ping command with nonce, pong will never arrive. pto->nPingNonceSent = 0; - pto->PushMessage("ping"); + pto->PushMessage(NetMsgType::PING); } } @@ -5012,28 +5324,17 @@ bool SendMessages(CNode* pto, bool fSendTrickle) return true; // Address refresh broadcast - static int64_t nLastRebroadcast; - if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60)) - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - { - // Periodically clear addrKnown to allow refresh broadcasts - if (nLastRebroadcast) - pnode->addrKnown.reset(); - - // Rebroadcast our address - AdvertizeLocal(pnode); - } - if (!vNodes.empty()) - nLastRebroadcast = GetTime(); + int64_t nNow = GetTimeMicros(); + if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) { + AdvertizeLocal(pto); + pto->nNextLocalAddrSend = PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL); } // // Message: addr // - if (fSendTrickle) - { + if (pto->nNextAddrSend < nNow) { + pto->nNextAddrSend = PoissonNextSend(nNow, AVG_ADDRESS_BROADCAST_INTERVAL); vector vAddr; vAddr.reserve(pto->vAddrToSend.size()); BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend) @@ -5045,14 +5346,14 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // receiver rejects addr messages larger than 1000 if (vAddr.size() >= 1000) { - pto->PushMessage("addr", vAddr); + pto->PushMessage(NetMsgType::ADDR, vAddr); vAddr.clear(); } } } pto->vAddrToSend.clear(); if (!vAddr.empty()) - pto->PushMessage("addr", vAddr); + pto->PushMessage(NetMsgType::ADDR, vAddr); } CNodeState &state = *State(pto->GetId()); @@ -5072,7 +5373,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } BOOST_FOREACH(const CBlockReject& reject, state.rejects) - pto->PushMessage("reject", (string)"block", reject.chRejectCode, reject.strRejectReason, reject.hashBlock); + pto->PushMessage(NetMsgType::REJECT, (string)NetMsgType::BLOCK, reject.chRejectCode, reject.strRejectReason, reject.hashBlock); state.rejects.clear(); // Start block sync @@ -5095,7 +5396,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) if (pindexStart->pprev) pindexStart = pindexStart->pprev; LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight); - pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256()); + pto->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexStart), uint256()); } } @@ -5107,18 +5408,117 @@ bool SendMessages(CNode* pto, bool fSendTrickle) GetMainSignals().Broadcast(nTimeBestReceived); } + // + // Try sending block announcements via headers + // + { + // If we have less than MAX_BLOCKS_TO_ANNOUNCE in our + // list of block hashes we're relaying, and our peer wants + // headers announcements, then find the first header + // not yet known to our peer but would connect, and send. + // If no header would connect, or if we have too many + // blocks, or if the peer doesn't want headers, just + // add all to the inv queue. + LOCK(pto->cs_inventory); + vector vHeaders; + bool fRevertToInv = (!state.fPreferHeaders || pto->vBlockHashesToAnnounce.size() > MAX_BLOCKS_TO_ANNOUNCE); + CBlockIndex *pBestIndex = NULL; // last header queued for delivery + ProcessBlockAvailability(pto->id); // ensure pindexBestKnownBlock is up-to-date + + if (!fRevertToInv) { + bool fFoundStartingHeader = false; + // Try to find first header that our peer doesn't have, and + // then send all headers past that one. If we come across any + // headers that aren't on chainActive, give up. + BOOST_FOREACH(const uint256 &hash, pto->vBlockHashesToAnnounce) { + BlockMap::iterator mi = mapBlockIndex.find(hash); + assert(mi != mapBlockIndex.end()); + CBlockIndex *pindex = mi->second; + if (chainActive[pindex->nHeight] != pindex) { + // Bail out if we reorged away from this block + fRevertToInv = true; + break; + } + assert(pBestIndex == NULL || pindex->pprev == pBestIndex); + pBestIndex = pindex; + if (fFoundStartingHeader) { + // add this to the headers message + vHeaders.push_back(pindex->GetBlockHeader()); + } else if (PeerHasHeader(&state, pindex)) { + continue; // keep looking for the first new block + } else if (pindex->pprev == NULL || PeerHasHeader(&state, pindex->pprev)) { + // Peer doesn't have this header but they do have the prior one. + // Start sending headers. + fFoundStartingHeader = true; + vHeaders.push_back(pindex->GetBlockHeader()); + } else { + // Peer doesn't have this header or the prior one -- nothing will + // connect, so bail out. + fRevertToInv = true; + break; + } + } + } + if (fRevertToInv) { + // If falling back to using an inv, just try to inv the tip. + // The last entry in vBlockHashesToAnnounce was our tip at some point + // in the past. + if (!pto->vBlockHashesToAnnounce.empty()) { + const uint256 &hashToAnnounce = pto->vBlockHashesToAnnounce.back(); + BlockMap::iterator mi = mapBlockIndex.find(hashToAnnounce); + assert(mi != mapBlockIndex.end()); + CBlockIndex *pindex = mi->second; + + // Warn if we're announcing a block that is not on the main chain. + // This should be very rare and could be optimized out. + // Just log for now. + if (chainActive[pindex->nHeight] != pindex) { + LogPrint("net", "Announcing block %s not on main chain (tip=%s)\n", + hashToAnnounce.ToString(), chainActive.Tip()->GetBlockHash().ToString()); + } + + // If the peer announced this block to us, don't inv it back. + // (Since block announcements may not be via inv's, we can't solely rely on + // setInventoryKnown to track this.) + if (!PeerHasHeader(&state, pindex)) { + pto->PushInventory(CInv(MSG_BLOCK, hashToAnnounce)); + LogPrint("net", "%s: sending inv peer=%d hash=%s\n", __func__, + pto->id, hashToAnnounce.ToString()); + } + } + } else if (!vHeaders.empty()) { + if (vHeaders.size() > 1) { + LogPrint("net", "%s: %u headers, range (%s, %s), to peer=%d\n", __func__, + vHeaders.size(), + vHeaders.front().GetHash().ToString(), + vHeaders.back().GetHash().ToString(), pto->id); + } else { + LogPrint("net", "%s: sending header %s to peer=%d\n", __func__, + vHeaders.front().GetHash().ToString(), pto->id); + } + pto->PushMessage(NetMsgType::HEADERS, vHeaders); + state.pindexBestHeaderSent = pBestIndex; + } + pto->vBlockHashesToAnnounce.clear(); + } + // // Message: inventory // vector vInv; vector vInvWait; { + bool fSendTrickle = pto->fWhitelisted; + if (pto->nNextInvSend < nNow) { + fSendTrickle = true; + pto->nNextInvSend = PoissonNextSend(nNow, AVG_INVENTORY_BROADCAST_INTERVAL); + } LOCK(pto->cs_inventory); - vInv.reserve(pto->vInventoryToSend.size()); + vInv.reserve(std::min(1000, pto->vInventoryToSend.size())); vInvWait.reserve(pto->vInventoryToSend.size()); BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend) { - if (pto->setInventoryKnown.count(inv)) + if (inv.type == MSG_TX && pto->filterInventoryKnown.contains(inv.hash)) continue; // trickle out tx inv to protect privacy @@ -5139,24 +5539,22 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } } - // returns true if wasn't already contained in the set - if (pto->setInventoryKnown.insert(inv).second) + pto->filterInventoryKnown.insert(inv.hash); + + vInv.push_back(inv); + if (vInv.size() >= 1000) { - vInv.push_back(inv); - if (vInv.size() >= 1000) - { - pto->PushMessage("inv", vInv); - vInv.clear(); - } + pto->PushMessage(NetMsgType::INV, vInv); + vInv.clear(); } } pto->vInventoryToSend = vInvWait; } if (!vInv.empty()) - pto->PushMessage("inv", vInv); + pto->PushMessage(NetMsgType::INV, vInv); // Detect whether we're stalling - int64_t nNow = GetTimeMicros(); + nNow = GetTimeMicros(); if (!pto->fDisconnect && state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) { // Stalling only triggers when the block download window cannot move. During normal steady state, // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection @@ -5222,14 +5620,17 @@ bool SendMessages(CNode* pto, bool fSendTrickle) vGetData.push_back(inv); if (vGetData.size() >= 1000) { - pto->PushMessage("getdata", vGetData); + pto->PushMessage(NetMsgType::GETDATA, vGetData); vGetData.clear(); } + } else { + //If we're not going to ask, don't expect a response. + pto->setAskFor.erase(inv.hash); } pto->mapAskFor.erase(pto->mapAskFor.begin()); } if (!vGetData.empty()) - pto->PushMessage("getdata", vGetData); + pto->PushMessage(NetMsgType::GETDATA, vGetData); } return true; diff --git a/src/main.h b/src/main.h index eb61ff957..793737422 100644 --- a/src/main.h +++ b/src/main.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -42,10 +42,18 @@ struct CNodeStateStats; /** Default for accepting alerts from the P2P network. */ static const bool DEFAULT_ALERTS = true; -/** Default for DEFAULT_WHITELISTALWAYSRELAY. */ -static const bool DEFAULT_WHITELISTALWAYSRELAY = true; +/** Default for DEFAULT_WHITELISTRELAY. */ +static const bool DEFAULT_WHITELISTRELAY = true; +/** Default for DEFAULT_WHITELISTFORCERELAY. */ +static const bool DEFAULT_WHITELISTFORCERELAY = true; /** Default for -minrelaytxfee, minimum relay fee for transactions */ static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000; +//! -maxtxfee default +static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; +//! Discourage users to set fees higher than this amount (in satoshis) per kB +static const CAmount HIGH_TX_FEE_PER_KB = 0.01 * COIN; +//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis) +static const CAmount HIGH_MAX_TX_FEE = 100 * HIGH_TX_FEE_PER_KB; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; /** Default for -limitancestorcount, max number of in-mempool ancestors */ @@ -56,8 +64,6 @@ static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 101; static const unsigned int DEFAULT_DESCENDANT_LIMIT = 25; /** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */ static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 101; -/** Default for -maxmempool, maximum megabytes of mempool memory usage */ -static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300; /** Default for -mempoolexpiry, expiration time for mempool transactions in hours */ static const unsigned int DEFAULT_MEMPOOL_EXPIRY = 72; /** The maximum size of a blk?????.dat file (since 0.8) */ @@ -66,6 +72,7 @@ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB /** The pre-allocation chunk size for rev?????.dat files (since 0.8) */ static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB + /** Maximum number of script-checking threads allowed */ static const int MAX_SCRIPTCHECK_THREADS = 16; /** -par default (number of script-checking threads, 0 = auto) */ @@ -88,6 +95,31 @@ static const unsigned int DATABASE_WRITE_INTERVAL = 60 * 60; static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60; /** Maximum length of reject messages. */ static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111; +/** Average delay between local address broadcasts in seconds. */ +static const unsigned int AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 24 * 60; +/** Average delay between peer address broadcasts in seconds. */ +static const unsigned int AVG_ADDRESS_BROADCAST_INTERVAL = 30; +/** Average delay between trickled inventory broadcasts in seconds. + * Blocks, whitelisted receivers, and a random 25% of transactions bypass this. */ +static const unsigned int AVG_INVENTORY_BROADCAST_INTERVAL = 5; + +static const unsigned int DEFAULT_LIMITFREERELAY = 15; +static const bool DEFAULT_RELAYPRIORITY = true; +static const int64_t DEFAULT_MAX_TIP_AGE = 24 * 60 * 60; + +/** Default for -permitbaremultisig */ +static const bool DEFAULT_PERMIT_BAREMULTISIG = true; +static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20; +static const bool DEFAULT_CHECKPOINTS_ENABLED = true; +static const bool DEFAULT_TXINDEX = false; +static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100; + +static const bool DEFAULT_TESTSAFEMODE = false; +/** Default for -permitrbf */ +static const bool DEFAULT_PERMIT_REPLACEMENT = true; + +/** Maximum number of headers to announce when relaying blocks with headers message.*/ +static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8; struct BlockHasher { @@ -110,11 +142,18 @@ extern int nScriptCheckThreads; extern bool fTxIndex; extern bool fIsBareMultisigStd; extern bool fRequireStandard; +extern unsigned int nBytesPerSigOp; extern bool fCheckBlockIndex; extern bool fCheckpointsEnabled; extern size_t nCoinCacheUsage; +/** A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) */ extern CFeeRate minRelayTxFee; +/** Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendrawtransaction) */ +extern CAmount maxTxFee; extern bool fAlerts; +/** If the tip is older than this (in seconds), the node is considered to be in initial block download. */ +extern int64_t nMaxTipAge; +extern bool fPermitReplacement; /** Best header we've seen so far (used for getheaders queries' starting points). */ extern CBlockIndex *pindexBestHeader; @@ -172,9 +211,9 @@ FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false); /** Translation to a filesystem path */ boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix); /** Import blocks from an external file */ -bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp = NULL); +bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskBlockPos *dbp = NULL); /** Initialize a new block tree database + block data on disk */ -bool InitBlockIndex(); +bool InitBlockIndex(const CChainParams& chainparams); /** Load the block tree and coins database from disk */ bool LoadBlockIndex(); /** Unload database information */ @@ -185,21 +224,26 @@ bool ProcessMessages(CNode* pfrom); * Send queued protocol messages to be sent to a give node. * * @param[in] pto The node which we are sending messages to. - * @param[in] fSendTrickle When true send the trickled data, otherwise trickle the data until true. */ -bool SendMessages(CNode* pto, bool fSendTrickle); +bool SendMessages(CNode* pto); /** Run an instance of the script checking thread */ void ThreadScriptCheck(); /** Try to detect Partition (network isolation) attacks against us */ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const CBlockIndex *const &bestHeader, int64_t nPowTargetSpacing); /** Check whether we are doing an initial block download (synchronizing from disk or network) */ bool IsInitialBlockDownload(); -/** Format a string that describes several potential problems detected by the core */ +/** Format a string that describes several potential problems detected by the core. + * strFor can have three values: + * - "rpc": get critical warnings, which should put the client in safe mode if non-empty + * - "statusbar": get all warnings + * - "gui": get all warnings, translated (where possible) for GUI + * This function only returns the highest priority warning of the set selected by strFor. + */ std::string GetWarnings(const std::string& strFor); /** Retrieve a transaction (from memory pool, or from disk, if possible) */ bool GetTransaction(const uint256 &hash, CTransaction &tx, const Consensus::Params& params, uint256 &hashBlock, bool fAllowSlow = false); /** Find the best known block, and make it the tip of the block chain */ -bool ActivateBestChain(CValidationState &state, const CBlock *pblock = NULL); +bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams, const CBlock* pblock = NULL); CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); /** @@ -210,14 +254,14 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); * * Pruning functions are called from FlushStateToDisk when the global fCheckForPruning flag has been set. * Block and undo files are deleted in lock-step (when blk00003.dat is deleted, so is rev00003.dat.) - * Pruning cannot take place until the longest chain is at least a certain length (100000 on mainnet, 1000 on testnet, 10 on regtest). + * Pruning cannot take place until the longest chain is at least a certain length (100000 on mainnet, 1000 on testnet, 1000 on regtest). * Pruning will never delete a block within a defined distance (currently 288) from the active chain's tip. * The block index is updated by unsetting HAVE_DATA and HAVE_UNDO for any blocks that were stored in the deleted files. * A db flag records the fact that at least some block files have been pruned. * * @param[out] setFilesToPrune The set of file indices that can be unlinked will be returned */ -void FindFilesToPrune(std::set& setFilesToPrune); +void FindFilesToPrune(std::set& setFilesToPrune, uint64_t nPruneAfterHeight); /** * Actually unlink the specified files @@ -239,6 +283,8 @@ void PruneAndFlush(); bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool* pfMissingInputs, bool fOverrideMempoolLimit=false, bool fRejectAbsurdFee=false); +/** Convert CValidationState to a human-readable message for logging */ +std::string FormatStateMessage(const CValidationState &state); struct CNodeStateStats { int nMisbehavior; @@ -273,8 +319,6 @@ struct CDiskTxPos : public CDiskBlockPos }; -CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree); - /** * Count ECDSA signature operations the old-fashioned (pre-0.6) way * @return number of sigops this transaction's outputs will produce when spent @@ -383,9 +427,6 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn /** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); -/** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */ -bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp); - class CBlockFileInfo { @@ -446,7 +487,7 @@ class CVerifyDB { public: CVerifyDB(); ~CVerifyDB(); - bool VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth); + bool VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, int nCheckLevel, int nCheckDepth); }; /** Find the last common block between the parameter chain and a locator. */ @@ -458,7 +499,7 @@ bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensus /** Remove invalidity status from a block and its descendants. */ bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex); -/** The currently-connected chain of blocks. */ +/** The currently-connected chain of blocks (protected by cs_main). */ extern CChain chainActive; /** Global variable that points to the active CCoinsView (protected by cs_main) */ diff --git a/src/memusage.h b/src/memusage.h index e96c5bf03..49760e64c 100644 --- a/src/memusage.h +++ b/src/memusage.h @@ -46,7 +46,9 @@ template static inline size_t DynamicUsage(const X * const &v) { ret static inline size_t MallocUsage(size_t alloc) { // Measured on libc6 2.19 on Linux. - if (sizeof(void*) == 8) { + if (alloc == 0) { + return 0; + } else if (sizeof(void*) == 8) { return ((alloc + 31) >> 4) << 4; } else if (sizeof(void*) == 4) { return ((alloc + 15) >> 3) << 3; @@ -74,6 +76,12 @@ static inline size_t DynamicUsage(const std::vector& v) return MallocUsage(v.capacity() * sizeof(X)); } +template +static inline size_t DynamicUsage(const prevector& v) +{ + return MallocUsage(v.allocated_memory()); +} + template static inline size_t DynamicUsage(const std::set& s) { diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index f8e877df2..8447f924e 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/merkleblock.h b/src/merkleblock.h index 904c22abc..996cd1262 100644 --- a/src/merkleblock.h +++ b/src/merkleblock.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/miner.cpp b/src/miner.cpp index bb6b51337..c454c0279 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,6 +10,7 @@ #include "chainparams.h" #include "coins.h" #include "consensus/consensus.h" +#include "consensus/merkle.h" #include "consensus/validation.h" #include "hash.h" #include "main.h" @@ -26,6 +27,7 @@ #include #include +#include using namespace std; @@ -39,48 +41,18 @@ using namespace std; // transactions in the memory pool. When we select transactions from the // pool, we select by highest priority or fee rate, so we might consider // transactions that depend on transactions that aren't yet in the block. -// The COrphan class keeps track of these 'temporary orphans' while -// CreateBlock is figuring out which transactions to include. -// -class COrphan -{ -public: - const CTransaction* ptx; - set setDependsOn; - CFeeRate feeRate; - double dPriority; - - COrphan(const CTransaction* ptxIn) : ptx(ptxIn), feeRate(0), dPriority(0) - { - } -}; uint64_t nLastBlockTx = 0; uint64_t nLastBlockSize = 0; -// We want to sort transactions by priority and fee rate, so: -typedef boost::tuple TxPriority; -class TxPriorityCompare +class ScoreCompare { - bool byFee; - public: - TxPriorityCompare(bool _byFee) : byFee(_byFee) { } + ScoreCompare() {} - bool operator()(const TxPriority& a, const TxPriority& b) + bool operator()(const CTxMemPool::txiter a, const CTxMemPool::txiter b) { - if (byFee) - { - if (a.get<1>() == b.get<1>()) - return a.get<0>() < b.get<0>(); - return a.get<1>() < b.get<1>(); - } - else - { - if (a.get<0>() == b.get<0>()) - return a.get<1>() < b.get<1>(); - return a.get<0>() < b.get<0>(); - } + return CompareTxMemPoolEntryByScore()(*b,*a); // Convert to less than } }; @@ -126,7 +98,7 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s // Largest block you're willing to create: unsigned int nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); - // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity: + // Limit to between 1K and MAX_BLOCK_SIZE-1K for sanity: nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize)); // How much of the block should be dedicated to high-priority transactions, @@ -140,6 +112,22 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); // Collect memory pool transactions into the block + CTxMemPool::setEntries inBlock; + CTxMemPool::setEntries waitSet; + + // This vector will be sorted into a priority queue: + vector vecPriority; + TxCoinAgePriorityCompare pricomparer; + std::map waitPriMap; + typedef std::map::iterator waitPriIter; + double actualPriority = -1; + + std::priority_queue, ScoreCompare> clearedTxs; + bool fPrintPriority = GetBoolArg("-printpriority", DEFAULT_PRINTPRIORITY); + uint64_t nBlockSize = 1000; + uint64_t nBlockTx = 0; + unsigned int nBlockSigOps = 100; + int lastFewTxs = 0; CAmount nFees = 0; { @@ -148,157 +136,102 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s const int nHeight = pindexPrev->nHeight + 1; pblock->nTime = GetAdjustedTime(); const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); - CCoinsViewCache view(pcoinsTip); - // Priority order to process transactions - list vOrphan; // list memory doesn't move - map > mapDependers; - bool fPrintPriority = GetBoolArg("-printpriority", false); + int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST) + ? nMedianTimePast + : pblock->GetBlockTime(); - // This vector will be sorted into a priority queue: - vector vecPriority; - vecPriority.reserve(mempool.mapTx.size()); - for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin(); - mi != mempool.mapTx.end(); ++mi) - { - const CTransaction& tx = mi->GetTx(); - - int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST) - ? nMedianTimePast - : pblock->GetBlockTime(); - - if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, nLockTimeCutoff)) - continue; - - COrphan* porphan = NULL; - double dPriority = 0; - CAmount nTotalIn = 0; - bool fMissingInputs = false; - BOOST_FOREACH(const CTxIn& txin, tx.vin) + bool fPriorityBlock = nBlockPrioritySize > 0; + if (fPriorityBlock) { + vecPriority.reserve(mempool.mapTx.size()); + for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin(); + mi != mempool.mapTx.end(); ++mi) { - // Read prev transaction - if (!view.HaveCoins(txin.prevout.hash)) - { - // This should never happen; all transactions in the memory - // pool should connect to either transactions in the chain - // or other transactions in the memory pool. - if (!mempool.mapTx.count(txin.prevout.hash)) - { - LogPrintf("ERROR: mempool transaction missing input\n"); - if (fDebug) assert("mempool transaction missing input" == 0); - fMissingInputs = true; - if (porphan) - vOrphan.pop_back(); - break; - } - - // Has to wait for dependencies - if (!porphan) - { - // Use list for automatic deletion - vOrphan.push_back(COrphan(&tx)); - porphan = &vOrphan.back(); - } - mapDependers[txin.prevout.hash].push_back(porphan); - porphan->setDependsOn.insert(txin.prevout.hash); - nTotalIn += mempool.mapTx.find(txin.prevout.hash)->GetTx().vout[txin.prevout.n].nValue; - continue; - } - const CCoins* coins = view.AccessCoins(txin.prevout.hash); - assert(coins); - - CAmount nValueIn = coins->vout[txin.prevout.n].nValue; - nTotalIn += nValueIn; - - int nConf = nHeight - coins->nHeight; - - dPriority += (double)nValueIn * nConf; + double dPriority = mi->GetPriority(nHeight); + CAmount dummy; + mempool.ApplyDeltas(mi->GetTx().GetHash(), dPriority, dummy); + vecPriority.push_back(TxCoinAgePriority(dPriority, mi)); } - if (fMissingInputs) continue; - - // Priority is sum(valuein * age) / modified_txsize - unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - dPriority = tx.ComputePriority(dPriority, nTxSize); - - uint256 hash = tx.GetHash(); - mempool.ApplyDeltas(hash, dPriority, nTotalIn); - - CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize); - - if (porphan) - { - porphan->dPriority = dPriority; - porphan->feeRate = feeRate; - } - else - vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx()))); + std::make_heap(vecPriority.begin(), vecPriority.end(), pricomparer); } - // Collect transactions into block - uint64_t nBlockSize = 1000; - uint64_t nBlockTx = 0; - int nBlockSigOps = 100; - bool fSortedByFee = (nBlockPrioritySize <= 0); + CTxMemPool::indexed_transaction_set::nth_index<3>::type::iterator mi = mempool.mapTx.get<3>().begin(); + CTxMemPool::txiter iter; - TxPriorityCompare comparer(fSortedByFee); - std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); - - while (!vecPriority.empty()) + while (mi != mempool.mapTx.get<3>().end() || !clearedTxs.empty()) { - // Take highest priority transaction off the priority queue: - double dPriority = vecPriority.front().get<0>(); - CFeeRate feeRate = vecPriority.front().get<1>(); - const CTransaction& tx = *(vecPriority.front().get<2>()); - - std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer); - vecPriority.pop_back(); - - // Size limits - unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - if (nBlockSize + nTxSize >= nBlockMaxSize) - continue; - - // Legacy limits on sigOps: - unsigned int nTxSigOps = GetLegacySigOpCount(tx); - if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) - continue; - - // Skip free transactions if we're past the minimum block size: - const uint256& hash = tx.GetHash(); - double dPriorityDelta = 0; - CAmount nFeeDelta = 0; - mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta); - if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize)) - continue; - - // Prioritise by fee once past the priority size or we run out of high-priority - // transactions: - if (!fSortedByFee && - ((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority))) - { - fSortedByFee = true; - comparer = TxPriorityCompare(fSortedByFee); - std::make_heap(vecPriority.begin(), vecPriority.end(), comparer); + bool priorityTx = false; + if (fPriorityBlock && !vecPriority.empty()) { // add a tx from priority queue to fill the blockprioritysize + priorityTx = true; + iter = vecPriority.front().second; + actualPriority = vecPriority.front().first; + std::pop_heap(vecPriority.begin(), vecPriority.end(), pricomparer); + vecPriority.pop_back(); + } + else if (clearedTxs.empty()) { // add tx with next highest score + iter = mempool.mapTx.project<0>(mi); + mi++; + } + else { // try to add a previously postponed child tx + iter = clearedTxs.top(); + clearedTxs.pop(); } - if (!view.HaveInputs(tx)) + if (inBlock.count(iter)) + continue; // could have been added to the priorityBlock + + const CTransaction& tx = iter->GetTx(); + + bool fOrphan = false; + BOOST_FOREACH(CTxMemPool::txiter parent, mempool.GetMemPoolParents(iter)) + { + if (!inBlock.count(parent)) { + fOrphan = true; + break; + } + } + if (fOrphan) { + if (priorityTx) + waitPriMap.insert(std::make_pair(iter,actualPriority)); + else + waitSet.insert(iter); + continue; + } + + unsigned int nTxSize = iter->GetTxSize(); + if (fPriorityBlock && + (nBlockSize + nTxSize >= nBlockPrioritySize || !AllowFree(actualPriority))) { + fPriorityBlock = false; + waitPriMap.clear(); + } + if (!priorityTx && + (iter->GetModifiedFee() < ::minRelayTxFee.GetFee(nTxSize) && nBlockSize >= nBlockMinSize)) { + break; + } + if (nBlockSize + nTxSize >= nBlockMaxSize) { + if (nBlockSize > nBlockMaxSize - 100 || lastFewTxs > 50) { + break; + } + // Once we're within 1000 bytes of a full block, only look at 50 more txs + // to try to fill the remaining space. + if (nBlockSize > nBlockMaxSize - 1000) { + lastFewTxs++; + } + continue; + } + + if (!IsFinalTx(tx, nHeight, nLockTimeCutoff)) continue; - CAmount nTxFees = view.GetValueIn(tx)-tx.GetValueOut(); - - nTxSigOps += GetP2SHSigOpCount(tx, view); - if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) + unsigned int nTxSigOps = iter->GetSigOpCount(); + if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) { + if (nBlockSigOps > MAX_BLOCK_SIGOPS - 2) { + break; + } continue; + } - // Note that flags: we don't want to set mempool/IsStandard() - // policy here, but we still have to ensure that the block we - // create only contains transactions that are valid in new blocks. - CValidationState state; - if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) - continue; - - UpdateCoins(tx, state, view, nHeight); - + CAmount nTxFees = iter->GetFee(); // Added pblock->vtx.push_back(tx); pblocktemplate->vTxFees.push_back(nTxFees); @@ -310,31 +243,37 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s if (fPrintPriority) { + double dPriority = iter->GetPriority(nHeight); + CAmount dummy; + mempool.ApplyDeltas(tx.GetHash(), dPriority, dummy); LogPrintf("priority %.1f fee %s txid %s\n", - dPriority, feeRate.ToString(), tx.GetHash().ToString()); + dPriority , CFeeRate(iter->GetModifiedFee(), nTxSize).ToString(), tx.GetHash().ToString()); } + inBlock.insert(iter); + // Add transactions that depend on this one to the priority queue - if (mapDependers.count(hash)) + BOOST_FOREACH(CTxMemPool::txiter child, mempool.GetMemPoolChildren(iter)) { - BOOST_FOREACH(COrphan* porphan, mapDependers[hash]) - { - if (!porphan->setDependsOn.empty()) - { - porphan->setDependsOn.erase(hash); - if (porphan->setDependsOn.empty()) - { - vecPriority.push_back(TxPriority(porphan->dPriority, porphan->feeRate, porphan->ptx)); - std::push_heap(vecPriority.begin(), vecPriority.end(), comparer); - } + if (fPriorityBlock) { + waitPriIter wpiter = waitPriMap.find(child); + if (wpiter != waitPriMap.end()) { + vecPriority.push_back(TxCoinAgePriority(wpiter->second,child)); + std::push_heap(vecPriority.begin(), vecPriority.end(), pricomparer); + waitPriMap.erase(wpiter); + } + } + else { + if (waitSet.count(child)) { + clearedTxs.push(child); + waitSet.erase(child); } } } } - nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; - LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize); + LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOps); // Compute final coinbase transaction. txNew.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus()); @@ -350,8 +289,9 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); CValidationState state; - if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) - throw std::runtime_error("CreateNewBlock(): TestBlockValidity failed"); + if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) { + throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state))); + } } return pblocktemplate.release(); @@ -373,7 +313,7 @@ void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned assert(txCoinbase.vin[0].scriptSig.size() <= 100); pblock->vtx[0] = txCoinbase; - pblock->hashMerkleRoot = pblock->ComputeMerkleRoot(); + pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); } ////////////////////////////////////////////////////////////////////////////// diff --git a/src/miner.h b/src/miner.h index 7b544303e..512494198 100644 --- a/src/miner.h +++ b/src/miner.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -17,8 +17,11 @@ class CScript; class CWallet; namespace Consensus { struct Params; }; +static const bool DEFAULT_GENERATE = false; static const int DEFAULT_GENERATE_THREADS = 1; +static const bool DEFAULT_PRINTPRIORITY = false; + struct CBlockTemplate { CBlock block; diff --git a/src/mruset.h b/src/mruset.h deleted file mode 100644 index 398aa173b..000000000 --- a/src/mruset.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2012-2015 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_MRUSET_H -#define BITCOIN_MRUSET_H - -#include -#include -#include - -/** STL-like set container that only keeps the most recent N elements. */ -template -class mruset -{ -public: - typedef T key_type; - typedef T value_type; - typedef typename std::set::iterator iterator; - typedef typename std::set::const_iterator const_iterator; - typedef typename std::set::size_type size_type; - -protected: - std::set set; - std::vector order; - size_type first_used; - size_type first_unused; - const size_type nMaxSize; - -public: - mruset(size_type nMaxSizeIn = 1) : nMaxSize(nMaxSizeIn) { clear(); } - iterator begin() const { return set.begin(); } - iterator end() const { return set.end(); } - size_type size() const { return set.size(); } - bool empty() const { return set.empty(); } - iterator find(const key_type& k) const { return set.find(k); } - size_type count(const key_type& k) const { return set.count(k); } - void clear() - { - set.clear(); - order.assign(nMaxSize, set.end()); - first_used = 0; - first_unused = 0; - } - bool inline friend operator==(const mruset& a, const mruset& b) { return a.set == b.set; } - bool inline friend operator==(const mruset& a, const std::set& b) { return a.set == b; } - bool inline friend operator<(const mruset& a, const mruset& b) { return a.set < b.set; } - std::pair insert(const key_type& x) - { - std::pair ret = set.insert(x); - if (ret.second) { - if (set.size() == nMaxSize + 1) { - set.erase(order[first_used]); - order[first_used] = set.end(); - if (++first_used == nMaxSize) first_used = 0; - } - order[first_unused] = ret.first; - if (++first_unused == nMaxSize) first_unused = 0; - } - return ret; - } - size_type max_size() const { return nMaxSize; } -}; - -#endif // BITCOIN_MRUSET_H diff --git a/src/net.cpp b/src/net.cpp index 2b804b0b4..04bf71509 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -36,7 +36,9 @@ #include #include -// Dump addresses to peers.dat every 15 minutes (900s) +#include + +// Dump addresses to peers.dat and banlist.dat every 15 minutes (900s) #define DUMP_ADDRESSES_INTERVAL 900 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) @@ -67,6 +69,8 @@ namespace { }; } +const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*"; + // // Global state variables // @@ -459,7 +463,7 @@ void CNode::PushVersion() LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id); else LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id); - PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, + PushMessage(NetMsgType::VERSION, PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, strSubVersion, nBestHeight, !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)); } @@ -521,12 +525,11 @@ void CNode::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t banti banEntry.banReason = banReason; if (bantimeoffset <= 0) { - bantimeoffset = GetArg("-bantime", 60*60*24); // Default 24-hour ban + bantimeoffset = GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME); sinceUnixEpoch = false; } banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset; - LOCK(cs_setBanned); if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) setBanned[subNet] = banEntry; @@ -570,11 +573,13 @@ void CNode::SweepBanned() banmap_t::iterator it = setBanned.begin(); while(it != setBanned.end()) { + CSubNet subNet = (*it).first; CBanEntry banEntry = (*it).second; if(now > banEntry.nBanUntil) { setBanned.erase(it++); setBannedIsDirty = true; + LogPrint("net", "%s: Removed banned node ip/subnet from banlist.dat: %s\n", __func__, subNet.ToString()); } else ++it; @@ -628,7 +633,9 @@ void CNode::copyStats(CNodeStats &stats) X(fInbound); X(nStartingHeight); X(nSendBytes); + X(mapSendBytesPerMsgCmd); X(nRecvBytes); + X(mapRecvBytesPerMsgCmd); X(fWhitelisted); // It is common for nodes with good ping times to suddenly become lagged, @@ -683,6 +690,15 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes) nBytes -= handled; if (msg.complete()) { + + //store received bytes per message command + //to prevent a memory DOS, only allow valid commands + mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.hdr.pchCommand); + if (i == mapRecvBytesPerMsgCmd.end()) + i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER); + assert(i != mapRecvBytesPerMsgCmd.end()); + i->second += msg.hdr.nMessageSize + CMessageHeader::HEADER_SIZE; + msg.nTime = GetTimeMicros(); messageHandlerCondition.notify_one(); } @@ -883,8 +899,6 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { continue; if (node->fDisconnect) continue; - if (node->addr.IsLocal()) - continue; vEvictionCandidates.push_back(CNodeRef(node)); } } @@ -915,15 +929,20 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { if (vEvictionCandidates.empty()) return false; - // Identify the network group with the most connections + // Identify the network group with the most connections and youngest member. + // (vEvictionCandidates is already sorted by reverse connect time) std::vector naMostConnections; unsigned int nMostConnections = 0; + int64_t nMostConnectionsTime = 0; std::map, std::vector > mapAddrCounts; BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) { mapAddrCounts[node->addr.GetGroup()].push_back(node); + int64_t grouptime = mapAddrCounts[node->addr.GetGroup()][0]->nTimeConnected; + size_t groupsize = mapAddrCounts[node->addr.GetGroup()].size(); - if (mapAddrCounts[node->addr.GetGroup()].size() > nMostConnections) { - nMostConnections = mapAddrCounts[node->addr.GetGroup()].size(); + if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) { + nMostConnections = groupsize; + nMostConnectionsTime = grouptime; naMostConnections = node->addr.GetGroup(); } } @@ -931,14 +950,13 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { // Reduce to the network group with the most connections vEvictionCandidates = mapAddrCounts[naMostConnections]; - // Do not disconnect peers if there is only 1 connection from their network group + // Do not disconnect peers if there is only one unprotected connection from their network group. if (vEvictionCandidates.size() <= 1) // unless we prefer the new connection (for whitelisted peers) if (!fPreferNewConnection) return false; - // Disconnect the most recent connection from the network group with the most connections - std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected); + // Disconnect from the network group with the most connections vEvictionCandidates[0]->fDisconnect = true; return true; @@ -1356,7 +1374,7 @@ void ThreadMapPort() LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r)); else - LogPrintf("UPnP Port Mapping successful.\n");; + LogPrintf("UPnP Port Mapping successful.\n"); MilliSleep(20*60*1000); // Refresh every 20 minutes } @@ -1414,7 +1432,7 @@ void ThreadDNSAddressSeed() { // goal: only query DNS seeds if address need is acute if ((addrman.size() > 0) && - (!GetBoolArg("-forcednsseed", false))) { + (!GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) { MilliSleep(11 * 1000); LOCK(cs_vNodes); @@ -1478,12 +1496,7 @@ void DumpAddresses() void DumpData() { DumpAddresses(); - - if (CNode::BannedSetIsDirty()) - { - DumpBanlist(); - CNode::SetBannedSetDirty(false); - } + DumpBanlist(); } void static ProcessOneShot() @@ -1721,11 +1734,6 @@ void ThreadMessageHandler() } } - // Poll the connected nodes for messages - CNode* pnodeTrickle = NULL; - if (!vNodesCopy.empty()) - pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())]; - bool fSleep = true; BOOST_FOREACH(CNode* pnode, vNodesCopy) @@ -1756,7 +1764,7 @@ void ThreadMessageHandler() { TRY_LOCK(pnode->cs_vSend, lockSend); if (lockSend) - g_signals.SendMessages(pnode, pnode == pnodeTrickle || pnode->fWhitelisted); + g_signals.SendMessages(pnode); } boost::this_thread::interruption_point(); } @@ -1929,31 +1937,36 @@ void static Discover(boost::thread_group& threadGroup) void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) { uiInterface.InitMessage(_("Loading addresses...")); - // Load addresses for peers.dat + // Load addresses from peers.dat int64_t nStart = GetTimeMillis(); { CAddrDB adb; - if (!adb.Read(addrman)) + if (adb.Read(addrman)) + LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart); + else LogPrintf("Invalid or missing peers.dat; recreating\n"); } - //try to read stored banlist + uiInterface.InitMessage(_("Loading banlist...")); + // Load addresses from banlist.dat + nStart = GetTimeMillis(); CBanDB bandb; banmap_t banmap; - if (!bandb.Read(banmap)) + if (bandb.Read(banmap)) { + CNode::SetBanned(banmap); // thread save setter + CNode::SetBannedSetDirty(false); // no need to write down, just read data + CNode::SweepBanned(); // sweep out unused entries + + LogPrint("net", "Loaded %d banned node ips/subnets from banlist.dat %dms\n", + banmap.size(), GetTimeMillis() - nStart); + } else LogPrintf("Invalid or missing banlist.dat; recreating\n"); - CNode::SetBanned(banmap); //thread save setter - CNode::SetBannedSetDirty(false); //no need to write down just read or nonexistent data - CNode::SweepBanned(); //sweap out unused entries - - LogPrintf("Loaded %i addresses from peers.dat %dms\n", - addrman.size(), GetTimeMillis() - nStart); fAddressesInitialized = true; if (semOutbound == NULL) { // initialize semaphore - int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections); + int nMaxOutbound = std::min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections); semOutbound = new CSemaphore(nMaxOutbound); } @@ -2168,7 +2181,7 @@ bool CNode::OutboundTargetReached(bool historicalBlockServingLimit) if (historicalBlockServingLimit) { - // keep a large enought buffer to at least relay each block once + // keep a large enough buffer to at least relay each block once uint64_t timeLeftInCycle = GetMaxOutboundTimeLeftInCycle(); uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SIZE; if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer) @@ -2337,13 +2350,13 @@ bool CAddrDB::Read(CAddrMan& addr) return true; } -unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); } -unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); } +unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER); } +unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER); } CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), addrKnown(5000, 0.001), - setInventoryKnown(SendBufferSize() / 1000) + filterInventoryKnown(50000, 0.000001) { nServices = 0; hSocket = hSocketIn; @@ -2370,7 +2383,11 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nSendOffset = 0; hashContinue = uint256(); nStartingHeight = -1; + filterInventoryKnown.reset(); fGetAddr = false; + nNextLocalAddrSend = 0; + nNextAddrSend = 0; + nNextInvSend = 0; fRelayTxes = false; pfilter = new CBloomFilter(); nPingNonceSent = 0; @@ -2378,6 +2395,9 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa nPingUsecTime = 0; fPingQueued = false; nMinPingUsecTime = std::numeric_limits::max(); + BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes()) + mapRecvBytesPerMsgCmd[msg] = 0; + mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0; { LOCK(cs_nLastNodeId); @@ -2408,8 +2428,12 @@ CNode::~CNode() void CNode::AskFor(const CInv& inv) { - if (mapAskFor.size() > MAPASKFOR_MAX_SZ) + if (mapAskFor.size() > MAPASKFOR_MAX_SZ || setAskFor.size() > SETASKFOR_MAX_SZ) return; + // a peer may not have multiple non-responded queue positions for a single inv item + if (!setAskFor.insert(inv.hash).second) + return; + // We're using mapAskFor as a priority queue, // the key is the earliest time the request can be sent int64_t nRequestTime; @@ -2453,7 +2477,7 @@ void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend) LogPrint("net", "(aborted)\n"); } -void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend) +void CNode::EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend) { // The -*messagestest options are intentionally not documented in the help message, // since they are only used during development to debug the networking code and are @@ -2476,6 +2500,9 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend) unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE; WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize); + //log total amount of bytes per command + mapSendBytesPerMsgCmd[std::string(pszCommand)] += nSize + CMessageHeader::HEADER_SIZE; + // Set the checksum uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end()); unsigned int nChecksum = 0; @@ -2586,28 +2613,36 @@ bool CBanDB::Read(banmap_t& banSet) // ... verify the network matches ours if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) return error("%s: Invalid network magic number", __func__); - + // de-serialize address data into one CAddrMan object ssBanlist >> banSet; } catch (const std::exception& e) { return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } - + return true; } void DumpBanlist() { - int64_t nStart = GetTimeMillis(); + CNode::SweepBanned(); // clean unused entries (if bantime has expired) - CNode::SweepBanned(); //clean unused entries (if bantime has expired) + if (!CNode::BannedSetIsDirty()) + return; + + int64_t nStart = GetTimeMillis(); CBanDB bandb; banmap_t banmap; CNode::GetBanned(banmap); - bandb.Write(banmap); + if (bandb.Write(banmap)) + CNode::SetBannedSetDirty(false); LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", - banmap.size(), GetTimeMillis() - nStart); + banmap.size(), GetTimeMillis() - nStart); +} + +int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) { + return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5); } diff --git a/src/net.h b/src/net.h index 559cdf087..5f249c445 100644 --- a/src/net.h +++ b/src/net.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,7 +9,6 @@ #include "bloom.h" #include "compat.h" #include "limitedmap.h" -#include "mruset.h" #include "netbase.h" #include "protocol.h" #include "random.h" @@ -58,6 +57,8 @@ static const bool DEFAULT_UPNP = false; #endif /** The maximum number of entries in mapAskFor */ static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ; +/** The maximum number of entries in setAskFor (larger due to getdata latency)*/ +static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ; /** The maximum number of peer connections to maintain. */ static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125; /** The default for -maxuploadtarget. 0 = Unlimited */ @@ -65,6 +66,13 @@ static const uint64_t DEFAULT_MAX_UPLOAD_TARGET = 0; /** Default for blocks only*/ static const bool DEFAULT_BLOCKSONLY = false; +static const bool DEFAULT_FORCEDNSSEED = false; +static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000; +static const size_t DEFAULT_MAXSENDBUFFER = 1 * 1000; + +// NOTE: When adjusting this, update rpcnet:setban's help ("24h") +static const unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban + unsigned int ReceiveFloodSize(); unsigned int SendBufferSize(); @@ -105,7 +113,7 @@ struct CNodeSignals { boost::signals2::signal GetHeight; boost::signals2::signal ProcessMessages; - boost::signals2::signal SendMessages; + boost::signals2::signal SendMessages; boost::signals2::signal InitializeNode; boost::signals2::signal FinalizeNode; }; @@ -174,6 +182,7 @@ struct LocalServiceInfo { extern CCriticalSection cs_mapLocalHost; extern std::map mapLocalHost; +typedef std::map mapMsgCmdSize; //command, total bytes class CNodeStats { @@ -191,7 +200,9 @@ public: bool fInbound; int nStartingHeight; uint64_t nSendBytes; + mapMsgCmdSize mapSendBytesPerMsgCmd; uint64_t nRecvBytes; + mapMsgCmdSize mapRecvBytesPerMsgCmd; bool fWhitelisted; double dPingTime; double dPingWait; @@ -365,6 +376,9 @@ protected: static std::vector vWhitelistedRange; static CCriticalSection cs_vWhitelistedRange; + mapMsgCmdSize mapSendBytesPerMsgCmd; + mapMsgCmdSize mapRecvBytesPerMsgCmd; + // Basic fuzz-testing void Fuzz(int nChance); // modifies ssSend @@ -377,12 +391,19 @@ public: CRollingBloomFilter addrKnown; bool fGetAddr; std::set setKnown; + int64_t nNextAddrSend; + int64_t nNextLocalAddrSend; // inventory based relay - mruset setInventoryKnown; + CRollingBloomFilter filterInventoryKnown; std::vector vInventoryToSend; CCriticalSection cs_inventory; + std::set setAskFor; std::multimap mapAskFor; + int64_t nNextInvSend; + // Used for headers announcements - unfiltered blocks to relay + // Also protected by cs_inventory + std::vector vBlockHashesToAnnounce; // Ping time measurement: // The pong reply we're expecting, or 0 if no pong expected. @@ -484,7 +505,7 @@ public: { { LOCK(cs_inventory); - setInventoryKnown.insert(inv); + filterInventoryKnown.insert(inv.hash); } } @@ -492,11 +513,18 @@ public: { { LOCK(cs_inventory); - if (!setInventoryKnown.count(inv)) - vInventoryToSend.push_back(inv); + if (inv.type == MSG_TX && filterInventoryKnown.contains(inv.hash)) + return; + vInventoryToSend.push_back(inv); } } + void PushBlockHash(const uint256 &hash) + { + LOCK(cs_inventory); + vBlockHashesToAnnounce.push_back(hash); + } + void AskFor(const CInv& inv); // TODO: Document the postcondition of this function. Is cs_vSend locked? @@ -506,7 +534,7 @@ public: void AbortMessage() UNLOCK_FUNCTION(cs_vSend); // TODO: Document the precondition of this function. Is cs_vSend locked? - void EndMessage() UNLOCK_FUNCTION(cs_vSend); + void EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend); void PushVersion(); @@ -516,7 +544,7 @@ public: try { BeginMessage(pszCommand); - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -532,7 +560,7 @@ public: { BeginMessage(pszCommand); ssSend << a1; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -548,7 +576,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -564,7 +592,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -580,7 +608,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -596,7 +624,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -612,7 +640,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5 << a6; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -628,7 +656,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -644,7 +672,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -660,7 +688,7 @@ public: { BeginMessage(pszCommand); ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9; - EndMessage(); + EndMessage(pszCommand); } catch (...) { @@ -766,4 +794,7 @@ public: void DumpBanlist(); +/** Return a timestamp in the future (in microseconds) for exponentially distributed events. */ +int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds); + #endif // BITCOIN_NET_H diff --git a/src/netbase.cpp b/src/netbase.cpp index 83cedfb62..7f79dd02c 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -40,7 +40,7 @@ static proxyType proxyInfo[NET_MAX]; static proxyType nameProxy; static CCriticalSection cs_proxyInfos; int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; -bool fNameLookup = false; +bool fNameLookup = DEFAULT_NAME_LOOKUP; static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; @@ -140,7 +140,7 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign return false; do { - // Should set the timeout limit to a resonable value to avoid + // Should set the timeout limit to a reasonable value to avoid // generating unnecessary checking call during the polling loop, // while it can still response to stop request quick enough. // 2 seconds looks fine in our situation. diff --git a/src/netbase.h b/src/netbase.h index 2a79f82d7..1db66ac27 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -19,8 +19,10 @@ extern int nConnectTimeout; extern bool fNameLookup; -/** -timeout default */ +//! -timeout default static const int DEFAULT_CONNECT_TIMEOUT = 5000; +//! -dns default +static const int DEFAULT_NAME_LOOKUP = true; #ifdef WIN32 // In MSVC, this is defined as a macro, undefine it to prevent a compile and link error diff --git a/src/noui.h b/src/noui.h index 15cd30a63..ff16cc9aa 100644 --- a/src/noui.h +++ b/src/noui.h @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-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. diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index ffe31d194..de3c060d6 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -4,6 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "policy/fees.h" +#include "policy/policy.h" #include "amount.h" #include "primitives/transaction.h" @@ -86,7 +87,7 @@ double TxConfirmStats::EstimateMedianVal(int confTarget, double sufficientTxVal, int maxbucketindex = buckets.size() - 1; // requireGreater means we are looking for the lowest fee/priority such that all higher - // values pass, so we start at maxbucketindex (highest fee) and look at succesively + // values pass, so we start at maxbucketindex (highest fee) and look at successively // smaller buckets until we reach failure. Otherwise, we are looking for the highest // fee/priority such that all lower values fail, and we go in the opposite direction. unsigned int startbucket = requireGreater ? maxbucketindex : 0; @@ -504,6 +505,33 @@ CFeeRate CBlockPolicyEstimator::estimateFee(int confTarget) return CFeeRate(median); } +CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool) +{ + if (answerFoundAtTarget) + *answerFoundAtTarget = confTarget; + // Return failure if trying to analyze a target we're not tracking + if (confTarget <= 0 || (unsigned int)confTarget > feeStats.GetMaxConfirms()) + return CFeeRate(0); + + double median = -1; + while (median < 0 && (unsigned int)confTarget <= feeStats.GetMaxConfirms()) { + median = feeStats.EstimateMedianVal(confTarget++, SUFFICIENT_FEETXS, MIN_SUCCESS_PCT, true, nBestSeenHeight); + } + + if (answerFoundAtTarget) + *answerFoundAtTarget = confTarget - 1; + + // If mempool is limiting txs , return at least the min fee from the mempool + CAmount minPoolFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(); + if (minPoolFee > 0 && minPoolFee > median) + return CFeeRate(minPoolFee); + + if (median < 0) + return CFeeRate(0); + + return CFeeRate(median); +} + double CBlockPolicyEstimator::estimatePriority(int confTarget) { // Return failure if trying to analyze a target we're not tracking @@ -513,6 +541,30 @@ double CBlockPolicyEstimator::estimatePriority(int confTarget) return priStats.EstimateMedianVal(confTarget, SUFFICIENT_PRITXS, MIN_SUCCESS_PCT, true, nBestSeenHeight); } +double CBlockPolicyEstimator::estimateSmartPriority(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool) +{ + if (answerFoundAtTarget) + *answerFoundAtTarget = confTarget; + // Return failure if trying to analyze a target we're not tracking + if (confTarget <= 0 || (unsigned int)confTarget > priStats.GetMaxConfirms()) + return -1; + + // If mempool is limiting txs, no priority txs are allowed + CAmount minPoolFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(); + if (minPoolFee > 0) + return INF_PRIORITY; + + double median = -1; + while (median < 0 && (unsigned int)confTarget <= priStats.GetMaxConfirms()) { + median = priStats.EstimateMedianVal(confTarget++, SUFFICIENT_PRITXS, MIN_SUCCESS_PCT, true, nBestSeenHeight); + } + + if (answerFoundAtTarget) + *answerFoundAtTarget = confTarget - 1; + + return median; +} + void CBlockPolicyEstimator::Write(CAutoFile& fileout) { fileout << nBestSeenHeight; diff --git a/src/policy/fees.h b/src/policy/fees.h index 15577d128..3fa31c39e 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -15,6 +15,7 @@ class CAutoFile; class CFeeRate; class CTxMemPoolEntry; +class CTxMemPool; /** \class CBlockPolicyEstimator * The BlockPolicyEstimator is used for estimating the fee or priority needed @@ -28,7 +29,7 @@ class CTxMemPoolEntry; * included in blocks before transactions of lower fee/priority. So for * example if you wanted to know what fee you should put on a transaction to * be included in a block within the next 5 blocks, you would start by looking - * at the bucket with with the highest fee transactions and verifying that a + * at the bucket with the highest fee transactions and verifying that a * sufficiently high percentage of them were confirmed within 5 blocks and * then you would look at the next highest fee bucket, and so on, stopping at * the last bucket to pass the test. The average fee of transactions in this @@ -86,13 +87,13 @@ private: // Count the total # of txs in each bucket // Track the historical moving average of this total over blocks std::vector txCtAvg; - // and calcuate the total for the current block to update the moving average + // and calculate the total for the current block to update the moving average std::vector curBlockTxCt; // Count the total # of txs confirmed within Y blocks in each bucket // Track the historical moving average of theses totals over blocks std::vector > confAvg; // confAvg[Y][X] - // and calcuate the totals for the current block to update the moving averages + // and calculate the totals for the current block to update the moving averages std::vector > curBlockConf; // curBlockConf[Y][X] // Sum the total priority/fee of all tx's in each bucket @@ -182,8 +183,8 @@ static const unsigned int MAX_BLOCK_CONFIRMS = 25; /** Decay of .998 is a half-life of 346 blocks or about 2.4 days */ static const double DEFAULT_DECAY = .998; -/** Require greater than 85% of X fee transactions to be confirmed within Y blocks for X to be big enough */ -static const double MIN_SUCCESS_PCT = .85; +/** Require greater than 95% of X fee transactions to be confirmed within Y blocks for X to be big enough */ +static const double MIN_SUCCESS_PCT = .95; static const double UNLIKELY_PCT = .5; /** Require an avg of 1 tx in the combined fee bucket per block to have stat significance */ @@ -242,9 +243,21 @@ public: /** Return a fee estimate */ CFeeRate estimateFee(int confTarget); + /** Estimate fee rate needed to get be included in a block within + * confTarget blocks. If no answer can be given at confTarget, return an + * estimate at the lowest target where one can be given. + */ + CFeeRate estimateSmartFee(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool); + /** Return a priority estimate */ double estimatePriority(int confTarget); + /** Estimate priority needed to get be included in a block within + * confTarget blocks. If no answer can be given at confTarget, return an + * estimate at the lowest target where one can be given. + */ + double estimateSmartPriority(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool); + /** Write estimation data to a file */ void Write(CAutoFile& fileout); diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 4c96fbf5a..332abc430 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -23,9 +23,6 @@ * 2. P2SH scripts with a crazy number of expensive * CHECKSIG/CHECKMULTISIG operations * - * Check transaction inputs, and make sure any - * pay-to-script-hash transactions are evaluating IsStandard scripts - * * Why bother? To avoid denial-of-service attacks; an attacker * can submit a standard HASH... OP_EQUAL transaction, * which will get accepted into blocks. The redemption @@ -50,7 +47,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) if (m < 1 || m > n) return false; } else if (whichType == TX_NULL_DATA && - (!GetBoolArg("-datacarrier", true) || scriptPubKey.size() > nMaxDatacarrierBytes)) + (!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) return false; return whichType != TX_NONSTANDARD; @@ -135,45 +132,20 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) const CScript& prevScript = prev.scriptPubKey; if (!Solver(prevScript, whichType, vSolutions)) return false; - int nArgsExpected = ScriptSigArgsExpected(whichType, vSolutions); - if (nArgsExpected < 0) - return false; - - // Transactions with extra stuff in their scriptSigs are - // non-standard. Note that this EvalScript() call will - // be quick, because if there are any operations - // beside "push data" in the scriptSig - // IsStandardTx() will have already returned false - // and this method isn't called. - std::vector > stack; - if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker())) - return false; if (whichType == TX_SCRIPTHASH) { + std::vector > stack; + // convert the scriptSig into a stack, so we can inspect the redeemScript + if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), 0)) + return false; if (stack.empty()) return false; CScript subscript(stack.back().begin(), stack.back().end()); - std::vector > vSolutions2; - txnouttype whichType2; - if (Solver(subscript, whichType2, vSolutions2)) - { - int tmpExpected = ScriptSigArgsExpected(whichType2, vSolutions2); - if (tmpExpected < 0) - return false; - nArgsExpected += tmpExpected; - } - else - { - // Any other Script with less than 15 sigops OK: - unsigned int sigops = subscript.GetSigOpCount(true); - // ... extra data left on the stack after execution is OK, too: - return (sigops <= MAX_P2SH_SIGOPS); + if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) { + return false; } } - - if (stack.size() != (unsigned int)nArgsExpected) - return false; } return true; diff --git a/src/policy/policy.h b/src/policy/policy.h index f269e8d47..726864f19 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin developers +// Copyright (c) 2009-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -18,13 +18,15 @@ class CCoinsViewCache; static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750000; static const unsigned int DEFAULT_BLOCK_MIN_SIZE = 0; /** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/ -static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 50000; +static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 0; /** The maximum size for transactions we're willing to relay/mine */ static const unsigned int MAX_STANDARD_TX_SIZE = 100000; /** Maximum number of signature check operations in an IsStandard() P2SH script */ static const unsigned int MAX_P2SH_SIGOPS = 15; /** The maximum number of sigops we're willing to relay/mine in a single tx */ static const unsigned int MAX_STANDARD_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; +/** Default for -maxmempool, maximum megabytes of mempool memory usage */ +static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300; /** * Standard script verification flags that standard transactions will comply * with. However scripts violating these flags may still be present in valid diff --git a/src/policy/rbf.cpp b/src/policy/rbf.cpp new file mode 100644 index 000000000..98b1a1ba4 --- /dev/null +++ b/src/policy/rbf.cpp @@ -0,0 +1,46 @@ +// Copyright (c) 2016 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "policy/rbf.h" + +bool SignalsOptInRBF(const CTransaction &tx) +{ + BOOST_FOREACH(const CTxIn &txin, tx.vin) { + if (txin.nSequence < std::numeric_limits::max()-1) { + return true; + } + } + return false; +} + +bool IsRBFOptIn(const CTxMemPoolEntry &entry, CTxMemPool &pool) +{ + AssertLockHeld(pool.cs); + + CTxMemPool::setEntries setAncestors; + + // First check the transaction itself. + if (SignalsOptInRBF(entry.GetTx())) { + return true; + } + + // If this transaction is not in our mempool, then we can't be sure + // we will know about all its inputs. + if (!pool.exists(entry.GetTx().GetHash())) { + throw std::runtime_error("Cannot determine RBF opt-in signal for non-mempool transaction\n"); + } + + // If all the inputs have nSequence >= maxint-1, it still might be + // signaled for RBF if any unconfirmed parents have signaled. + uint64_t noLimit = std::numeric_limits::max(); + std::string dummy; + pool.CalculateMemPoolAncestors(entry, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false); + + BOOST_FOREACH(CTxMemPool::txiter it, setAncestors) { + if (SignalsOptInRBF(it->GetTx())) { + return true; + } + } + return false; +} diff --git a/src/policy/rbf.h b/src/policy/rbf.h new file mode 100644 index 000000000..925ce0d9b --- /dev/null +++ b/src/policy/rbf.h @@ -0,0 +1,20 @@ +// Copyright (c) 2016 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_POLICY_RBF_H +#define BITCOIN_POLICY_RBF_H + +#include "txmempool.h" + +// Check whether the sequence numbers on this transaction are signaling +// opt-in to replace-by-fee, according to BIP 125 +bool SignalsOptInRBF(const CTransaction &tx); + +// Determine whether an in-mempool transaction is signaling opt-in to RBF +// according to BIP 125 +// This involves checking sequence numbers of the transaction, as well +// as the sequence numbers of all in-mempool ancestors. +bool IsRBFOptIn(const CTxMemPoolEntry &entry, CTxMemPool &pool); + +#endif // BITCOIN_POLICY_RBF_H diff --git a/src/pow.cpp b/src/pow.cpp index 5ace3fbc9..40c72f9d7 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -102,35 +102,3 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& return true; } - -arith_uint256 GetBlockProof(const CBlockIndex& block) -{ - arith_uint256 bnTarget; - bool fNegative; - bool fOverflow; - bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); - if (fNegative || fOverflow || bnTarget == 0) - return 0; - // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 - // as it's too large for a arith_uint256. However, as 2**256 is at least as large - // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, - // or ~bnTarget / (nTarget+1) + 1. - return (~bnTarget / (bnTarget + 1)) + 1; -} - -int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params) -{ - arith_uint256 r; - int sign = 1; - if (to.nChainWork > from.nChainWork) { - r = to.nChainWork - from.nChainWork; - } else { - r = from.nChainWork - to.nChainWork; - sign = -1; - } - r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip); - if (r.bits() > 63) { - return sign * std::numeric_limits::max(); - } - return sign * r.GetLow64(); -} diff --git a/src/pow.h b/src/pow.h index e864a474c..23e9c1c35 100644 --- a/src/pow.h +++ b/src/pow.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -13,16 +13,11 @@ class CBlockHeader; class CBlockIndex; class uint256; -class arith_uint256; unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&); unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&); /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&); -arith_uint256 GetBlockProof(const CBlockIndex& block); - -/** Return the time it would take to redo the work difference between from and to, assuming the current hashrate corresponds to the difficulty at tip, in seconds. */ -int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&); #endif // BITCOIN_POW_H diff --git a/src/prevector.h b/src/prevector.h new file mode 100644 index 000000000..1da459bcf --- /dev/null +++ b/src/prevector.h @@ -0,0 +1,490 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef _BITCOIN_PREVECTOR_H_ +#define _BITCOIN_PREVECTOR_H_ + +#include +#include +#include + +#include + +#pragma pack(push, 1) +/** Implements a drop-in replacement for std::vector which stores up to N + * elements directly (without heap allocation). The types Size and Diff are + * used to store element counts, and can be any unsigned + signed type. + * + * Storage layout is either: + * - Direct allocation: + * - Size _size: the number of used elements (between 0 and N) + * - T direct[N]: an array of N elements of type T + * (only the first _size are initialized). + * - Indirect allocation: + * - Size _size: the number of used elements plus N + 1 + * - Size capacity: the number of allocated elements + * - T* indirect: a pointer to an array of capacity elements of type T + * (only the first _size are initialized). + * + * The data type T must be movable by memmove/realloc(). Once we switch to C++, + * move constructors can be used instead. + */ +template +class prevector { +public: + typedef Size size_type; + typedef Diff difference_type; + typedef T value_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + + class iterator { + T* ptr; + public: + typedef Diff difference_type; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef std::random_access_iterator_tag iterator_category; + iterator(T* ptr_) : ptr(ptr_) {} + T& operator*() const { return *ptr; } + T* operator->() const { return ptr; } + T& operator[](size_type pos) { return ptr[pos]; } + const T& operator[](size_type pos) const { return ptr[pos]; } + iterator& operator++() { ptr++; return *this; } + iterator& operator--() { ptr--; return *this; } + iterator operator++(int) { iterator copy(*this); ++(*this); return copy; } + iterator operator--(int) { iterator copy(*this); --(*this); return copy; } + difference_type friend operator-(iterator a, iterator b) { return (&(*a) - &(*b)); } + iterator operator+(size_type n) { return iterator(ptr + n); } + iterator& operator+=(size_type n) { ptr += n; return *this; } + iterator operator-(size_type n) { return iterator(ptr - n); } + iterator& operator-=(size_type n) { ptr -= n; return *this; } + bool operator==(iterator x) const { return ptr == x.ptr; } + bool operator!=(iterator x) const { return ptr != x.ptr; } + bool operator>=(iterator x) const { return ptr >= x.ptr; } + bool operator<=(iterator x) const { return ptr <= x.ptr; } + bool operator>(iterator x) const { return ptr > x.ptr; } + bool operator<(iterator x) const { return ptr < x.ptr; } + }; + + class reverse_iterator { + T* ptr; + public: + typedef Diff difference_type; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef std::bidirectional_iterator_tag iterator_category; + reverse_iterator(T* ptr_) : ptr(ptr_) {} + T& operator*() { return *ptr; } + const T& operator*() const { return *ptr; } + T* operator->() { return ptr; } + const T* operator->() const { return ptr; } + reverse_iterator& operator--() { ptr++; return *this; } + reverse_iterator& operator++() { ptr--; return *this; } + reverse_iterator operator++(int) { reverse_iterator copy(*this); ++(*this); return copy; } + reverse_iterator operator--(int) { reverse_iterator copy(*this); --(*this); return copy; } + bool operator==(reverse_iterator x) const { return ptr == x.ptr; } + bool operator!=(reverse_iterator x) const { return ptr != x.ptr; } + }; + + class const_iterator { + const T* ptr; + public: + typedef Diff difference_type; + typedef const T value_type; + typedef const T* pointer; + typedef const T& reference; + typedef std::random_access_iterator_tag iterator_category; + const_iterator(const T* ptr_) : ptr(ptr_) {} + const_iterator(iterator x) : ptr(&(*x)) {} + const T& operator*() const { return *ptr; } + const T* operator->() const { return ptr; } + const T& operator[](size_type pos) const { return ptr[pos]; } + const_iterator& operator++() { ptr++; return *this; } + const_iterator& operator--() { ptr--; return *this; } + const_iterator operator++(int) { const_iterator copy(*this); ++(*this); return copy; } + const_iterator operator--(int) { const_iterator copy(*this); --(*this); return copy; } + difference_type friend operator-(const_iterator a, const_iterator b) { return (&(*a) - &(*b)); } + const_iterator operator+(size_type n) { return const_iterator(ptr + n); } + const_iterator& operator+=(size_type n) { ptr += n; return *this; } + const_iterator operator-(size_type n) { return const_iterator(ptr - n); } + const_iterator& operator-=(size_type n) { ptr -= n; return *this; } + bool operator==(const_iterator x) const { return ptr == x.ptr; } + bool operator!=(const_iterator x) const { return ptr != x.ptr; } + bool operator>=(const_iterator x) const { return ptr >= x.ptr; } + bool operator<=(const_iterator x) const { return ptr <= x.ptr; } + bool operator>(const_iterator x) const { return ptr > x.ptr; } + bool operator<(const_iterator x) const { return ptr < x.ptr; } + }; + + class const_reverse_iterator { + const T* ptr; + public: + typedef Diff difference_type; + typedef const T value_type; + typedef const T* pointer; + typedef const T& reference; + typedef std::bidirectional_iterator_tag iterator_category; + const_reverse_iterator(T* ptr_) : ptr(ptr_) {} + const_reverse_iterator(reverse_iterator x) : ptr(&(*x)) {} + const T& operator*() const { return *ptr; } + const T* operator->() const { return ptr; } + const_reverse_iterator& operator--() { ptr++; return *this; } + const_reverse_iterator& operator++() { ptr--; return *this; } + const_reverse_iterator operator++(int) { const_reverse_iterator copy(*this); ++(*this); return copy; } + const_reverse_iterator operator--(int) { const_reverse_iterator copy(*this); --(*this); return copy; } + bool operator==(const_reverse_iterator x) const { return ptr == x.ptr; } + bool operator!=(const_reverse_iterator x) const { return ptr != x.ptr; } + }; + +private: + size_type _size; + union direct_or_indirect { + char direct[sizeof(T) * N]; + struct { + size_type capacity; + char* indirect; + }; + } _union; + + T* direct_ptr(difference_type pos) { return reinterpret_cast(_union.direct) + pos; } + const T* direct_ptr(difference_type pos) const { return reinterpret_cast(_union.direct) + pos; } + T* indirect_ptr(difference_type pos) { return reinterpret_cast(_union.indirect) + pos; } + const T* indirect_ptr(difference_type pos) const { return reinterpret_cast(_union.indirect) + pos; } + bool is_direct() const { return _size <= N; } + + void change_capacity(size_type new_capacity) { + if (new_capacity <= N) { + if (!is_direct()) { + T* indirect = indirect_ptr(0); + T* src = indirect; + T* dst = direct_ptr(0); + memcpy(dst, src, size() * sizeof(T)); + free(indirect); + _size -= N + 1; + } + } else { + if (!is_direct()) { + _union.indirect = static_cast(realloc(_union.indirect, ((size_t)sizeof(T)) * new_capacity)); + _union.capacity = new_capacity; + } else { + char* new_indirect = static_cast(malloc(((size_t)sizeof(T)) * new_capacity)); + T* src = direct_ptr(0); + T* dst = reinterpret_cast(new_indirect); + memcpy(dst, src, size() * sizeof(T)); + _union.indirect = new_indirect; + _union.capacity = new_capacity; + _size += N + 1; + } + } + } + + T* item_ptr(difference_type pos) { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); } + const T* item_ptr(difference_type pos) const { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); } + +public: + void assign(size_type n, const T& val) { + clear(); + if (capacity() < n) { + change_capacity(n); + } + while (size() < n) { + _size++; + new(static_cast(item_ptr(size() - 1))) T(val); + } + } + + template + void assign(InputIterator first, InputIterator last) { + size_type n = last - first; + clear(); + if (capacity() < n) { + change_capacity(n); + } + while (first != last) { + _size++; + new(static_cast(item_ptr(size() - 1))) T(*first); + ++first; + } + } + + prevector() : _size(0) {} + + explicit prevector(size_type n) : _size(0) { + resize(n); + } + + explicit prevector(size_type n, const T& val = T()) : _size(0) { + change_capacity(n); + while (size() < n) { + _size++; + new(static_cast(item_ptr(size() - 1))) T(val); + } + } + + template + prevector(InputIterator first, InputIterator last) : _size(0) { + size_type n = last - first; + change_capacity(n); + while (first != last) { + _size++; + new(static_cast(item_ptr(size() - 1))) T(*first); + ++first; + } + } + + prevector(const prevector& other) : _size(0) { + change_capacity(other.size()); + const_iterator it = other.begin(); + while (it != other.end()) { + _size++; + new(static_cast(item_ptr(size() - 1))) T(*it); + ++it; + } + } + + prevector& operator=(const prevector& other) { + if (&other == this) { + return *this; + } + resize(0); + change_capacity(other.size()); + const_iterator it = other.begin(); + while (it != other.end()) { + _size++; + new(static_cast(item_ptr(size() - 1))) T(*it); + ++it; + } + return *this; + } + + size_type size() const { + return is_direct() ? _size : _size - N - 1; + } + + bool empty() const { + return size() == 0; + } + + iterator begin() { return iterator(item_ptr(0)); } + const_iterator begin() const { return const_iterator(item_ptr(0)); } + iterator end() { return iterator(item_ptr(size())); } + const_iterator end() const { return const_iterator(item_ptr(size())); } + + reverse_iterator rbegin() { return reverse_iterator(item_ptr(size() - 1)); } + const_reverse_iterator rbegin() const { return const_reverse_iterator(item_ptr(size() - 1)); } + reverse_iterator rend() { return reverse_iterator(item_ptr(-1)); } + const_reverse_iterator rend() const { return const_reverse_iterator(item_ptr(-1)); } + + size_t capacity() const { + if (is_direct()) { + return N; + } else { + return _union.capacity; + } + } + + T& operator[](size_type pos) { + return *item_ptr(pos); + } + + const T& operator[](size_type pos) const { + return *item_ptr(pos); + } + + void resize(size_type new_size) { + while (size() > new_size) { + item_ptr(size() - 1)->~T(); + _size--; + } + if (new_size > capacity()) { + change_capacity(new_size); + } + while (size() < new_size) { + _size++; + new(static_cast(item_ptr(size() - 1))) T(); + } + } + + void reserve(size_type new_capacity) { + if (new_capacity > capacity()) { + change_capacity(new_capacity); + } + } + + void shrink_to_fit() { + change_capacity(size()); + } + + void clear() { + resize(0); + } + + iterator insert(iterator pos, const T& value) { + size_type p = pos - begin(); + size_type new_size = size() + 1; + if (capacity() < new_size) { + change_capacity(new_size + (new_size >> 1)); + } + memmove(item_ptr(p + 1), item_ptr(p), (size() - p) * sizeof(T)); + _size++; + new(static_cast(item_ptr(p))) T(value); + return iterator(item_ptr(p)); + } + + void insert(iterator pos, size_type count, const T& value) { + size_type p = pos - begin(); + size_type new_size = size() + count; + if (capacity() < new_size) { + change_capacity(new_size + (new_size >> 1)); + } + memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T)); + _size += count; + for (size_type i = 0; i < count; i++) { + new(static_cast(item_ptr(p + i))) T(value); + } + } + + template + void insert(iterator pos, InputIterator first, InputIterator last) { + size_type p = pos - begin(); + difference_type count = last - first; + size_type new_size = size() + count; + if (capacity() < new_size) { + change_capacity(new_size + (new_size >> 1)); + } + memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T)); + _size += count; + while (first != last) { + new(static_cast(item_ptr(p))) T(*first); + ++p; + ++first; + } + } + + iterator erase(iterator pos) { + (*pos).~T(); + memmove(&(*pos), &(*pos) + 1, ((char*)&(*end())) - ((char*)(1 + &(*pos)))); + _size--; + return pos; + } + + iterator erase(iterator first, iterator last) { + iterator p = first; + char* endp = (char*)&(*end()); + while (p != last) { + (*p).~T(); + _size--; + ++p; + } + memmove(&(*first), &(*last), endp - ((char*)(&(*last)))); + return first; + } + + void push_back(const T& value) { + size_type new_size = size() + 1; + if (capacity() < new_size) { + change_capacity(new_size + (new_size >> 1)); + } + new(item_ptr(size())) T(value); + _size++; + } + + void pop_back() { + _size--; + } + + T& front() { + return *item_ptr(0); + } + + const T& front() const { + return *item_ptr(0); + } + + T& back() { + return *item_ptr(size() - 1); + } + + const T& back() const { + return *item_ptr(size() - 1); + } + + void swap(prevector& other) { + if (_size & other._size & 1) { + std::swap(_union.capacity, other._union.capacity); + std::swap(_union.indirect, other._union.indirect); + } else { + std::swap(_union, other._union); + } + std::swap(_size, other._size); + } + + ~prevector() { + clear(); + if (!is_direct()) { + free(_union.indirect); + _union.indirect = NULL; + } + } + + bool operator==(const prevector& other) const { + if (other.size() != size()) { + return false; + } + const_iterator b1 = begin(); + const_iterator b2 = other.begin(); + const_iterator e1 = end(); + while (b1 != e1) { + if ((*b1) != (*b2)) { + return false; + } + ++b1; + ++b2; + } + return true; + } + + bool operator!=(const prevector& other) const { + return !(*this == other); + } + + bool operator<(const prevector& other) const { + if (size() < other.size()) { + return true; + } + if (size() > other.size()) { + return false; + } + const_iterator b1 = begin(); + const_iterator b2 = other.begin(); + const_iterator e1 = end(); + while (b1 != e1) { + if ((*b1) < (*b2)) { + return true; + } + if ((*b2) < (*b1)) { + return false; + } + ++b1; + ++b2; + } + return false; + } + + size_t allocated_memory() const { + if (is_direct()) { + return 0; + } else { + return ((size_t)(sizeof(T))) * _union.capacity; + } + } +}; +#pragma pack(pop) + +#endif diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 7a58074d2..59e949d71 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,69 +15,6 @@ uint256 CBlockHeader::GetHash() const return SerializeHash(*this); } -uint256 CBlock::ComputeMerkleRoot(bool* fMutated) const -{ - /* WARNING! If you're reading this because you're learning about crypto - and/or designing a new system that will use merkle trees, keep in mind - that the following merkle tree algorithm has a serious flaw related to - duplicate txids, resulting in a vulnerability (CVE-2012-2459). - - The reason is that if the number of hashes in the list at a given time - is odd, the last one is duplicated before computing the next level (which - is unusual in Merkle trees). This results in certain sequences of - transactions leading to the same merkle root. For example, these two - trees: - - A A - / \ / \ - B C B C - / \ | / \ / \ - D E F D E F F - / \ / \ / \ / \ / \ / \ / \ - 1 2 3 4 5 6 1 2 3 4 5 6 5 6 - - for transaction lists [1,2,3,4,5,6] and [1,2,3,4,5,6,5,6] (where 5 and - 6 are repeated) result in the same root hash A (because the hash of both - of (F) and (F,F) is C). - - The vulnerability results from being able to send a block with such a - transaction list, with the same merkle root, and the same block hash as - the original without duplication, resulting in failed validation. If the - receiving node proceeds to mark that block as permanently invalid - however, it will fail to accept further unmodified (and thus potentially - valid) versions of the same block. We defend against this by detecting - the case where we would hash two identical hashes at the end of the list - together, and treating that identically to the block having an invalid - merkle root. Assuming no double-SHA256 collisions, this will detect all - known ways of changing the transactions without affecting the merkle - root. - */ - std::vector vMerkleTree; - vMerkleTree.reserve(vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes. - for (std::vector::const_iterator it(vtx.begin()); it != vtx.end(); ++it) - vMerkleTree.push_back(it->GetHash()); - int j = 0; - bool mutated = false; - for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) - { - for (int i = 0; i < nSize; i += 2) - { - int i2 = std::min(i+1, nSize-1); - if (i2 == i + 1 && i2 + 1 == nSize && vMerkleTree[j+i] == vMerkleTree[j+i2]) { - // Two identical hashes at the end of the list at a particular level. - mutated = true; - } - vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), - BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); - } - j += nSize; - } - if (fMutated) { - *fMutated = mutated; - } - return (vMerkleTree.empty() ? uint256() : vMerkleTree.back()); -} - std::string CBlock::ToString() const { std::stringstream s; diff --git a/src/primitives/block.h b/src/primitives/block.h index 54731ff55..0e93399c0 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -118,12 +118,6 @@ public: return block; } - // Build the merkle tree for this block and return the merkle root. - // If non-NULL, *mutated is set to whether mutation was detected in the merkle - // tree (a duplication of transactions in the block leading to an identical - // merkle root). - uint256 ComputeMerkleRoot(bool* mutated = NULL) const; - std::string ToString() const; }; diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 46d3cbbe2..aea96d8a1 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 98882d315..8bd6d00e2 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -74,7 +74,7 @@ public: template inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(prevout); - READWRITE(scriptSig); + READWRITE(*(CScriptBase*)(&scriptSig)); READWRITE(nSequence); } @@ -119,7 +119,7 @@ public: template inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(nValue); - READWRITE(scriptPubKey); + READWRITE(*(CScriptBase*)(&scriptPubKey)); } void SetNull() diff --git a/src/protocol.cpp b/src/protocol.cpp index dd855aa33..c1c7c0b96 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,14 +12,68 @@ # include #endif +namespace NetMsgType { +const char *VERSION="version"; +const char *VERACK="verack"; +const char *ADDR="addr"; +const char *INV="inv"; +const char *GETDATA="getdata"; +const char *MERKLEBLOCK="merkleblock"; +const char *GETBLOCKS="getblocks"; +const char *GETHEADERS="getheaders"; +const char *TX="tx"; +const char *HEADERS="headers"; +const char *BLOCK="block"; +const char *GETADDR="getaddr"; +const char *MEMPOOL="mempool"; +const char *PING="ping"; +const char *PONG="pong"; +const char *ALERT="alert"; +const char *NOTFOUND="notfound"; +const char *FILTERLOAD="filterload"; +const char *FILTERADD="filteradd"; +const char *FILTERCLEAR="filterclear"; +const char *REJECT="reject"; +const char *SENDHEADERS="sendheaders"; +}; + static const char* ppszTypeName[] = { - "ERROR", - "tx", - "block", - "filtered block" + "ERROR", // Should never occur + NetMsgType::TX, + NetMsgType::BLOCK, + "filtered block" // Should never occur }; +/** All known message types. Keep this in the same order as the list of + * messages above and in protocol.h. + */ +const static std::string allNetMessageTypes[] = { + NetMsgType::VERSION, + NetMsgType::VERACK, + NetMsgType::ADDR, + NetMsgType::INV, + NetMsgType::GETDATA, + NetMsgType::MERKLEBLOCK, + NetMsgType::GETBLOCKS, + NetMsgType::GETHEADERS, + NetMsgType::TX, + NetMsgType::HEADERS, + NetMsgType::BLOCK, + NetMsgType::GETADDR, + NetMsgType::MEMPOOL, + NetMsgType::PING, + NetMsgType::PONG, + NetMsgType::ALERT, + NetMsgType::NOTFOUND, + NetMsgType::FILTERLOAD, + NetMsgType::FILTERADD, + NetMsgType::FILTERCLEAR, + NetMsgType::REJECT, + NetMsgType::SENDHEADERS +}; +const static std::vector allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes)); + CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn) { memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE); @@ -140,3 +194,8 @@ std::string CInv::ToString() const { return strprintf("%s %s", GetCommand(), hash.ToString()); } + +const std::vector &getAllNetMessageTypes() +{ + return allNetMessageTypesVec; +} diff --git a/src/protocol.h b/src/protocol.h index 50aeaf44b..c8b8d20ea 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -65,6 +65,165 @@ public: unsigned int nChecksum; }; +/** + * Bitcoin protocol message types. When adding new message types, don't forget + * to update allNetMessageTypes in protocol.cpp. + */ +namespace NetMsgType { + +/** + * The version message provides information about the transmitting node to the + * receiving node at the beginning of a connection. + * @see https://bitcoin.org/en/developer-reference#version + */ +extern const char *VERSION; +/** + * The verack message acknowledges a previously-received version message, + * informing the connecting node that it can begin to send other messages. + * @see https://bitcoin.org/en/developer-reference#verack + */ +extern const char *VERACK; +/** + * The addr (IP address) message relays connection information for peers on the + * network. + * @see https://bitcoin.org/en/developer-reference#addr + */ +extern const char *ADDR; +/** + * The inv message (inventory message) transmits one or more inventories of + * objects known to the transmitting peer. + * @see https://bitcoin.org/en/developer-reference#inv + */ +extern const char *INV; +/** + * The getdata message requests one or more data objects from another node. + * @see https://bitcoin.org/en/developer-reference#getdata + */ +extern const char *GETDATA; +/** + * The merkleblock message is a reply to a getdata message which requested a + * block using the inventory type MSG_MERKLEBLOCK. + * @since protocol version 70001 as described by BIP37. + * @see https://bitcoin.org/en/developer-reference#merkleblock + */ +extern const char *MERKLEBLOCK; +/** + * The getblocks message requests an inv message that provides block header + * hashes starting from a particular point in the block chain. + * @see https://bitcoin.org/en/developer-reference#getblocks + */ +extern const char *GETBLOCKS; +/** + * The getheaders message requests a headers message that provides block + * headers starting from a particular point in the block chain. + * @since protocol version 31800. + * @see https://bitcoin.org/en/developer-reference#getheaders + */ +extern const char *GETHEADERS; +/** + * The tx message transmits a single transaction. + * @see https://bitcoin.org/en/developer-reference#tx + */ +extern const char *TX; +/** + * The headers message sends one or more block headers to a node which + * previously requested certain headers with a getheaders message. + * @since protocol version 31800. + * @see https://bitcoin.org/en/developer-reference#headers + */ +extern const char *HEADERS; +/** + * The block message transmits a single serialized block. + * @see https://bitcoin.org/en/developer-reference#block + */ +extern const char *BLOCK; +/** + * The getaddr message requests an addr message from the receiving node, + * preferably one with lots of IP addresses of other receiving nodes. + * @see https://bitcoin.org/en/developer-reference#getaddr + */ +extern const char *GETADDR; +/** + * The mempool message requests the TXIDs of transactions that the receiving + * node has verified as valid but which have not yet appeared in a block. + * @since protocol version 60002. + * @see https://bitcoin.org/en/developer-reference#mempool + */ +extern const char *MEMPOOL; +/** + * The ping message is sent periodically to help confirm that the receiving + * peer is still connected. + * @see https://bitcoin.org/en/developer-reference#ping + */ +extern const char *PING; +/** + * The pong message replies to a ping message, proving to the pinging node that + * the ponging node is still alive. + * @since protocol version 60001 as described by BIP31. + * @see https://bitcoin.org/en/developer-reference#pong + */ +extern const char *PONG; +/** + * The alert message warns nodes of problems that may affect them or the rest + * of the network. + * @since protocol version 311. + * @see https://bitcoin.org/en/developer-reference#alert + */ +extern const char *ALERT; +/** + * The notfound message is a reply to a getdata message which requested an + * object the receiving node does not have available for relay. + * @ince protocol version 70001. + * @see https://bitcoin.org/en/developer-reference#notfound + */ +extern const char *NOTFOUND; +/** + * The filterload message tells the receiving peer to filter all relayed + * transactions and requested merkle blocks through the provided filter. + * @since protocol version 70001 as described by BIP37. + * Only available with service bit NODE_BLOOM since protocol version + * 70011 as described by BIP111. + * @see https://bitcoin.org/en/developer-reference#filterload + */ +extern const char *FILTERLOAD; +/** + * The filteradd message tells the receiving peer to add a single element to a + * previously-set bloom filter, such as a new public key. + * @since protocol version 70001 as described by BIP37. + * Only available with service bit NODE_BLOOM since protocol version + * 70011 as described by BIP111. + * @see https://bitcoin.org/en/developer-reference#filteradd + */ +extern const char *FILTERADD; +/** + * The filterclear message tells the receiving peer to remove a previously-set + * bloom filter. + * @since protocol version 70001 as described by BIP37. + * Only available with service bit NODE_BLOOM since protocol version + * 70011 as described by BIP111. + * @see https://bitcoin.org/en/developer-reference#filterclear + */ +extern const char *FILTERCLEAR; +/** + * The reject message informs the receiving node that one of its previous + * messages has been rejected. + * @since protocol version 70002 as described by BIP61. + * @see https://bitcoin.org/en/developer-reference#reject + */ +extern const char *REJECT; +/** + * Indicates that a node prefers to receive new block announcements via a + * "headers" message rather than an "inv". + * @since protocol version 70012 as described by BIP130. + * @see https://bitcoin.org/en/developer-reference#sendheaders + */ +extern const char *SENDHEADERS; + +}; + +/* Get a vector of all valid message types (see above) */ +const std::vector &getAllNetMessageTypes(); + /** nServices flags */ enum { // NODE_NETWORK means that the node is capable of serving the block chain. It is currently diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 6ebb152c7..db06a8928 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/pubkey.h b/src/pubkey.h index a1d437e70..e1a17b658 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 8bd158644..135f15ffa 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index 92e6cab9a..c22566d47 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index a488d298c..71ed3618e 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 2b7475c4e..d04b95eba 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index e8e5825d1..415bffb99 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index d4d832825..727b5a1ad 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp index 33792af5b..d95106b5a 100644 --- a/src/qt/bantablemodel.cpp +++ b/src/qt/bantablemodel.cpp @@ -103,7 +103,7 @@ int BanTableModel::rowCount(const QModelIndex &parent) const int BanTableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return columns.length();; + return columns.length(); } QVariant BanTableModel::data(const QModelIndex &index, int role) const @@ -178,4 +178,4 @@ bool BanTableModel::shouldShow() if (priv->size() > 0) return true; return false; -} \ No newline at end of file +} diff --git a/src/qt/bantablemodel.h b/src/qt/bantablemodel.h index c21dd04e3..fe9600ac0 100644 --- a/src/qt/bantablemodel.h +++ b/src/qt/bantablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index e108c84e3..9c21bb24c 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -26,7 +26,7 @@ #endif #include "init.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "scheduler.h" #include "ui_interface.h" #include "util.h" @@ -201,6 +201,8 @@ public: /// Create payment server void createPaymentServer(); #endif + /// parameter interaction/setup based on rules + void parameterSetup(); /// Create options model void createOptionsModel(bool resetSettings); /// Create main window @@ -309,14 +311,8 @@ BitcoinApplication::BitcoinApplication(int &argc, char **argv): // UI per-platform customization // This must be done inside the BitcoinApplication constructor, or after it, because // PlatformStyle::instantiate requires a QApplication -#if defined(Q_OS_MAC) - std::string platformName = "macosx"; -#elif defined(Q_OS_WIN) - std::string platformName = "windows"; -#else - std::string platformName = "other"; -#endif - platformName = GetArg("-uiplatform", platformName); + std::string platformName; + platformName = GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM); platformStyle = PlatformStyle::instantiate(QString::fromStdString(platformName)); if (!platformStyle) // Fall back to "other" if specified name not found platformStyle = PlatformStyle::instantiate("other"); @@ -397,6 +393,12 @@ void BitcoinApplication::startThread() coreThread->start(); } +void BitcoinApplication::parameterSetup() +{ + InitLogging(); + InitParameterInteraction(); +} + void BitcoinApplication::requestInitialize() { qDebug() << __func__ << ": Requesting initialize"; @@ -644,13 +646,15 @@ int main(int argc, char *argv[]) // Install qDebug() message handler to route to debug.log qInstallMessageHandler(DebugMessageHandler); #endif + // Allow parameter interaction before we create the options model + app.parameterSetup(); // Load GUI settings from QSettings app.createOptionsModel(mapArgs.count("-resetguisettings") != 0); // Subscribe to global signals from core uiInterface.InitMessage.connect(InitMessage); - if (GetBoolArg("-splash", true) && !GetBoolArg("-min", false)) + if (GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !GetBoolArg("-min", false)) app.createSplashScreen(networkStyle.data()); try diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index c899e9550..dcd3b4ae2 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -46,6 +46,9 @@ res/icons/about_qt.png res/icons/verify.png res/icons/warning.png + res/icons/fontbigger.png + res/icons/fontsmaller.png + res/icons/chevron.png res/movies/spinner-000.png diff --git a/src/qt/bitcoin_locale.qrc b/src/qt/bitcoin_locale.qrc index b70a10739..a8a0253b0 100644 --- a/src/qt/bitcoin_locale.qrc +++ b/src/qt/bitcoin_locale.qrc @@ -1,36 +1,40 @@ - locale/bitcoin_ach.qm locale/bitcoin_af_ZA.qm locale/bitcoin_ar.qm locale/bitcoin_be_BY.qm + locale/bitcoin_bg_BG.qm locale/bitcoin_bg.qm locale/bitcoin_bs.qm locale/bitcoin_ca_ES.qm locale/bitcoin_ca.qm locale/bitcoin_ca@valencia.qm - locale/bitcoin_cmn.qm + locale/bitcoin_cs_CZ.qm locale/bitcoin_cs.qm locale/bitcoin_cy.qm locale/bitcoin_da.qm locale/bitcoin_de.qm locale/bitcoin_el_GR.qm + locale/bitcoin_el.qm + locale/bitcoin_en_GB.qm locale/bitcoin_en.qm locale/bitcoin_eo.qm locale/bitcoin_es_CL.qm locale/bitcoin_es_DO.qm + locale/bitcoin_es_ES.qm locale/bitcoin_es_MX.qm locale/bitcoin_es.qm locale/bitcoin_es_UY.qm + locale/bitcoin_es_VE.qm locale/bitcoin_et.qm locale/bitcoin_eu_ES.qm locale/bitcoin_fa_IR.qm locale/bitcoin_fa.qm locale/bitcoin_fi.qm locale/bitcoin_fr_CA.qm + locale/bitcoin_fr_FR.qm locale/bitcoin_fr.qm locale/bitcoin_gl.qm - locale/bitcoin_gu_IN.qm locale/bitcoin_he.qm locale/bitcoin_hi_IN.qm locale/bitcoin_hr.qm @@ -45,6 +49,7 @@ locale/bitcoin_la.qm locale/bitcoin_lt.qm locale/bitcoin_lv_LV.qm + locale/bitcoin_mk_MK.qm locale/bitcoin_mn.qm locale/bitcoin_ms_MY.qm locale/bitcoin_nb.qm @@ -54,14 +59,15 @@ locale/bitcoin_pt_BR.qm locale/bitcoin_pt_PT.qm locale/bitcoin_ro_RO.qm + locale/bitcoin_ru_RU.qm locale/bitcoin_ru.qm - locale/bitcoin_sah.qm locale/bitcoin_sk.qm locale/bitcoin_sl_SI.qm locale/bitcoin_sq.qm locale/bitcoin_sr.qm locale/bitcoin_sv.qm locale/bitcoin_th_TH.qm + locale/bitcoin_tr_TR.qm locale/bitcoin_tr.qm locale/bitcoin_uk.qm locale/bitcoin_ur_PK.qm @@ -69,7 +75,7 @@ locale/bitcoin_vi.qm locale/bitcoin_vi_VN.qm locale/bitcoin_zh_CN.qm - locale/bitcoin_zh_HK.qm + locale/bitcoin_zh.qm locale/bitcoin_zh_TW.qm diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index d19b9fd4a..73eb35a54 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h index 3703b1f8d..2f03a3d17 100644 --- a/src/qt/bitcoinamountfield.h +++ b/src/qt/bitcoinamountfield.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 811f27f97..b00cdfcaf 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -63,6 +63,16 @@ #include #endif +const std::string BitcoinGUI::DEFAULT_UIPLATFORM = +#if defined(Q_OS_MAC) + "macosx" +#elif defined(Q_OS_WIN) + "windows" +#else + "other" +#endif + ; + const QString BitcoinGUI::DEFAULT_WALLET = "~Default"; BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent) : @@ -447,8 +457,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) setNumConnections(clientModel->getNumConnections()); connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); - setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate()); - connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime))); + setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate(), clientModel->getVerificationProgress(NULL)); + connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(setNumBlocks(int,QDateTime,double))); // Receive and report messages from client model connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int))); @@ -676,7 +686,7 @@ void BitcoinGUI::setNumConnections(int count) labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count)); } -void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate) +void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress) { if(!clientModel) return; @@ -753,7 +763,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate) progressBarLabel->setVisible(true); progressBar->setFormat(tr("%1 behind").arg(timeBehindText)); progressBar->setMaximum(1000000000); - progressBar->setValue(clientModel->getVerificationProgress() * 1000000000.0 + 0.5); + progressBar->setValue(nVerificationProgress * 1000000000.0 + 0.5); progressBar->setVisible(true); tooltip = tr("Catching up...") + QString("
") + tooltip; diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 2b98dabc5..871ca1ba3 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -48,6 +48,7 @@ class BitcoinGUI : public QMainWindow public: static const QString DEFAULT_WALLET; + static const std::string DEFAULT_UIPLATFORM; explicit BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent = 0); ~BitcoinGUI(); @@ -149,7 +150,7 @@ public Q_SLOTS: /** Set number of connections shown in the UI */ void setNumConnections(int count); /** Set number of blocks and last block date shown in the UI */ - void setNumBlocks(int count, const QDateTime& blockDate); + void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress); /** Notify the user of an event from the core network or transaction handling code. @param[in] title the message box / notification title diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 244904653..41f1d5841 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -1,4 +1,6 @@ - +// Copyright (c) 2013-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. #include @@ -67,6 +69,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Fees (in %s/kB) smaller than this are considered zero fee for relaying, " "mining and transaction creation (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Fees (in %s/kB) smaller than this are considered zero fee for transaction " +"creation (default: %s)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "How thorough the block verification of -checkblocks is (0-4, default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "If is not supplied or if = 1, output all debugging " @@ -121,6 +126,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Set the number of threads for coin generation if enabled (-1 = all cores, " "default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Support filtering of blocks and transaction with bloom filters (default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "The block database contains a block which appears to be from the future. " "This may be due to your computer's date and time being set incorrectly. Only " "rebuild the block database if you are sure that your computer's date and " @@ -152,6 +159,10 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: " "%s)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Username and hashed password for JSON-RPC connections. The field " +"comes in the format: :$. A canonical python script is " +"included in share/rpcuser. This option can be specified multiple times"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "WARNING: abnormally high number of blocks generated, %d blocks received in " "the last %d hours (%d expected)"), QT_TRANSLATE_NOOP("bitcoin-core", "" @@ -178,7 +189,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "mode. This will redownload the entire blockchain"), QT_TRANSLATE_NOOP("bitcoin-core", "(default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "(default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "(default: 1)"), QT_TRANSLATE_NOOP("bitcoin-core", "-maxmempool must be at least %d MB"), QT_TRANSLATE_NOOP("bitcoin-core", " can be:"), QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"), @@ -197,7 +207,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -whitebind address: '%s'"), QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"), -QT_TRANSLATE_NOOP("bitcoin-core", "Choose data directory on startup (default: 0)"), QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node(s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Connect through SOCKS5 proxy"), QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"), @@ -274,15 +283,12 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."), QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"), QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"), QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Set SSL root certificates for payment request (default: -system-)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Set language, for example \"de_DE\" (default: system locale)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set maximum block size in bytes (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set minimum block size in bytes (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set the number of threads to service RPC calls (default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "Show all debugging options (usage: --help -help-debug)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Show splash screen on startup (default: 1)"), QT_TRANSLATE_NOOP("bitcoin-core", "Shrink debug.log file on client startup (default: 1 when no -debug)"), QT_TRANSLATE_NOOP("bitcoin-core", "Signing transaction failed"), QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: %s)"), @@ -292,7 +298,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)"), QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"), QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: %u)"), -QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized"), QT_TRANSLATE_NOOP("bitcoin-core", "The transaction amount is too small to pay the fee"), QT_TRANSLATE_NOOP("bitcoin-core", "This help message"), QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."), @@ -303,7 +308,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amount too small"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction amounts must be positive"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large for fee policy"), QT_TRANSLATE_NOOP("bitcoin-core", "Transaction too large"), -QT_TRANSLATE_NOOP("bitcoin-core", "UI Options:"), QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Unable to start HTTP server. See debug log for details."), QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"), diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp index 425b45d91..649005789 100644 --- a/src/qt/bitcoinunits.cpp +++ b/src/qt/bitcoinunits.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -111,13 +111,6 @@ QString BitcoinUnits::format(int unit, const CAmount& nIn, bool fPlus, Separator } -// TODO: Review all remaining calls to BitcoinUnits::formatWithUnit to -// TODO: determine whether the output is used in a plain text context -// TODO: or an HTML context (and replace with -// TODO: BtcoinUnits::formatHtmlWithUnit in the latter case). Hopefully -// TODO: there aren't instances where the result could be used in -// TODO: either context. - // NOTE: Using formatWithUnit in an HTML context risks wrapping // quantities at the thousands separator. More subtly, it also results // in a standard space rather than a thin space, due to a bug in Qt's diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h index 1871c33a7..fda067b0b 100644 --- a/src/qt/bitcoinunits.h +++ b/src/qt/bitcoinunits.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -88,6 +88,7 @@ public: static QString format(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); //! Format as string (with unit) static QString formatWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); + //! Format as HTML string (with unit) static QString formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); //! Parse string to coin amount static bool parse(int unit, const QString &value, CAmount *val_out); diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 566e8fa62..fb502b3c8 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -22,17 +22,16 @@ #include #include +class CBlockIndex; + static const int64_t nClientStartupTime = GetTime(); +static int64_t nLastBlockTipUpdateNotification = 0; ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : QObject(parent), optionsModel(optionsModel), peerTableModel(0), banTableModel(0), - cachedNumBlocks(0), - cachedBlockDate(QDateTime()), - cachedReindexing(0), - cachedImporting(0), pollTimer(0) { peerTableModel = new PeerTableModel(this); @@ -99,40 +98,21 @@ size_t ClientModel::getMempoolDynamicUsage() const return mempool.DynamicMemoryUsage(); } -double ClientModel::getVerificationProgress() const +double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const { - LOCK(cs_main); - return Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip()); + CBlockIndex *tip = const_cast(tipIn); + if (!tip) + { + LOCK(cs_main); + tip = chainActive.Tip(); + } + return Checkpoints::GuessVerificationProgress(Params().Checkpoints(), tip); } void ClientModel::updateTimer() { - // Get required lock upfront. This avoids the GUI from getting stuck on - // 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) - 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 || - cachedBlockDate != newBlockDate || - cachedReindexing != fReindex || - cachedImporting != fImporting) - { - cachedNumBlocks = newNumBlocks; - cachedBlockDate = newBlockDate; - cachedReindexing = fReindex; - cachedImporting = fImporting; - - Q_EMIT numBlocksChanged(newNumBlocks, newBlockDate); - } - + // no locking required at this point + // the following calls will acquire the required lock Q_EMIT mempoolSizeChanged(getMempoolSize(), getMempoolDynamicUsage()); Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent()); } @@ -178,7 +158,7 @@ enum BlockSource ClientModel::getBlockSource() const QString ClientModel::getStatusBarWarnings() const { - return QString::fromStdString(GetWarnings("statusbar")); + return QString::fromStdString(GetWarnings("gui")); } OptionsModel *ClientModel::getOptionsModel() @@ -261,6 +241,26 @@ static void BannedListChanged(ClientModel *clientmodel) QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection); } +static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex) +{ + // lock free async UI updates in case we have a new block tip + // during initial sync, only update the UI if the last update + // was > 250ms (MODEL_UPDATE_DELAY) ago + int64_t now = 0; + if (initialSync) + now = GetTimeMillis(); + + // if we are in-sync, update the UI regardless of last update time + if (!initialSync || now - nLastBlockTipUpdateNotification > MODEL_UPDATE_DELAY) { + //pass a async signal to the UI thread + QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection, + Q_ARG(int, pIndex->nHeight), + Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())), + Q_ARG(double, clientmodel->getVerificationProgress(pIndex))); + nLastBlockTipUpdateNotification = now; + } +} + void ClientModel::subscribeToCoreSignals() { // Connect signals to client @@ -268,6 +268,7 @@ void ClientModel::subscribeToCoreSignals() uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1)); uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2)); uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this)); + uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2)); } void ClientModel::unsubscribeFromCoreSignals() @@ -277,4 +278,5 @@ void ClientModel::unsubscribeFromCoreSignals() uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1)); uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2)); uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this)); + uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2)); } diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 493a75933..62c9f71ac 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,6 +15,7 @@ class PeerTableModel; class TransactionTableModel; class CWallet; +class CBlockIndex; QT_BEGIN_NAMESPACE class QTimer; @@ -59,7 +60,7 @@ public: quint64 getTotalBytesRecv() const; quint64 getTotalBytesSent() const; - double getVerificationProgress() const; + double getVerificationProgress(const CBlockIndex *tip) const; QDateTime getLastBlockDate() const; //! Return true if core is doing initial block download @@ -81,11 +82,6 @@ private: PeerTableModel *peerTableModel; BanTableModel *banTableModel; - int cachedNumBlocks; - QDateTime cachedBlockDate; - bool cachedReindexing; - bool cachedImporting; - QTimer *pollTimer; void subscribeToCoreSignals(); @@ -93,7 +89,7 @@ private: Q_SIGNALS: void numConnectionsChanged(int count); - void numBlocksChanged(int count, const QDateTime& blockDate); + void numBlocksChanged(int count, const QDateTime& blockDate, double nVerificationProgress); void mempoolSizeChanged(long count, size_t mempoolSizeInBytes); void alertsChanged(const QString &warnings); void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 81b2597c3..7393c83c7 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -130,7 +130,7 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget ui->treeWidget->setColumnWidth(COLUMN_DATE, 110); ui->treeWidget->setColumnWidth(COLUMN_CONFIRMATIONS, 100); ui->treeWidget->setColumnWidth(COLUMN_PRIORITY, 100); - ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transacton hash in this column, but don't show it + ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transaction hash in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_VOUT_INDEX, true); // store vout index in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_AMOUNT_INT64, true); // store amount int64 in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_PRIORITY_INT64, true); // store priority int64 in this column, but don't show it @@ -408,10 +408,8 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) CoinControlDialog::updateLabels(model, this); } - // todo: this is a temporary qt5 fix: when clicking a parent node in tree mode, the parent node - // including all children are partially selected. But the parent node should be fully selected - // as well as the children. Children should never be partially selected in the first place. - // Please remove this ugly fix, once the bug is solved upstream. + // TODO: Remove this temporary qt5 fix after Qt5.3 and Qt5.4 are no longer used. + // Fixed in Qt5.5 and above: https://bugreports.qt.io/browse/QTBUG-43473 #if QT_VERSION >= 0x050000 else if (column == COLUMN_CHECKBOX && item->childCount() > 0) { @@ -538,7 +536,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) nBytes = nBytesInputs + ((CoinControlDialog::payAmounts.size() > 0 ? CoinControlDialog::payAmounts.size() + 1 : 2) * 34) + 10; // always assume +1 output for change here // Priority - double mempoolEstimatePriority = mempool.estimatePriority(nTxConfirmTarget); + double mempoolEstimatePriority = mempool.estimateSmartPriority(nTxConfirmTarget); 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); @@ -549,11 +547,12 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // Fee nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool); + if (nPayFee > 0 && coinControl->nMinimumTotalFee > nPayFee) + nPayFee = coinControl->nMinimumTotalFee; - // Allow free? - double dPriorityNeeded = mempoolEstimatePriority; - if (dPriorityNeeded <= 0) - dPriorityNeeded = AllowFreeThreshold(); // not enough data, back to hard-coded + + // Allow free? (require at least hard-coded threshold and default to that if no estimate) + double dPriorityNeeded = std::max(mempoolEstimatePriority, AllowFreeThreshold()); fAllowFree = (dPriority >= dPriorityNeeded); if (fSendFreeTransactions) @@ -621,7 +620,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) l6->setText(sPriorityLabel); // Priority l7->setText(fDust ? tr("yes") : tr("no")); // Dust l8->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nChange)); // Change - if (nPayFee > 0 && !(payTxFee.GetFeePerK() > 0 && fPayAtLeastCustomFee && nBytes < 1000)) + if (nPayFee > 0 && (coinControl->nMinimumTotalFee < nPayFee)) { l3->setText(ASYMP_UTF8 + l3->text()); l4->setText(ASYMP_UTF8 + l4->text()); @@ -636,21 +635,22 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // tool tips QString toolTip1 = tr("This label turns red if the transaction size is greater than 1000 bytes.") + "

"; - toolTip1 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CWallet::GetRequiredFee(1000))) + "

"; + toolTip1 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, CWallet::GetRequiredFee(1000))) + "

"; toolTip1 += tr("Can vary +/- 1 byte per input."); QString toolTip2 = tr("Transactions with higher priority are more likely to get included into a block.") + "

"; toolTip2 += tr("This label turns red if the priority is smaller than \"medium\".") + "

"; - toolTip2 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CWallet::GetRequiredFee(1000))); + toolTip2 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, CWallet::GetRequiredFee(1000))); - QString toolTip3 = tr("This label turns red if any recipient receives an amount smaller than %1.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, ::minRelayTxFee.GetFee(546))); + QString toolTip3 = tr("This label turns red if any recipient receives an amount smaller than the current dust threshold."); // how many satoshis the estimated fee can vary per byte we guess wrong double dFeeVary; if (payTxFee.GetFeePerK() > 0) dFeeVary = (double)std::max(CWallet::GetRequiredFee(1000), payTxFee.GetFeePerK()) / 1000; - else - dFeeVary = (double)std::max(CWallet::GetRequiredFee(1000), mempool.estimateFee(nTxConfirmTarget).GetFeePerK()) / 1000; + else { + dFeeVary = (double)std::max(CWallet::GetRequiredFee(1000), mempool.estimateSmartFee(nTxConfirmTarget).GetFeePerK()) / 1000; + } QString toolTip4 = tr("Can vary +/- %1 satoshi(s) per input.").arg(dFeeVary); l3->setToolTip(toolTip4); @@ -686,7 +686,7 @@ void CoinControlDialog::updateView() QFlags flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate; int nDisplayUnit = model->getOptionsModel()->getDisplayUnit(); - double mempoolEstimatePriority = mempool.estimatePriority(nTxConfirmTarget); + double mempoolEstimatePriority = mempool.estimateSmartPriority(nTxConfirmTarget); std::map > mapCoins; model->listCoins(mapCoins); diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 8ff1eac70..1a467eb2f 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/coincontroltreewidget.cpp b/src/qt/coincontroltreewidget.cpp index 5dcbf0c3f..f86bc0851 100644 --- a/src/qt/coincontroltreewidget.cpp +++ b/src/qt/coincontroltreewidget.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/coincontroltreewidget.h b/src/qt/coincontroltreewidget.h index 98a7d32f0..62645fcdb 100644 --- a/src/qt/coincontroltreewidget.h +++ b/src/qt/coincontroltreewidget.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp index 55c595708..8a1a49bb0 100644 --- a/src/qt/csvmodelwriter.cpp +++ b/src/qt/csvmodelwriter.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/csvmodelwriter.h b/src/qt/csvmodelwriter.h index a2bf379f4..edea369ad 100644 --- a/src/qt/csvmodelwriter.h +++ b/src/qt/csvmodelwriter.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp index 1c22594cd..5f45031e9 100644 --- a/src/qt/editaddressdialog.cpp +++ b/src/qt/editaddressdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h index d59fce2d4..ddb67ece7 100644 --- a/src/qt/editaddressdialog.h +++ b/src/qt/editaddressdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index 7a3d29417..febbaeda1 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -450,6 +450,125 @@ 3 + + 5 + + + + + 4 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 24 + 24 + + + + + + + Decrease font size + + + + :/icons/fontsmaller:/icons/fontsmaller + + + + 24 + 16 + + + + false + + + true + + + + + + + + 24 + 24 + + + + Increase font size + + + + + + + :/icons/fontbigger:/icons/fontbigger + + + + 24 + 16 + + + + false + + + true + + + + + + + + 24 + 24 + + + + Clear console + + + Qt::LeftToRight + + + + + + + :/icons/remove:/icons/remove + + + Ctrl+L + + + false + + + true + + + + + @@ -470,44 +589,48 @@ - + 3 - - - > + + + false - - - - - - - - 24 + 16 24 - - Clear console - - :/icons/remove:/icons/remove + :/icons/prompticon + :/icons/prompticon:/icons/prompticon - - Ctrl+L + + + 14 + 14 + false + + true + + + + + + + + @@ -782,6 +905,9 @@ Qt::ScrollBarAsNeeded + + false + true @@ -843,6 +969,9 @@ Qt::ScrollBarAsNeeded + + false + true diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 7d3e48ff3..5ceffcd70 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -14,6 +14,8 @@ static const int MAX_PASSPHRASE_SIZE = 1024; /* BitcoinGUI -- Size of icons in status bar */ static const int STATUSBAR_ICONSIZE = 16; +static const bool DEFAULT_SPLASHSCREEN = true; + /* Invalid field background style */ #define STYLE_INVALID "background:#FF8080" diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 6dce9370d..ff4320b36 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -62,6 +62,10 @@ #include #endif +#if QT_VERSION >= 0x50200 +#include +#endif + #if BOOST_FILESYSTEM_VERSION >= 3 static boost::filesystem::detail::utf8_codecvt_facet utf8; #endif @@ -90,6 +94,9 @@ QString dateTimeStr(qint64 nTime) QFont fixedPitchFont() { +#if QT_VERSION >= 0x50200 + return QFontDatabase::systemFont(QFontDatabase::FixedFont); +#else QFont font("Monospace"); #if QT_VERSION >= 0x040800 font.setStyleHint(QFont::Monospace); @@ -97,6 +104,7 @@ QFont fixedPitchFont() font.setStyleHint(QFont::TypeWriter); #endif return font; +#endif } void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) @@ -217,7 +225,7 @@ QString formatBitcoinURI(const SendCoinsRecipient &info) if (!info.message.isEmpty()) { - QString msg(QUrl::toPercentEncoding(info.message));; + QString msg(QUrl::toPercentEncoding(info.message)); ret += QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg); paramCount++; } @@ -898,6 +906,9 @@ QString formatServicesStr(quint64 mask) case NODE_GETUTXO: strList.append("GETUTXO"); break; + case NODE_BLOOM: + strList.append("BLOOM"); + break; default: strList.append(QString("%1[%2]").arg("UNKNOWN").arg(check)); } diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index ec678c4af..9267e0a6c 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 8d1dc349d..6d6af5429 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -19,9 +19,15 @@ #include #include -/* Minimum free space (in bytes) needed for data directory */ +#include + static const uint64_t GB_BYTES = 1000000000LL; -static const uint64_t BLOCK_CHAIN_SIZE = 20LL * GB_BYTES; +/* Minimum free space (in GB) needed for data directory */ +static const uint64_t BLOCK_CHAIN_SIZE = 80; +/* Minimum free space (in GB) needed for data directory when pruned; Does not include prune target */ +static const uint64_t CHAIN_STATE_SIZE = 2; +/* Total required space (in GB) depending on user choice (prune, not prune) */ +static uint64_t requiredSpace; /* Check free space asynchronously to prevent hanging the UI thread. @@ -118,7 +124,11 @@ Intro::Intro(QWidget *parent) : ui->setupUi(this); ui->welcomeLabel->setText(ui->welcomeLabel->text().arg(tr(PACKAGE_NAME))); ui->storageLabel->setText(ui->storageLabel->text().arg(tr(PACKAGE_NAME))); - ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(tr(PACKAGE_NAME)).arg(BLOCK_CHAIN_SIZE/GB_BYTES)); + uint64_t pruneTarget = std::max(0, GetArg("-prune", 0)); + requiredSpace = BLOCK_CHAIN_SIZE; + if (pruneTarget) + requiredSpace = CHAIN_STATE_SIZE + std::ceil(pruneTarget * 1024 * 1024.0 / GB_BYTES); + ui->sizeWarningLabel->setText(ui->sizeWarningLabel->text().arg(tr(PACKAGE_NAME)).arg(requiredSpace)); startThread(); } @@ -168,7 +178,7 @@ void Intro::pickDataDirectory() /* 2) Allow QSettings to override default dir */ dataDir = settings.value("strDataDir", dataDir).toString(); - if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", false)) + if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR)) { /* If current default data directory does not exist, let the user choose one */ Intro intro; @@ -222,9 +232,9 @@ void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable ui->freeSpace->setText(""); } else { QString freeString = tr("%n GB of free space available", "", bytesAvailable/GB_BYTES); - if(bytesAvailable < BLOCK_CHAIN_SIZE) + if(bytesAvailable < requiredSpace * GB_BYTES) { - freeString += " " + tr("(of %n GB needed)", "", BLOCK_CHAIN_SIZE/GB_BYTES); + freeString += " " + tr("(of %n GB needed)", "", requiredSpace); ui->freeSpace->setStyleSheet("QLabel { color: #800000 }"); } else { ui->freeSpace->setStyleSheet(""); diff --git a/src/qt/intro.h b/src/qt/intro.h index 50783f722..9e2e96dc9 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,6 +9,8 @@ #include #include +static const bool DEFAULT_CHOOSE_DATADIR = false; + class FreespaceChecker; namespace Ui { diff --git a/src/qt/locale/bitcoin_ach.ts b/src/qt/locale/bitcoin_ach.ts deleted file mode 100644 index 336554085..000000000 --- a/src/qt/locale/bitcoin_ach.ts +++ /dev/null @@ -1,113 +0,0 @@ - - - AddressBookPage - - - AddressTableModel - - - AskPassphraseDialog - - - BanTableModel - - - BitcoinGUI - - - ClientModel - - - CoinControlDialog - - - EditAddressDialog - - - FreespaceChecker - - - HelpMessageDialog - - - Intro - - - OpenURIDialog - - - OptionsDialog - - - OverviewPage - - - PaymentServer - - - PeerTableModel - - - QObject - - - QRImageWidget - - - RPCConsole - - - ReceiveCoinsDialog - - - ReceiveRequestDialog - - - RecentRequestsTableModel - - - SendCoinsDialog - - - SendCoinsEntry - - - ShutdownWindow - - - SignVerifyMessageDialog - - - SplashScreen - - - TrafficGraphWidget - - - TransactionDesc - - - TransactionDescDialog - - - TransactionTableModel - - - TransactionView - - - UnitDisplayStatusBarControl - - - WalletFrame - - - WalletModel - - - WalletView - - - bitcoin-core - - \ No newline at end of file diff --git a/src/qt/locale/bitcoin_af_ZA.ts b/src/qt/locale/bitcoin_af_ZA.ts index d55d2f58a..d77aa77f8 100644 --- a/src/qt/locale/bitcoin_af_ZA.ts +++ b/src/qt/locale/bitcoin_af_ZA.ts @@ -214,6 +214,14 @@ EditAddressDialog + + &Label + &Etiket + + + &Address + &Adres + New receiving address Nuwe ontvangende adres @@ -261,6 +269,10 @@ Options Opsies + + W&allet + &Beursie + OverviewPage @@ -294,6 +306,14 @@ ReceiveCoinsDialog + + &Amount: + &Bedrag: + + + &Message: + &Boodskap: + Copy amount Kopieer bedrag @@ -347,10 +367,18 @@ Send Coins Stuur Munstukke + + Insufficient funds! + Onvoldoende fondse + Amount: Bedrag: + + Transaction Fee: + Transaksie fooi: + Send to multiple recipients at once Stuur aan vele ontvangers op eens @@ -374,6 +402,10 @@ SendCoinsEntry + + A&mount: + &Bedrag: + Message: Boodskap: @@ -453,6 +485,10 @@ Transaction ID Transaksie ID + + Transaction + Transaksie + Amount Bedrag diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index 8a54f1579..88ce05bbd 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -93,7 +93,11 @@ Exporting Failed فشل التصدير - + + There was an error trying to save the address list to %1. Please try again. + لقد حدث خطأ أثناء حفظ قائمة العناوين إلى %1. يرجى المحاولة مرة أخرى. + + AddressTableModel @@ -333,6 +337,10 @@ Wallet محفظة + + &Send + &ارسل + &Receive &استقبل @@ -377,6 +385,10 @@ &About Bitcoin Core حول bitcoin core + + %1 and %2 + %1 و %2 + Error خطأ @@ -779,6 +791,10 @@ PaymentServer + + Bad response from server %1 + استجابة سيئة من الملقم %1 + PeerTableModel @@ -789,6 +805,14 @@ Amount المبلغ + + %1 h + %1 ساعة + + + %1 m + %1 دقيقة + N/A غير معروف @@ -831,6 +855,10 @@ &Information المعلومات + + Debug window + نافذة المعالجة + General عام @@ -907,6 +935,22 @@ Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. استخدم اسهم الاعلى و الاسفل للتنقل بين السجلات و <b>Ctrl-L</b> لمسح الشاشة + + %1 B + %1 بايت + + + %1 KB + %1 كيلو بايت + + + %1 MB + %1 ميقا بايت + + + %1 GB + %1 قيقا بايت + Yes نعم @@ -1075,6 +1119,10 @@ Change: تعديل : + + Transaction Fee: + رسوم المعاملة: + Send to multiple recipients at once إرسال إلى عدة مستلمين في وقت واحد @@ -1107,6 +1155,10 @@ Confirm send coins تأكيد الإرسال Coins + + %1 to %2 + %1 الى %2 + Copy quantity نسخ الكمية @@ -1143,6 +1195,10 @@ The amount exceeds your balance. القيمة تتجاوز رصيدك + + The total exceeds your balance when the %1 transaction fee is included. + المجموع يتجاوز رصيدك عندما يتم اضافة %1 رسوم العملية + (no label) (لا وصف) @@ -1150,6 +1206,10 @@ SendCoinsEntry + + A&mount: + &القيمة + Pay &To: ادفع &الى : @@ -1178,6 +1238,10 @@ Message: الرسائل + + Pay To: + ادفع &الى : + ShutdownWindow @@ -1297,10 +1361,22 @@ TransactionDesc + + Open until %1 + مفتوح حتى %1 + conflicted يتعارض + + %1/offline + %1 غير متواجد + + + %1/unconfirmed + غير مؤكدة/%1 + %1 confirmations تأكيد %1 @@ -1411,6 +1487,10 @@ Type النوع + + Open until %1 + مفتوح حتى %1 + This block was not received by any other nodes and will probably not be accepted! لم يتم تلقى هذه الكتلة (Block) من قبل أي العقد الأخرى وربما لن تكون مقبولة! @@ -1427,6 +1507,10 @@ Label وصف + + Conflicted + يتعارض + Received with استقبل مع diff --git a/src/qt/locale/bitcoin_be_BY.ts b/src/qt/locale/bitcoin_be_BY.ts index c1efc822e..2709ff37e 100644 --- a/src/qt/locale/bitcoin_be_BY.ts +++ b/src/qt/locale/bitcoin_be_BY.ts @@ -798,7 +798,7 @@ command-line options опцыі каманднага радка - + Intro @@ -843,6 +843,10 @@ MB Мб + + W&allet + Гаманец + OverviewPage @@ -869,9 +873,21 @@ RPCConsole + + &Information + Інфармацыя + + + Debug window + Вакно адладкі + ReceiveCoinsDialog + + &Amount: + &Колькасць: + &Label: Метка: @@ -887,6 +903,10 @@ ReceiveRequestDialog + + Copy &Address + Капіяваць адрас + Address Адрас @@ -933,6 +953,10 @@ Send Coins Даслаць Манеты + + Insufficient funds! + Недастаткова сродкаў + Quantity: Колькасць: @@ -1044,6 +1068,14 @@ Alt+P Alt+P + + Message: + Паведамленне: + + + Pay To: + Заплаціць да: + Memo: Памятка: @@ -1443,10 +1475,6 @@ Signing transaction failed Памылка подпісу транзакцыі - - Start minimized - Стартаваць ммінімізаванай - This is experimental software. Гэта эксперыментальная праграма. diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index 8496a3348..ecd10e546 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -445,6 +445,36 @@ Catching up... Зарежда блокове... + + Date: %1 + + Дата: %1 + + + + Amount: %1 + + Сума: %1 + + + + Type: %1 + + Тип: %1 + + + + Label: %1 + + Етикет: %1 + + + + Address: %1 + + Адрес: %1 + + Sent transaction Изходяща транзакция @@ -776,7 +806,7 @@ command-line options Списък с налични команди - + Intro @@ -833,6 +863,10 @@ MB Мегабайта + + Number of script &verification threads + Брой на скриптове и &нишки за потвърждение + Accept connections from outside Приемай връзки отвън @@ -873,6 +907,10 @@ Expert Експерт + + Enable coin &control features + Позволяване на монетите и &техните възможности + &Spend unconfirmed change &Похарчете непотвърденото ресто @@ -2234,6 +2272,10 @@ Export Transaction History Изнасяне историята на транзакциите + + Watch-only + само гледане + Exporting Failed Грешка при изнасянето @@ -2361,10 +2403,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Сложете в бял списък пиъри,свързващи се от дадената интернет маска или айпи адрес.Може да бъде заложено неколкократно. - - (default: 1) - (по подразбиране 1) - <category> can be: <category> може да бъде: @@ -2409,10 +2447,6 @@ Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) Заложете броя на нишки за генерация на монети ако е включено(-1 = всички ядра, по подразбиране: %d) - - Choose data directory on startup (default: 0) - Изберете директория при стартиране на програмата.( настройка по подразбиране:0) - Connect through SOCKS5 proxy Свързване чрез SOCKS5 прокси @@ -2425,6 +2459,10 @@ Information Информация + + Invalid amount for -maxtxfee=<amount>: '%s' + Невалидна сума за -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Невалидна сума за -minrelaytxfee=<amount>: '%s' @@ -2437,14 +2475,6 @@ Send trace/debug info to console instead of debug.log file Изпрати локализиращата или дебъг информацията към конзолата, вместо файлът debug.log - - Set language, for example "de_DE" (default: system locale) - Задаване на език,например "de_DE" (по подразбиране: system locale) - - - Start minimized - Стартирай минимизирано - This is experimental software. Това е експериментален софтуер. diff --git a/src/qt/locale/bitcoin_cmn.ts b/src/qt/locale/bitcoin_bg_BG.ts similarity index 60% rename from src/qt/locale/bitcoin_cmn.ts rename to src/qt/locale/bitcoin_bg_BG.ts index a6444867c..353f6d771 100644 --- a/src/qt/locale/bitcoin_cmn.ts +++ b/src/qt/locale/bitcoin_bg_BG.ts @@ -1,9 +1,25 @@ - + AddressBookPage + + Right-click to edit address or label + Клик с десен бутон на мишката за промяна на адрес или етикет + Create a new address - 创建新地址 + Създай нов адрес + + + &New + Нов + + + &Copy + Копирай + + + C&lose + Затвори @@ -17,6 +33,14 @@ BitcoinGUI + + Bitcoin Core + Биткойн ядро + + + &About Bitcoin Core + За Биткойн ядрото + ClientModel @@ -32,9 +56,21 @@ HelpMessageDialog + + Bitcoin Core + Биткойн ядро + + + About Bitcoin Core + За Биткойн ядрото + Intro + + Bitcoin Core + Биткойн ядро + OpenURIDialog @@ -83,6 +119,10 @@ SplashScreen + + Bitcoin Core + Биткойн ядро + TrafficGraphWidget diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index dcbe4dc4c..38e770f18 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP / Màscara de xarxa + + + Banned Until + Bandejat fins + + BitcoinGUI @@ -874,6 +882,34 @@ command-line options Opcions de la línia d'ordres + + UI Options: + Opcions d'interfície d'usuari: + + + Choose data directory on startup (default: %u) + Trieu el directori de dades a l'inici (per defecte: %u) + + + Set language, for example "de_DE" (default: system locale) + Defineix la llengua, per exemple «de_DE» (per defecte: la definida pel sistema) + + + Start minimized + Inicia minimitzat + + + Set SSL root certificates for payment request (default: -system-) + Defineix els certificats arrel SSL per a la sol·licitud de pagament (per defecte: els del sistema) + + + Show splash screen on startup (default: %u) + Mostra la pantalla de benvinguda a l'inici (per defecte: %u) + + + Reset all settings changes made over the GUI + Reinicialitza tots els canvis de configuració fets des de la interfície gràfica + Intro @@ -1071,6 +1107,18 @@ Port of the proxy (e.g. 9050) Port del proxy (per exemple 9050) + + Used for reaching peers via: + Utilitzat per arribar als iguals mitjançant: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Mostra si el proxy SOCKS5 per defecte proporcionat s'utilitza per arribar als iguals mitjançant aquest tipus de xarxa. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor: + &Window &Finestra @@ -1457,10 +1505,18 @@ &Peers &Iguals + + Banned peers + Iguals bandejats + Select a peer to view detailed information. Seleccioneu un igual per mostrar informació detallada. + + Whitelisted + A la llista blanca + Direction Direcció @@ -1469,6 +1525,18 @@ Version Versió + + Starting Block + Bloc d'inici + + + Synced Headers + Capçaleres sincronitzades + + + Synced Blocks + Blocs sincronitzats + User Agent Agent d'usuari @@ -1497,6 +1565,14 @@ Ping Time Temps de ping + + The duration of a currently outstanding ping. + La duració d'un ping més destacat actualment. + + + Ping Wait + Espera de ping + Time Offset Diferència horària @@ -1545,6 +1621,34 @@ Clear console Neteja la consola + + &Disconnect Node + &Desconnecta el node + + + Ban Node for + Bandeja el node durant + + + 1 &hour + 1 &hora + + + 1 &day + 1 &dia + + + 1 &week + 1 &setmana + + + 1 &year + 1 &any + + + &Unban Node + &Desbandeja el node + Welcome to the Bitcoin Core RPC console. Us donem la benviguda a la consola RPC del Bitcoin Core. @@ -1573,6 +1677,10 @@ %1 GB %1 GB + + (node id: %1) + (id del node: %1) + via %1 a través de %1 @@ -1965,6 +2073,10 @@ Copy change Copia el canvi + + Total Amount %1 + Import total %1 + or o @@ -1997,6 +2109,10 @@ Payment request expired. La sol·licitud de pagament ha vençut. + + Pay only the required fee of %1 + Paga només la comissió necessària de %1 + Estimated to begin confirmation within %n block(s). Estimat per començar la confirmació en %n bloc.Estimat per començar la confirmació en %n blocs. @@ -2779,6 +2895,14 @@ Accept command line and JSON-RPC commands Accepta la línia d'ordres i ordres JSON-RPC + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Comissions totals màximes (en %s) per utilitzar en una única transacció de moneder; definir-ne una massa baixa pot interrompre les transaccions més grans (per defecte: %s) + + + Fee (in %s/kB) to add to transactions you send (default: %s) + Comissió (en %s/kB) per afegir a les transaccions que envieu (per defecte: %s) + Run in the background as a daemon and accept commands Executa en segon pla com a programa dimoni i accepta ordres @@ -2839,10 +2963,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Afegeix a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades. - - (default: 1) - (per defecte: 1) - <category> can be: <category> pot ser: @@ -3059,10 +3179,6 @@ Cannot resolve -whitebind address: '%s' No es pot resoldre l'adreça -whitebind: «%s» - - Choose data directory on startup (default: 0) - Tria el directori de dades a l'inici (per defecte: 0) - Connect through SOCKS5 proxy Connecta a través del proxy SOCKS5 @@ -3139,22 +3255,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Envia les transaccions com a transaccions de comissió zero sempre que sigui possible (per defecte: %u) - - Set SSL root certificates for payment request (default: -system-) - Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-) - - - Set language, for example "de_DE" (default: system locale) - Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema) - Show all debugging options (usage: --help -help-debug) Mostra totes les opcions de depuració (ús: --help --help-debug) - - Show splash screen on startup (default: 1) - Mostra la finestra de benvinguda a l'inici (per defecte: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Redueix el fitxer debug.log durant l'inici del client (per defecte: 1 quan no -debug) @@ -3163,10 +3267,6 @@ Signing transaction failed Ha fallat la signatura de la transacció - - Start minimized - Inicia minimitzat - The transaction amount is too small to pay the fee L'import de la transacció és massa petit per pagar-ne una comissió @@ -3191,10 +3291,6 @@ Transaction too large La transacció és massa gran - - UI Options: - Opcions d'interfície: - Unable to bind to %s on this computer (bind returned error %s) No s'ha pogut vincular a %s en aquest ordinador (la vinculació ha retornat l'error %s) diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index e717f53d4..2c41ec78d 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -433,6 +433,10 @@ No block source available... No hi ha cap font de bloc disponible... + + Processed %n block(s) of transaction history. + Proccessats %n bloc de l'historial de transaccions.Proccessats %n blocs de l'historial de transaccions. + %n hour(s) %n hora%n hores @@ -870,7 +874,7 @@ command-line options Opcions de la línia d'ordes - + Intro @@ -1067,6 +1071,10 @@ Port of the proxy (e.g. 9050) Port del proxy (per exemple 9050) + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor: + &Window &Finestra @@ -2835,10 +2843,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Afig a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades. - - (default: 1) - (per defecte: 1) - <category> can be: <category> pot ser: @@ -3055,10 +3059,6 @@ Cannot resolve -whitebind address: '%s' No es pot resoldre l'adreça -whitebind: «%s» - - Choose data directory on startup (default: 0) - Tria el directori de dades a l'inici (per defecte: 0) - Connect through SOCKS5 proxy Connecta a través del proxy SOCKS5 @@ -3135,22 +3135,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Envia les transaccions com a transaccions de comissió zero sempre que siga possible (per defecte: %u) - - Set SSL root certificates for payment request (default: -system-) - Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-) - - - Set language, for example "de_DE" (default: system locale) - Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema) - Show all debugging options (usage: --help -help-debug) Mostra totes les opcions de depuració (ús: --help --help-debug) - - Show splash screen on startup (default: 1) - Mostra la finestra de benvinguda a l'inici (per defecte: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Redueix el fitxer debug.log durant l'inici del client (per defecte: 1 quan no -debug) @@ -3159,10 +3147,6 @@ Signing transaction failed Ha fallat la signatura de la transacció - - Start minimized - Inicia minimitzat - The transaction amount is too small to pay the fee L'import de la transacció és massa petit per pagar-ne una comissió @@ -3187,10 +3171,6 @@ Transaction too large La transacció és massa gran - - UI Options: - Opcions d'interfície: - Unable to bind to %s on this computer (bind returned error %s) No s'ha pogut vincular a %s en este ordinador (la vinculació ha retornat l'error %s) diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index 331ad835f..e6a932ebe 100644 --- a/src/qt/locale/bitcoin_ca_ES.ts +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP / Màscara de xarxa + + + Banned Until + Bandejat fins + + BitcoinGUI @@ -874,6 +882,34 @@ command-line options Opcions de la línia d'ordres + + UI Options: + Opcions d'interfície d'usuari: + + + Choose data directory on startup (default: %u) + Trieu el directori de dades a l'inici (per defecte: %u) + + + Set language, for example "de_DE" (default: system locale) + Defineix la llengua, per exemple «de_DE» (per defecte: la definida pel sistema) + + + Start minimized + Inicia minimitzat + + + Set SSL root certificates for payment request (default: -system-) + Defineix els certificats arrel SSL per a la sol·licitud de pagament (per defecte: els del sistema) + + + Show splash screen on startup (default: %u) + Mostra la pantalla de benvinguda a l'inici (per defecte: %u) + + + Reset all settings changes made over the GUI + Reinicialitza tots els canvis de configuració fets des de la interfície gràfica + Intro @@ -1071,6 +1107,18 @@ Port of the proxy (e.g. 9050) Port del proxy (per exemple 9050) + + Used for reaching peers via: + Utilitzat per arribar als iguals mitjançant: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Mostra si el proxy SOCKS5 per defecte proporcionat s'utilitza per arribar als iguals mitjançant aquest tipus de xarxa. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Utilitza un proxy SOCKS4 apart per a arribar als iguals a través de serveis ocults de Tor: + &Window &Finestra @@ -1457,10 +1505,18 @@ &Peers &Iguals + + Banned peers + Iguals bandejats + Select a peer to view detailed information. Seleccioneu un igual per mostrar informació detallada. + + Whitelisted + A la llista blanca + Direction Direcció @@ -1469,6 +1525,18 @@ Version Versió + + Starting Block + Bloc d'inici + + + Synced Headers + Capçaleres sincronitzades + + + Synced Blocks + Blocs sincronitzats + User Agent Agent d'usuari @@ -1497,6 +1565,14 @@ Ping Time Temps de ping + + The duration of a currently outstanding ping. + La duració d'un ping més destacat actualment. + + + Ping Wait + Espera de ping + Time Offset Diferència horària @@ -1545,6 +1621,34 @@ Clear console Neteja la consola + + &Disconnect Node + &Desconnecta el node + + + Ban Node for + Bandeja el node durant + + + 1 &hour + 1 &hora + + + 1 &day + 1 &dia + + + 1 &week + 1 &setmana + + + 1 &year + 1 &any + + + &Unban Node + &Desbandeja el node + Welcome to the Bitcoin Core RPC console. Us donem la benviguda a la consola RPC del Bitcoin Core. @@ -1573,6 +1677,10 @@ %1 GB %1 GB + + (node id: %1) + (id del node: %1) + via %1 a través de %1 @@ -1965,6 +2073,10 @@ Copy change Copia el canvi + + Total Amount %1 + Import total %1 + or o @@ -1997,6 +2109,10 @@ Payment request expired. La sol·licitud de pagament ha vençut. + + Pay only the required fee of %1 + Paga només la comissió necessària de %1 + Estimated to begin confirmation within %n block(s). Estimat per començar la confirmació en %n bloc.Estimat per començar la confirmació en %n blocs. @@ -2779,6 +2895,14 @@ Accept command line and JSON-RPC commands Accepta la línia d'ordres i ordres JSON-RPC + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Comissions totals màximes (en %s) per utilitzar en una única transacció de moneder; definir-ne una massa baixa pot interrompre les transaccions més grans (per defecte: %s) + + + Fee (in %s/kB) to add to transactions you send (default: %s) + Comissió (en %s/kB) per afegir a les transaccions que envieu (per defecte: %s) + Run in the background as a daemon and accept commands Executa en segon pla com a programa dimoni i accepta ordres @@ -2839,10 +2963,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Afegeix a la llista blanca els iguals que es connecten de la màscara de xarxa o adreça IP donada. Es pot especificar moltes vegades. - - (default: 1) - (per defecte: 1) - <category> can be: <category> pot ser: @@ -3059,10 +3179,6 @@ Cannot resolve -whitebind address: '%s' No es pot resoldre l'adreça -whitebind: «%s» - - Choose data directory on startup (default: 0) - Tria el directori de dades a l'inici (per defecte: 0) - Connect through SOCKS5 proxy Connecta a través del proxy SOCKS5 @@ -3139,22 +3255,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Envia les transaccions com a transaccions de comissió zero sempre que sigui possible (per defecte: %u) - - Set SSL root certificates for payment request (default: -system-) - Defineix certificats arrel SSL per a la sol·licitud de pagament (per defecte: -sistema-) - - - Set language, for example "de_DE" (default: system locale) - Defineix un idioma, per exemple «de_DE» (per defecte: preferències locals de sistema) - Show all debugging options (usage: --help -help-debug) Mostra totes les opcions de depuració (ús: --help --help-debug) - - Show splash screen on startup (default: 1) - Mostra la finestra de benvinguda a l'inici (per defecte: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Redueix el fitxer debug.log durant l'inici del client (per defecte: 1 quan no -debug) @@ -3163,10 +3267,6 @@ Signing transaction failed Ha fallat la signatura de la transacció - - Start minimized - Inicia minimitzat - The transaction amount is too small to pay the fee L'import de la transacció és massa petit per pagar-ne una comissió @@ -3191,10 +3291,6 @@ Transaction too large La transacció és massa gran - - UI Options: - Opcions d'interfície: - Unable to bind to %s on this computer (bind returned error %s) No s'ha pogut vincular a %s en aquest ordinador (la vinculació ha retornat l'error %s) diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index a2232dbe8..ef1903edd 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -874,7 +874,7 @@ command-line options možnosti příkazové řádky - + Intro @@ -1071,6 +1071,10 @@ Port of the proxy (e.g. 9050) Port proxy (např. 9050) + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Použít samostatnou SOCKS5 proxy ke spojení s protějšky přes skryté služby v Toru: + &Window O&kno @@ -2839,10 +2843,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Umístit na bílou listinu protějšky připojující se z dané podsítě či IP adresy. Lze zadat i vícekrát. - - (default: 1) - (výchozí: 1) - <category> can be: <category> může být: @@ -3059,10 +3059,6 @@ Cannot resolve -whitebind address: '%s' Nemohu přeložit -whitebind adresu: '%s' - - Choose data directory on startup (default: 0) - Zvolit adresář pro data při startu (výchozí: 0) - Connect through SOCKS5 proxy Připojit se přes SOCKS5 proxy @@ -3139,22 +3135,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Posílat transakce pokud možno bez poplatků (výchozí: %u) - - Set SSL root certificates for payment request (default: -system-) - Nastavit kořenové SSL certifikáty pro platební požadavky (výchozí: -system-) - - - Set language, for example "de_DE" (default: system locale) - Nastavit jazyk, například „de_DE“ (výchozí: systémové nastavení) - Show all debugging options (usage: --help -help-debug) Zobrazit všechny možnosti ladění (užití: --help -help-debug) - - Show splash screen on startup (default: 1) - Zobrazit startovací obrazovku (výchozí: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Při spuštění klienta zmenšit soubor debug.log (výchozí: 1, pokud není zadáno -debug) @@ -3163,10 +3147,6 @@ Signing transaction failed Nepodařilo se podepsat transakci - - Start minimized - Nastartovat minimalizovaně - The transaction amount is too small to pay the fee Částka v transakci je příliš malá na pokrytí poplatku @@ -3191,10 +3171,6 @@ Transaction too large Transakce je příliš velká - - UI Options: - Možnosti UI: - Unable to bind to %s on this computer (bind returned error %s) Nedaří se mi připojit na %s na tomhle počítači (operace bind vrátila chybu %s) @@ -3351,6 +3327,10 @@ Specify connection timeout in milliseconds (minimum: 1, default: %d) Zadej časový limit spojení v milivteřinách (minimum: 1, výchozí: %d) + + Specify pid file (default: %s) + PID soubor (výchozí: %s) + Spend unconfirmed change when sending transactions (default: %u) Utrácet i ještě nepotvrzené drobné při posílání transakcí (výchozí: %u) diff --git a/src/qt/locale/bitcoin_cs_CZ.ts b/src/qt/locale/bitcoin_cs_CZ.ts new file mode 100644 index 000000000..cc0c79115 --- /dev/null +++ b/src/qt/locale/bitcoin_cs_CZ.ts @@ -0,0 +1,645 @@ + + + AddressBookPage + + Create a new address + Vytvořit novou adresu + + + Copy the currently selected address to the system clipboard + Kopírovat aktuálně vybrané adresy do schránky + + + &Delete + &Odstranit + + + Comma separated file (*.csv) + Textový soubor oddělený středníkem (*.csv) + + + + AddressTableModel + + Label + Popis + + + Address + Adresa + + + (no label) + (bez popisu) + + + + AskPassphraseDialog + + Enter passphrase + Zadej heslo + + + New passphrase + Nové heslo + + + Repeat new passphrase + Zopakujte nové heslo + + + Encrypt wallet + Zašifrovat peněženku + + + This operation needs your wallet passphrase to unlock the wallet. + Tato operace vyžaduje heslo k odemknutí peněženky. + + + Unlock wallet + Odemknout peněženku + + + This operation needs your wallet passphrase to decrypt the wallet. + Tato operace vyžaduje heslo k dešifrování peněženky. + + + Decrypt wallet + Dešifrovat peněženku + + + Change passphrase + Změnit heslo + + + Confirm wallet encryption + Potvrďte zašifrování peněženky + + + Wallet encrypted + Peněženka zašifrována + + + Wallet encryption failed + Zašifrování peněženky selhalo + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Šifrování peněženky selhalo vinou vnitřní chyby. Vaše peněženka nebyla zašifrována. + + + The supplied passphrases do not match. + Zadaná hesla nejsou shodná. + + + Wallet unlock failed + Odemčení peněženky selhalo + + + The passphrase entered for the wallet decryption was incorrect. + Heslo zadané k dešifrování peněženky nebylo správné + + + Wallet decryption failed + Deěifrování peněženky selhalo + + + + BanTableModel + + + BitcoinGUI + + Synchronizing with network... + Synchronizuji se sítí... + + + &Overview + &Přehled + + + Show general overview of wallet + Zobrazit základní přehled o peněžence + + + &Transactions + &Transakce + + + Browse transaction history + Procházení historií transakcí + + + Quit application + Ukončit aplikaci + + + &Options... + &Možnosti... + + + Change the passphrase used for wallet encryption + Změnit heslo k šifrování peněženky + + + Bitcoin + Bitcoin + + + &File + &Soubor + + + &Settings + &Nastavení + + + &Help + Nápo&věda + + + Tabs toolbar + Panely + + + Up to date + Aktuální + + + Catching up... + Zachytávám... + + + Sent transaction + Odeslané transakce + + + Incoming transaction + Příchozí transakce + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Peněženka je <b>zašifrována</b> a momentálně <b>odemčená</b> + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Peněženka je <b>zašifrována</b> a momentálně <b>uzamčená</b> + + + + ClientModel + + + CoinControlDialog + + Amount: + Množství: + + + Amount + Množství + + + Date + Datum + + + Confirmed + Potvrzeno + + + Copy address + Kopírovat sdresu + + + Copy label + Kopírovat popis + + + (no label) + (bez popisu) + + + + EditAddressDialog + + Edit Address + Upravit adresu + + + &Label + &Popisek + + + &Address + &Adresa + + + New receiving address + Nová adresa pro příjem + + + New sending address + Nová adresa k odeslání + + + Edit receiving address + Upravit adresu pro příjem + + + Edit sending address + Upravit adresu k odeslání + + + The entered address "%1" is already in the address book. + Zadaná adresa "%1" se již v seznamu adres nachází. + + + Could not unlock wallet. + Nemohu odemknout peněženku + + + New key generation failed. + Generování nového klíče selhalo. + + + + FreespaceChecker + + + HelpMessageDialog + + Usage: + Použití: + + + + Intro + + + OpenURIDialog + + + OptionsDialog + + Options + Možnosti + + + Map port using &UPnP + Mapovat port pomocí &UPnP + + + &Minimize to the tray instead of the taskbar + &Minimalizovat do systémové lišty (tray) namísto do hlavního panelu + + + M&inimize on close + M&inimalizovat při zavření + + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + Amount + Množství + + + + QRImageWidget + + + RPCConsole + + Name + Jméno + + + + ReceiveCoinsDialog + + &Label: + &Popisek: + + + &Message: + Zpráva: + + + Copy label + Kopírovat popis + + + + ReceiveRequestDialog + + Address + Adresa + + + Amount + Množství + + + Label + Popis + + + Message + Zpráva + + + + RecentRequestsTableModel + + Date + Datum + + + Label + Popis + + + Message + Zpráva + + + Amount + Množství + + + (no label) + (bez popisu) + + + + SendCoinsDialog + + Amount: + Množství: + + + Balance: + Zůstatek: + + + The amount to pay must be larger than 0. + Částka k zaplacení musí být větší než 0. + + + (no label) + (bez popisu) + + + + SendCoinsEntry + + &Label: + &Popisek: + + + Message: + Zpráva: + + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + [testnet] + [testnet] + + + + TrafficGraphWidget + + + TransactionDesc + + %1/unconfirmed + %1 potvrzeno + + + %1 confirmations + %1 potvrzení + + + Status + Stav + + + Date + Datum + + + Message + Zpráva + + + Transaction + Transakce + + + Amount + Množství + + + + TransactionDescDialog + + Transaction details + Detaily transakce + + + This pane shows a detailed description of the transaction + Toto podokno zobrazuje detailní popis transakce + + + + TransactionTableModel + + Date + Datum + + + Type + Typ + + + Confirmed (%1 confirmations) + Potvrzeno (%1 potvrzení) + + + This block was not received by any other nodes and will probably not be accepted! + Tento blok nebyl přijat žádným dalším uzlem a pravděpodobně nebude akceptován! + + + Label + Popis + + + Received with + Přijato s + + + Sent to + Odesláno na + + + Payment to yourself + Platba sobě samému + + + Mined + Vytěženo + + + Type of transaction. + Typ transakce. + + + + TransactionView + + All + Vše + + + Today + Dnes + + + This week + Tento týden + + + This month + Tento měsíc + + + Last month + Minulý měsíc + + + This year + Tento rok + + + Range... + Rozsah... + + + Received with + Přijato s + + + Sent to + Odesláno na + + + To yourself + Sobě samému + + + Mined + Vytěženo + + + Other + Ostatní + + + Min amount + Min. množství + + + Copy address + Kopírovat sdresu + + + Copy label + Kopírovat popis + + + Edit label + Upravit popis + + + Comma separated file (*.csv) + Textový soubor oddělený středníkem (*.csv) + + + Confirmed + Potvrzeno + + + Date + Datum + + + Type + Typ + + + Label + Popis + + + Address + Adresa + + + ID + ID + + + Range: + Rozsah: + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + + bitcoin-core + + Options: + Možnosti: + + + Loading addresses... + Načítání adres... + + + Loading wallet... + Načítání peněženky... + + + Done loading + Načítání dokončeno + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_cy.ts b/src/qt/locale/bitcoin_cy.ts index eba036333..c32d236a9 100644 --- a/src/qt/locale/bitcoin_cy.ts +++ b/src/qt/locale/bitcoin_cy.ts @@ -347,6 +347,10 @@ CoinControlDialog + + Amount: + Maint + Date Dyddiad @@ -545,6 +549,10 @@ ReceiveRequestDialog + + Copy &Address + &Cyfeiriad Copi + Address Cyfeiriad @@ -583,6 +591,10 @@ Send Coins Anfon arian + + Amount: + Maint + Send to multiple recipients at once Anfon at pobl lluosog ar yr un pryd @@ -626,6 +638,10 @@ Alt+P Alt+P + + Message: + Neges: + ShutdownWindow @@ -761,6 +777,10 @@ bitcoin-core + + Options: + Opsiynau: + Information Gwybodaeth diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index 93594dcb0..aa2724a1e 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -882,6 +882,34 @@ command-line options kommandolinjetilvalg + + UI Options: + Indstillinger for brugergrænseflade: + + + Choose data directory on startup (default: %u) + Vælg datamappe under opstart (standard: %u) + + + Set language, for example "de_DE" (default: system locale) + Vælg sprog; fx "da_DK" (standard: systemsprog) + + + Start minimized + Start minimeret + + + Set SSL root certificates for payment request (default: -system-) + Opsæt SSL-rodcertifikater til betalingsadmodninger (standard: -system-) + + + Show splash screen on startup (default: %u) + Vis startskærm under opstart (standard: %u) + + + Reset all settings changes made over the GUI + Nulstil alle indstillinger, der er foretaget i den grafiske brugerflade + Intro @@ -925,7 +953,11 @@ %n GB of free space available %n GB fri plads tilgængelig%n GB fri plads tilgængelig - + + (of %n GB needed) + (ud af %n GB behøvet)(ud af %n GB behøvet) + + OpenURIDialog @@ -1097,7 +1129,7 @@ Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. - Forbind til Bitcoin-netværket gennem en separat SOCKS5-proxy for skjulte tjenester via Tor. + Forbind til Bitcoin-netværket gennem en separat SOCKS5-proxy for skjulte Tor-tjenester. Use separate SOCKS5 proxy to reach peers via Tor hidden services: @@ -1473,6 +1505,18 @@ Current number of blocks Nuværende antal blokke + + Memory Pool + Hukommelsespulje + + + Current number of transactions + Aktuelt antal transaktioner + + + Memory usage + Hukommelsesforbrug + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Åbn Bitcoin Cores fejlsøgningslogfil fra den aktuelle datamappe. Dette kan tage nogle få sekunder for store logfiler. @@ -2732,6 +2776,10 @@ Copy transaction ID Kopiér transaktions-ID + + Copy raw transaction + Kopiér rå transaktion + Edit label Redigér mærkat @@ -2991,10 +3039,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Sæt andre knuder, der forbinder fra den angivne netmaske eller IP, på hvidliste. Kan angives flere gange. - - (default: 1) - (standard: 1) - -maxmempool must be at least %d MB -maxmempool skal være mindst %d MB @@ -3251,17 +3295,21 @@ Activating best chain... Aktiverer bedste kæde… + + Always relay transactions received from whitelisted peers (default: %d) + Videresend altid transaktioner, der modtages fra hvidlistede knuder (standard: %d) + Attempt to recover private keys from a corrupt wallet.dat on startup Forsøg at genskabe private nøgler fra en ødelagt wallet.dat under opstart - Cannot resolve -whitebind address: '%s' - Kan ikke løse -whitebind adresse: "%s" + Automatically create Tor hidden service (default: %d) + Opret automatisk skjult Tor-tjeneste (standard: %d) - Choose data directory on startup (default: 0) - Vælg datamappe ved opstart (standard: 0) + Cannot resolve -whitebind address: '%s' + Kan ikke løse -whitebind adresse: "%s" Connect through SOCKS5 proxy @@ -3351,22 +3399,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Send transaktioner som nul-gebyr-transaktioner hvis muligt (standard: %u) - - Set SSL root certificates for payment request (default: -system-) - Sæt SSL-rodcertifikater for betalingsanmodning (standard: -system-) - - - Set language, for example "de_DE" (default: system locale) - Angiv sprog, fx "da_DK" (standard: systemlokalitet) - Show all debugging options (usage: --help -help-debug) Vis alle tilvalg for fejlsøgning (brug: --help -help-debug) - - Show splash screen on startup (default: 1) - Vis opstartsbillede ved opstart (standard: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Formindsk debug.log filen ved klientopstart (standard: 1 hvis ikke -debug) @@ -3375,10 +3411,6 @@ Signing transaction failed Underskrift af transaktion mislykkedes - - Start minimized - Start minimeret - The transaction amount is too small to pay the fee Transaktionsbeløbet er for lille til at betale gebyret @@ -3387,6 +3419,14 @@ This is experimental software. Dette er eksperimentelt software. + + Tor control port password (default: empty) + Adgangskode for Tor kontrolport (standard: tom) + + + Tor control port to use if onion listening enabled (default: %s) + Tor kontrolport, der skal bruges, hvis onion-lytning er slået til (standard: %s) + Transaction amount too small Transaktionsbeløb er for lavt @@ -3403,10 +3443,6 @@ Transaction too large Transaktionen er for stor - - UI Options: - Indstillinger for brugerflade: - Unable to bind to %s on this computer (bind returned error %s) Ikke i stand til at tildele til %s på denne computer (bind returnerede fejl %s) @@ -3427,6 +3463,10 @@ Warning Advarsel + + Whether to operate in a blocks only mode (default: %u) + Hvorvidt der skal arbejdes i kun-blokke-tilstand (standard: %u) + Zapping all transactions from wallet... Zapper alle transaktioner fra tegnebog… @@ -3483,6 +3523,10 @@ Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Fejl under læsning af wallet.dat! Alle nøgler blev læst korrekt, men transaktionsdata eller indgange i adressebogen kan mangle eller være ukorrekte. + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Gebyrer (i %s/kB) mindre end dette opfattes som intet gebyr under oprettelse af transaktioner (standard: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Hvor gennemarbejdet blokverificeringen for -checkblocks er (0-4; standard: %u) @@ -3499,6 +3543,10 @@ Output debugging information (default: %u, supplying <category> is optional) Udskriv fejlsøgningsinformation (standard: %u, angivelse af <kategori> er valgfri) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Understøt filtrering af blokke og transaktioner med Bloom-filtre (standard: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. Den totale længde på netværksversionsstrengen (%i) overstiger maksimallængden (%i). Reducér antaller af eller størrelsen på uacomments. @@ -3513,7 +3561,11 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) - Brug separat SOCS5-proxy for at nå andre knuder via Tor skjulte tjenester (standard: %s) + Brug separat SOCS5-proxy for at nå knuder via skjulte Tor-tjenester (standard: %s) + + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Brugernavn og hashet adgangskode for JSON-RPC-forbindelser. Feltet <userpw> er i formatet: <BRUGERNAVN>:<SALT>$<HASH>. Et kanonisk Python-skript inkluderes i share/rpcuser. Dette tilvalg kan angives flere gange (default: %s) diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 42776f2c8..84de80aff 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -226,7 +226,11 @@ IP/Netmask IP/Netzmaske - + + Banned Until + Gesperrt bis + + BitcoinGUI @@ -878,6 +882,34 @@ command-line options Kommandozeilenoptionen + + UI Options: + UI Einstellungen: + + + Choose data directory on startup (default: %u) + Datenverzeichnis beim Starten auswählen (Standard: %u) + + + Set language, for example "de_DE" (default: system locale) + Sprache einstellen, zum Beispiel "de_DE" (default: system locale) + + + Start minimized + Minimiert starten + + + Set SSL root certificates for payment request (default: -system-) + SSL-Wurzelzertifikate für Zahlungsanforderungen festlegen (Standard: -system-) + + + Show splash screen on startup (default: %u) + Startbildschirm beim Starten anzeigen (Standard: %u) + + + Reset all settings changes made over the GUI + Setze alle Einstellungen zurück, die über die grafische Oberfläche geändert wurden. + Intro @@ -1075,6 +1107,14 @@ Port of the proxy (e.g. 9050) Port des Proxies (z.B. 9050) + + Used for reaching peers via: + Benutzt um Gegenstellen zu erreichen über: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Zeigt an, ob der eingegebene Standard SOCKS5 Proxy genutzt wird um Peers mit dem Netzwerktyp zu erreichen. + IPv4 IPv4 @@ -1087,6 +1127,14 @@ Tor Tor + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Über einen separaten SOCKS5 Proxy für Tor Services mit dem Bitcoint Netzwerk verbinden. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Separaten SOCKS5-Proxy verwenden, um Gegenstellen über versteckte Tor-Dienste zu erreichen: + &Window &Programmfenster @@ -1457,6 +1505,18 @@ Current number of blocks Aktuelle Anzahl Blöcke + + Memory Pool + Speicherpool + + + Current number of transactions + Aktuelle Anzahl der Transaktionen + + + Memory usage + Speichernutzung + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Öffnet die "Bitcoin Core"-Debugprotokolldatei aus dem aktuellen Datenverzeichnis. Dies kann bei großen Protokolldateien einige Sekunden dauern. @@ -1473,10 +1533,18 @@ &Peers &Gegenstellen + + Banned peers + Gesperrte Peers + Select a peer to view detailed information. Gegenstelle auswählen, um detaillierte Informationen zu erhalten. + + Whitelisted + Zugelassene + Direction Richtung @@ -1485,6 +1553,10 @@ Version Version + + Starting Block + Start Block + Synced Headers Synchronisierte Kopfdaten @@ -1521,6 +1593,14 @@ Ping Time Pingzeit + + The duration of a currently outstanding ping. + Die Laufzeit eines aktuell ausstehenden Ping. + + + Ping Wait + Ping Wartezeit + Time Offset Zeitversatz @@ -1573,6 +1653,10 @@ &Disconnect Node Knoten &trennen + + Ban Node for + Knoten gebannt für + 1 &hour 1 &Stunde @@ -1589,6 +1673,10 @@ 1 &year 1 &Jahr + + &Unban Node + &Node entsperren + Welcome to the Bitcoin Core RPC console. Willkommen in der "Bitcoin Core"-RPC-Konsole. @@ -2049,6 +2137,10 @@ Payment request expired. Zahlungsanforderung abgelaufen. + + Pay only the required fee of %1 + Nur die notwendige Gebühr in Höhe von %1 zahlen + Estimated to begin confirmation within %n block(s). Voraussichtlicher Beginn der Bestätigung innerhalb von %n Block.Voraussichtlicher Beginn der Bestätigung innerhalb von %n Blöcken. @@ -2684,6 +2776,10 @@ Copy transaction ID Transaktions-ID kopieren + + Copy raw transaction + Kopiere rohe Transaktion + Edit label Bezeichnung bearbeiten @@ -2831,6 +2927,14 @@ Accept command line and JSON-RPC commands Kommandozeilen- und JSON-RPC-Befehle annehmen + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Maximale Gesamtgebühr (in %s) in einer Börsentransaktion; wird dies zu niedrig gesetzten können große Transaktionen abgebrochen werden (Standard: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Bitte korrigieren Sie die Datums- und Uhrzeiteinstellungen Ihres Computers, da Bitcoin Core ansonsten nicht ordnungsgemäß funktionieren wird. + Error: A fatal internal error occurred, see debug.log for details Fehler: Ein schwerer interner Fehler ist aufgetreten, siehe debug.log für Details. @@ -2843,6 +2947,10 @@ Run in the background as a daemon and accept commands Als Hintergrunddienst ausführen und Befehle annehmen + + Unable to start HTTP server. See debug log for details. + Kann HTTP Server nicht starten. Siehe debug log für Details. + Accept connections from outside (default: 1 if no -proxy or -connect) Eingehende Verbindungen annehmen (Standard: 1, wenn nicht -proxy oder -connect) @@ -2899,10 +3007,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Gegenstellen die sich von der angegebenen Netzmaske oder IP-Adresse aus verbinden immer zulassen. Kann mehrmals angegeben werden. - - (default: 1) - (Standard: 1) - -maxmempool must be at least %d MB -maxmempool muss mindestens %d MB betragen @@ -2939,6 +3043,18 @@ Do you want to rebuild the block database now? Möchten Sie die Blockdatenbank jetzt neu aufbauen? + + Enable publish hash block in <address> + Aktiviere das Veröffentlichen des Hash-Blocks in <address> + + + Enable publish hash transaction in <address> + Aktiviere das Veröffentlichen der Hash-Transaktion in <address> + + + Enable publish raw block in <address> + Aktiviere das Veröffentlichen des Raw-Blocks in <address> + Error initializing block database Fehler beim Initialisieren der Blockdatenbank @@ -3003,6 +3119,18 @@ Specify wallet file (within data directory) Wallet-Datei angeben (innerhalb des Datenverzeichnisses) + + Unsupported argument -benchmark ignored, use -debug=bench. + Nicht unterstütztes Argument -benchmark wurde ignoriert, bitte -debug=bench verwenden. + + + Unsupported argument -debugnet ignored, use -debug=net. + Nicht unterstütztes Argument -debugnet wurde ignoriert, bitte -debug=net verwenden. + + + Unsupported argument -tor found, use -onion. + Nicht unterstütztes Argument -tor gefunden, bitte -onion verwenden. + Use UPnP to map the listening port (default: %u) UPnP verwenden, um eine Portweiterleitung einzurichten (Standard: %u) @@ -3120,12 +3248,16 @@ Aktiviere beste Blockkette... - Cannot resolve -whitebind address: '%s' - Kann Adresse in -whitebind nicht auflösen: '%s' + Attempt to recover private keys from a corrupt wallet.dat on startup + Versuchen, private Schlüssel beim Starten aus einer beschädigten wallet.dat wiederherzustellen - Choose data directory on startup (default: 0) - Datenverzeichnis beim Starten auswählen (Standard: 0) + Automatically create Tor hidden service (default: %d) + Automatisch versteckten Tor-Dienst erstellen (Standard: %d) + + + Cannot resolve -whitebind address: '%s' + Kann Adresse in -whitebind nicht auflösen: '%s' Connect through SOCKS5 proxy @@ -3143,6 +3275,10 @@ Error reading from database, shutting down. Fehler beim lesen der Datenbank, Ausführung wird beendet. + + Imports blocks from external blk000??.dat file on startup + Blöcke beim Starten aus externer Datei blk000??.dat importieren + Information Hinweis @@ -3195,6 +3331,10 @@ Receive and display P2P network alerts (default: %u) P2P-Netzwerk-Alarme empfangen und anzeigen (Standard: %u) + + Rescan the block chain for missing wallet transactions on startup + Blockkette beim Starten erneut nach fehlenden Wallet-Transaktionen durchsuchen + Send trace/debug info to console instead of debug.log file Rückverfolgungs- und Debuginformationen an die Konsole senden, anstatt sie in debug.log zu schreiben @@ -3203,22 +3343,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Transaktionen, wenn möglich, als gebührenfreie Transaktion senden (Standard: %u) - - Set SSL root certificates for payment request (default: -system-) - SSL-Wurzelzertifikate für Zahlungsanforderungen festlegen (Standard: -system-) - - - Set language, for example "de_DE" (default: system locale) - Sprache festlegen, z.B. "de_DE" (Standard: Systemstandard) - Show all debugging options (usage: --help -help-debug) Zeige alle Debuggingoptionen (Benutzung: --help -help-debug) - - Show splash screen on startup (default: 1) - Startbildschirm beim Starten anzeigen (Standard: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Protokolldatei debug.log beim Starten des Clients kürzen (Standard: 1, wenn kein -debug) @@ -3227,10 +3355,6 @@ Signing transaction failed Signierung der Transaktion fehlgeschlagen - - Start minimized - Minimiert starten - The transaction amount is too small to pay the fee Der Transaktionsbetrag ist zu niedrig, um die Gebühr zu bezahlen. @@ -3239,6 +3363,14 @@ This is experimental software. Dies ist experimentelle Software. + + Tor control port password (default: empty) + TOR Kontrollport Passwort (Standard: leer) + + + Tor control port to use if onion listening enabled (default: %s) + Zu benutzender TOR Kontrollport wenn Onion Auflistung aktiv ist (Standard: %s) + Transaction amount too small Transaktionsbetrag zu niedrig @@ -3255,14 +3387,14 @@ Transaction too large Transaktion zu groß - - UI Options: - Benutzeroberflächenoptionen: - Unable to bind to %s on this computer (bind returned error %s) Kann auf diesem Computer nicht an %s binden (bind meldete Fehler %s) + + Upgrade wallet to latest format on startup + Wallet beim Starten auf das neueste Format aktualisieren + Username for JSON-RPC connections Benutzername für JSON-RPC-Verbindungen @@ -3275,6 +3407,10 @@ Warning Warnung + + Whether to operate in a blocks only mode (default: %u) + Legt fest ob nur Blöcke Modus aktiv sein soll (Standard: %u) + Zapping all transactions from wallet... Lösche alle Transaktionen aus Wallet... @@ -3315,6 +3451,22 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = TX-Metadaten wie z.B. Accountbesitzer und Zahlungsanforderungsinformationen behalten, 2 = TX-Metadaten verwerfen) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee ist auf einen sehr hohen Wert festgelegt! Gebühren dieser Höhe könnten für eine einzelne Transaktion bezahlt werden. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee ist auf einen sehr hohen Wert festgelegt! Dies ist die Gebühr die beim Senden einer Transaktion fällig wird. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Die Transaktion nicht länger im Speicherpool behalten als <n> Stunden (Standard: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Lesen von wallet.dat fehlgeschlagen! Alle Schlüssel wurden korrekt gelesen, Transaktionsdaten bzw. Adressbucheinträge fehlen aber möglicherweise oder sind inkorrekt. + How thorough the block verification of -checkblocks is (0-4, default: %u) Legt fest, wie gründlich die Blockverifikation von -checkblocks ist (0-4, Standard: %u) @@ -3331,6 +3483,14 @@ Output debugging information (default: %u, supplying <category> is optional) Debugginginformationen ausgeben (Standard: %u, <category> anzugeben ist optional) + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Versucht ausgehenden Datenverkehr unter dem gegebenen Wert zu halten (in MiB pro 24h), 0 = kein Limit (default: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Nicht unterstütztes Argument -socks gefunden. Das Festlegen der SOCKS-Version ist nicht mehr möglich, nur noch SOCKS5-Proxies werden unterstützt. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Separaten SOCKS5-Proxy verwenden, um Gegenstellen über versteckte Tor-Dienste zu erreichen (Standard: %s) @@ -3367,6 +3527,10 @@ Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) <port> nach JSON-RPC-Verbindungen abhören (Standard: %u oder Testnetz: %u) + + Listen for connections on <port> (default: %u or testnet: %u) + <port> nach Verbindungen abhören (Standard: %u oder Testnetz: %u) + Maintain at most <n> connections to peers (default: %u) Maximal <n> Verbindungen zu Gegenstellen aufrechterhalten (Standard: %u) diff --git a/src/qt/locale/bitcoin_el.ts b/src/qt/locale/bitcoin_el.ts new file mode 100644 index 000000000..6777961cb --- /dev/null +++ b/src/qt/locale/bitcoin_el.ts @@ -0,0 +1,321 @@ + + + AddressBookPage + + Create a new address + Δημιουργία νέου λογαριασμού + + + + AddressTableModel + + Label + Ετικέτα + + + Address + Διεύθυνση + + + + AskPassphraseDialog + + Enter passphrase + Εισάγετε συνθηματικό + + + New passphrase + Νέο συνθηματικό + + + Repeat new passphrase + Επαναλάβετε νέο συνθηματικό + + + Change passphrase + Αλλαγή συνθηματικού + + + + BanTableModel + + + BitcoinGUI + + Quit application + Κλείσιμο εφαρμογής + + + Wallet + Πορτοφόλι + + + Error + Σφάλμα + + + + ClientModel + + + CoinControlDialog + + Date + Ημερομηνία + + + Copy address + Αντιγραφή διεύθυνσης + + + Copy amount + Αντιγραφή ποσού + + + Copy quantity + Αντιγραφή ποσότητας + + + Copy change + Αντιγραφή αλλαγής + + + + EditAddressDialog + + &Label + Ετικέτα + + + &Address + Διεύθυνση + + + + FreespaceChecker + + + HelpMessageDialog + + version + έκδοση + + + + Intro + + Welcome + Καλώς Ήλθατε + + + Error + Σφάλμα + + + + OpenURIDialog + + + OptionsDialog + + W&allet + Πορτοφόλι + + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + Services + Υπηρεσίες + + + + ReceiveCoinsDialog + + Remove + Αφαίρεση + + + Copy message + Αντιγραφή μηνύματος + + + Copy amount + Αντιγραφή ποσού + + + + ReceiveRequestDialog + + Address + Διεύθυνση + + + Label + Ετικέτα + + + Message + Μήνυμα + + + + RecentRequestsTableModel + + Date + Ημερομηνία + + + Label + Ετικέτα + + + Message + Μήνυμα + + + (no message) + (κανένα μήνυμα) + + + + SendCoinsDialog + + Insufficient funds! + Κεφάλαια μη επαρκή + + + Recommended: + Συνίσταται: + + + Copy quantity + Αντιγραφή ποσότητας + + + Copy amount + Αντιγραφή ποσού + + + Copy change + Αντιγραφή αλλαγής + + + + SendCoinsEntry + + Message: + Μήνυμα: + + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDesc + + Date + Ημερομηνία + + + Message + Μήνυμα + + + + TransactionDescDialog + + + TransactionTableModel + + Date + Ημερομηνία + + + Label + Ετικέτα + + + + TransactionView + + Copy address + Αντιγραφή διεύθυνσης + + + Copy amount + Αντιγραφή ποσού + + + Date + Ημερομηνία + + + Label + Ετικέτα + + + Address + Διεύθυνση + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + + bitcoin-core + + Insufficient funds + Κεφάλαια μη επαρκή + + + Loading wallet... + Φόρτωση πορτοφολιού... + + + Rescanning... + Επανάληψη σάρωσης + + + Done loading + Η φόρτωση ολοκληρώθηκε + + + Error + Σφάλμα + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts index d9f8dee5e..90c27c439 100644 --- a/src/qt/locale/bitcoin_el_GR.ts +++ b/src/qt/locale/bitcoin_el_GR.ts @@ -694,6 +694,10 @@ This label turns red if any recipient receives an amount smaller than %1. Αυτή η ετικέτα γίνεται κόκκινη αν οποιοσδήποτε παραλήπτης λάβει ποσό μικρότερο από %1. + + Can vary +/- %1 satoshi(s) per input. + Μπορεί να διαφέρει +/- %1 Satoshi (ες) ανά εγγραφή. + yes ναι @@ -706,6 +710,10 @@ This means a fee of at least %1 per kB is required. Ελάχιστο χρεώσιμο ποσό τουλάχιστο %1 ανα kB + + Can vary +/- 1 byte per input. + Μπορεί να διαφέρει +/- 1 byte ανά εγγραφή. + Transactions with higher priority are more likely to get included into a block. Συναλλαγές με υψηλότερη προτεραιότητα είναι πιο πιθανό να περιλαμβάνονται σε ένα μπλοκ. @@ -832,7 +840,7 @@ command-line options επιλογής γραμμής εντολών - + Intro @@ -2542,10 +2550,6 @@ 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. Προειδοποίηση : το αρχειο wallet.dat ειναι διεφθαρμένο, τα δεδομένα σώζονται ! Original wallet.dat αποθηκεύονται ως wallet.{timestamp}.bak στο %s . Αν το υπόλοιπο του ή τις συναλλαγές σας, είναι λάθος θα πρέπει να επαναφέρετε από ένα αντίγραφο ασφαλείας - - (default: 1) - (προεπιλογή: 1) - Block creation options: Αποκλεισμός επιλογων δημιουργίας: @@ -2606,6 +2610,10 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Μόνο σύνδεση σε κόμβους του δικτύου <net> (ipv4, ipv6 ή onion) + + Set maximum block size in bytes (default: %d) + Ορίστε το μέγιστο μέγεθος block σε bytes (προεπιλογή: %d) + Specify wallet file (within data directory) Επιλέξτε αρχείο πορτοφολιού (μέσα απο κατάλογο δεδομένων) @@ -2630,14 +2638,14 @@ Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. Αδυναμία κλειδώματος του φακέλου δεδομένων %s. Πιθανώς το Bitcoin να είναι ήδη ενεργό. - - Choose data directory on startup (default: 0) - Επιλογή φακέλου δεδομένων στην εκκίνηση (προεπιλεγμένο: 0) - Connect through SOCKS5 proxy Σύνδεση μέσω διαμεσολαβητή SOCKS5 + + Copyright (C) 2009-%i The Bitcoin Core Developers + Πνευματικά δικαιώματα 2009-%i Οι προγραμματιστές του Bitcoin Core + Error loading wallet.dat: Wallet requires newer version of Bitcoin Core Σφάλμα φόρτωσης wallet.dat: Το Πορτοφόλι απαιτεί μια νεότερη έκδοση του Bitcoin @@ -2654,6 +2662,10 @@ Initialization sanity check failed. Bitcoin Core is shutting down. Η εκκίνηση ελέγχου ορθότητας απέτυχε. Γίνεται τερματισμός του Bitcoin Core. + + Invalid amount for -maxtxfee=<amount>: '%s' + Μη έγκυρο ποσό για την παράμετρο -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Μη έγκυρο ποσό για την παράμετρο -paytxfee=<amount>: '%s' @@ -2674,22 +2686,10 @@ Send trace/debug info to console instead of debug.log file Αποστολή πληροφοριών εντοπισμού σφαλμάτων στην κονσόλα αντί του αρχείου debug.log - - Set SSL root certificates for payment request (default: -system-) - Ορίστε SSL root certificates για αίτηση πληρωμής (default: -system-) - - - Set language, for example "de_DE" (default: system locale) - Όρισε γλώσσα, για παράδειγμα "de_DE"(προεπιλογή:τοπικές ρυθμίσεις) - Show all debugging options (usage: --help -help-debug) Προβολή όλων των επιλογών εντοπισμού σφαλμάτων (χρήση: --help -help-debug) - - Show splash screen on startup (default: 1) - Εμφάνισε την οθόνη εκκίνησης κατά την εκκίνηση(προεπιλογή:1) - Shrink debug.log file on client startup (default: 1 when no -debug) Συρρίκνωση του αρχείο debug.log κατα την εκκίνηση του πελάτη (προεπιλογή: 1 όταν δεν-debug) @@ -2698,10 +2698,6 @@ Signing transaction failed Η υπογραφή συναλλαγής απέτυχε - - Start minimized - Έναρξη ελαχιστοποιημένο - This is experimental software. Η εφαρμογή είναι σε πειραματικό στάδιο. @@ -2790,6 +2786,14 @@ Invalid -proxy address: '%s' Δεν είναι έγκυρη η διεύθυνση διαμεσολαβητή: '%s' + + Maintain at most <n> connections to peers (default: %u) + Μέγιστες αριθμός συνδέσεων με τους peers <n> (προεπιλογή: %u) + + + Specify configuration file (default: %s) + Ορίστε αρχείο ρυθμίσεων (προεπιλογή: %s) + Specify connection timeout in milliseconds (minimum: 1, default: %d) Ορισμός λήξης χρονικού ορίου σε χιλιοστά του δευτερολέπτου(προεπιλογή: %d) diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 21df73252..00411741f 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -299,7 +299,7 @@ BitcoinGUI - + Sign &message... Sign &message... @@ -701,7 +701,7 @@ ClientModel - + Network Alert Network Alert @@ -925,7 +925,7 @@ - + This label turns red if the transaction size is greater than 1000 bytes. @@ -940,12 +940,12 @@ - + Can vary +/- %1 satoshi(s) per input. - + yes @@ -971,7 +971,7 @@ - + (no label) (no label) @@ -1086,7 +1086,7 @@ HelpMessageDialog - + Bitcoin Core Bitcoin Core @@ -1121,6 +1121,41 @@ command-line options command-line options + + + UI Options: + + + + + Choose data directory on startup (default: %u) + + + + + Set language, for example "de_DE" (default: system locale) + + + + + Start minimized + + + + + Set SSL root certificates for payment request (default: -system-) + + + + + Show splash screen on startup (default: %u) + + + + + Reset all settings changed in the GUI + + Intro @@ -1469,17 +1504,17 @@ &Cancel - + default default - + none - + Confirm options reset Confirm options reset @@ -1500,7 +1535,7 @@ - + The supplied proxy address is invalid. The supplied proxy address is invalid. @@ -1756,7 +1791,7 @@ - + %1 d @@ -1830,11 +1865,13 @@ - + - + + + @@ -1855,7 +1892,7 @@ N/A - + Client version Client version @@ -1890,12 +1927,12 @@ Startup time - + Network Network - + Name @@ -1915,12 +1952,27 @@ Current number of blocks - + + Memory Pool + + + + + Current number of transactions + + + + + Memory usage + + + + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - + Received @@ -1943,8 +1995,8 @@ - - + + Select a peer to view detailed information. @@ -1979,8 +2031,8 @@ - - + + User Agent @@ -2030,17 +2082,17 @@ - + Last block time Last block time - + &Open &Open - + &Console &Console @@ -2060,7 +2112,7 @@ - + In: @@ -2070,17 +2122,17 @@ - + Build date Build date - + Debug log file Debug log file - + Clear console Clear console @@ -2138,7 +2190,7 @@ Type <b>help</b> for an overview of available commands. - + %1 B @@ -2706,12 +2758,12 @@ - + Pay only the required fee of %1 - + Estimated to begin confirmation within %n block(s). Estimated to begin confirmation within %n block. @@ -2719,7 +2771,7 @@ - + The recipient address is not valid. Please recheck. @@ -2729,7 +2781,7 @@ - + Warning: Invalid Bitcoin address @@ -2744,7 +2796,7 @@ - + Copy dust @@ -2871,7 +2923,7 @@ ShutdownWindow - + Bitcoin Core is shutting down... @@ -3703,32 +3755,32 @@ bitcoin-core - + Options: Options: - + Specify data directory Specify data directory - + Connect to a node to retrieve peer addresses, and disconnect Connect to a node to retrieve peer addresses, and disconnect - + Specify your own public address Specify your own public address - + Accept command line and JSON-RPC commands Accept command line and JSON-RPC commands - + If <category> is not supplied or if <category> = 1, output all debugging information. @@ -3763,7 +3815,7 @@ - + Error: A fatal internal error occurred, see debug.log for details @@ -3783,17 +3835,17 @@ Run in the background as a daemon and accept commands - + Unable to start HTTP server. See debug log for details. - + Accept connections from outside (default: 1 if no -proxy or -connect) Accept connections from outside (default: 1 if no -proxy or -connect) - + Bind to given address and always listen on it. Use [host]:port notation for IPv6 Bind to given address and always listen on it. Use [host]:port notation for IPv6 @@ -3813,12 +3865,12 @@ Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) - + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) - + The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct @@ -3838,7 +3890,7 @@ - + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) @@ -3869,11 +3921,6 @@ - (default: 1) - - - - -maxmempool must be at least %d MB @@ -3888,7 +3935,7 @@ Block creation options: - + Connect only to the specified node(s) Connect only to the specified node(s) @@ -4008,22 +4055,22 @@ - + Set database cache size in megabytes (%d to %d, default: %d) - + Set maximum block size in bytes (default: %d) - + Specify wallet file (within data directory) Specify wallet file (within data directory) - + Unsupported argument -benchmark ignored, use -debug=bench. @@ -4078,7 +4125,7 @@ You need to rebuild the database using -reindex to change -txindex - + 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 @@ -4123,7 +4170,7 @@ - + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) @@ -4158,7 +4205,7 @@ - + The transaction amount is too small to send after the fee has been deducted @@ -4168,7 +4215,7 @@ - + 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 @@ -4183,7 +4230,7 @@ - + Accept public REST requests (default: %u) @@ -4213,12 +4260,7 @@ - - Choose data directory on startup (default: 0) - Choose data directory on startup (default: 0) - - - + Connect through SOCKS5 proxy @@ -4328,25 +4370,10 @@ - - Set SSL root certificates for payment request (default: -system-) - - - - - Set language, for example "de_DE" (default: system locale) - Set language, for example "de_DE" (default: system locale) - - - + Show all debugging options (usage: --help -help-debug) - - - Show splash screen on startup (default: 1) - Show splash screen on startup (default: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) @@ -4359,11 +4386,6 @@ - Start minimized - Start minimized - - - The transaction amount is too small to pay the fee @@ -4402,11 +4424,6 @@ Transaction too large Transaction too large - - - UI Options: - - Unable to bind to %s on this computer (bind returned error %s) @@ -4453,27 +4470,27 @@ wallet.dat corrupt, salvage failed - + Password for JSON-RPC connections Password for JSON-RPC connections - + Execute command when the best block changes (%s in cmd is replaced by block hash) Execute command when the best block changes (%s in cmd is replaced by block hash) - + This help message This help message - + Allow DNS lookups for -addnode, -seednode and -connect Allow DNS lookups for -addnode, -seednode and -connect - + Loading addresses... Loading addresses... @@ -4483,7 +4500,7 @@ Error loading wallet.dat: Wallet corrupted - + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) @@ -4509,6 +4526,11 @@ + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + + + + How thorough the block verification of -checkblocks is (0-4, default: %u) @@ -4528,7 +4550,12 @@ - + + Support filtering of blocks and transaction with bloom filters (default: %u) + + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. @@ -4548,17 +4575,22 @@ - + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + + + + (default: %s) - + Always query for peer addresses via DNS lookup (default: %u) - + Error loading wallet.dat Error loading wallet.dat @@ -4628,12 +4660,12 @@ - + Set key pool size to <n> (default: %u) - + Set minimum block size in bytes (default: %u) @@ -4643,7 +4675,7 @@ - + Specify configuration file (default: %s) @@ -4663,17 +4695,17 @@ - + Threshold for disconnecting misbehaving peers (default: %u) - + Unknown network specified in -onlynet: '%s' Unknown network specified in -onlynet: '%s' - + Cannot resolve -bind address: '%s' Cannot resolve -bind address: '%s' @@ -4683,7 +4715,7 @@ Cannot resolve -externalip address: '%s' - + Invalid amount for -paytxfee=<amount>: '%s' Invalid amount for -paytxfee=<amount>: '%s' @@ -4698,17 +4730,17 @@ Loading block index... - + Add a node to connect to and attempt to keep the connection open Add a node to connect to and attempt to keep the connection open - + Loading wallet... Loading wallet... - + Cannot downgrade wallet Cannot downgrade wallet @@ -4718,7 +4750,7 @@ Cannot write default address - + Rescanning... Rescanning... diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts new file mode 100644 index 000000000..bf912d295 --- /dev/null +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -0,0 +1,3719 @@ + + + AddressBookPage + + Right-click to edit address or label + Right-click to edit address or label + + + Create a new address + Create a new address + + + &New + &New + + + Copy the currently selected address to the system clipboard + Copy the currently selected address to the system clipboard + + + &Copy + &Copy + + + C&lose + C&lose + + + &Copy Address + &Copy Address + + + Delete the currently selected address from the list + Delete the currently selected address from the list + + + Export the data in the current tab to a file + Export the data in the current tab to a file + + + &Export + &Export + + + &Delete + &Delete + + + Choose the address to send coins to + Choose the address to send coins to + + + Choose the address to receive coins with + Choose the address to receive coins with + + + C&hoose + C&hoose + + + Sending addresses + Sending addresses + + + Receiving addresses + Receiving addresses + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + + + Copy &Label + Copy &Label + + + &Edit + &Edit + + + Export Address List + Export Address List + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + Exporting Failed + Exporting Failed + + + There was an error trying to save the address list to %1. Please try again. + There was an error trying to save the address list to %1. Please try again. + + + + AddressTableModel + + Label + Label + + + Address + Address + + + (no label) + (no label) + + + + AskPassphraseDialog + + Passphrase Dialog + Passphrase Dialog + + + Enter passphrase + Enter passphrase + + + New passphrase + New passphrase + + + Repeat new passphrase + Repeat new passphrase + + + Encrypt wallet + Encrypt wallet + + + This operation needs your wallet passphrase to unlock the wallet. + This operation needs your wallet passphrase to unlock the wallet. + + + Unlock wallet + Unlock wallet + + + This operation needs your wallet passphrase to decrypt the wallet. + This operation needs your wallet passphrase to decrypt the wallet. + + + Decrypt wallet + Decrypt wallet + + + Change passphrase + Change passphrase + + + Confirm wallet encryption + Confirm wallet encryption + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + + + Are you sure you wish to encrypt your wallet? + Are you sure you wish to encrypt your wallet? + + + Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + + + Warning: The Caps Lock key is on! + Warning: The Caps Lock key is on! + + + Wallet encrypted + Wallet encrypted + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + + + Enter the old passphrase and new passphrase to the wallet. + Enter the old passphrase and new passphrase to the wallet. + + + Wallet encryption failed + Wallet encryption failed + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + + + The supplied passphrases do not match. + The supplied passphrases do not match. + + + Wallet unlock failed + Wallet unlock failed + + + The passphrase entered for the wallet decryption was incorrect. + The passphrase entered for the wallet decryption was incorrect. + + + Wallet decryption failed + Wallet decryption failed + + + Wallet passphrase was successfully changed. + Wallet passphrase was successfully changed. + + + + BanTableModel + + IP/Netmask + IP/Netmask + + + Banned Until + Banned Until + + + + BitcoinGUI + + Sign &message... + Sign &message... + + + Synchronizing with network... + Synchronising with network... + + + &Overview + &Overview + + + Node + Node + + + Show general overview of wallet + Show general overview of wallet + + + &Transactions + &Transactions + + + Browse transaction history + Browse transaction history + + + E&xit + E&xit + + + Quit application + Quit application + + + About &Qt + About &Qt + + + Show information about Qt + Show information about Qt + + + &Options... + &Options... + + + &Encrypt Wallet... + &Encrypt Wallet... + + + &Backup Wallet... + &Backup Wallet... + + + &Change Passphrase... + &Change Passphrase... + + + &Sending addresses... + &Sending addresses... + + + &Receiving addresses... + &Receiving addresses... + + + Open &URI... + Open &URI... + + + Bitcoin Core client + Bitcoin Core client + + + Importing blocks from disk... + Importing blocks from disk... + + + Reindexing blocks on disk... + Reindexing blocks on disk... + + + Send coins to a Bitcoin address + Send coins to a Bitcoin address + + + Backup wallet to another location + Backup wallet to another location + + + Change the passphrase used for wallet encryption + Change the passphrase used for wallet encryption + + + &Debug window + &Debug window + + + Open debugging and diagnostic console + Open debugging and diagnostic console + + + &Verify message... + &Verify message... + + + Bitcoin + Bitcoin + + + Wallet + Wallet + + + &Send + &Send + + + &Receive + &Receive + + + Show information about Bitcoin Core + Show information about Bitcoin Core + + + &Show / Hide + &Show / Hide + + + Show or hide the main Window + Show or hide the main Window + + + Encrypt the private keys that belong to your wallet + Encrypt the private keys that belong to your wallet + + + Sign messages with your Bitcoin addresses to prove you own them + Sign messages with your Bitcoin addresses to prove you own them + + + Verify messages to ensure they were signed with specified Bitcoin addresses + Verify messages to ensure they were signed with specified Bitcoin addresses + + + &File + &File + + + &Settings + &Settings + + + &Help + &Help + + + Tabs toolbar + Tabs toolbar + + + Bitcoin Core + Bitcoin Core + + + Request payments (generates QR codes and bitcoin: URIs) + Request payments (generates QR codes and bitcoin: URIs) + + + &About Bitcoin Core + &About Bitcoin Core + + + Modify configuration options for Bitcoin Core + Modify configuration options for Bitcoin Core + + + Show the list of used sending addresses and labels + Show the list of used sending addresses and labels + + + Show the list of used receiving addresses and labels + Show the list of used receiving addresses and labels + + + Open a bitcoin: URI or payment request + Open a bitcoin: URI or payment request + + + &Command-line options + &Command-line options + + + Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options + Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options + + + %n active connection(s) to Bitcoin network + %n active connection to Bitcoin network%n active connections to Bitcoin network + + + No block source available... + No block source available... + + + Processed %n block(s) of transaction history. + Processed %n block of transaction history.Processed %n blocks of transaction history. + + + %n hour(s) + %n hour%n hours + + + %n day(s) + %n day%n days + + + %n week(s) + %n week%n weeks + + + %1 and %2 + %1 and %2 + + + %n year(s) + %n year%n years + + + %1 behind + %1 behind + + + Last received block was generated %1 ago. + Last received block was generated %1 ago. + + + Transactions after this will not yet be visible. + Transactions after this will not yet be visible. + + + Error + Error + + + Warning + Warning + + + Information + Information + + + Up to date + Up to date + + + Catching up... + Catching up... + + + Date: %1 + + Date: %1 + + + + Amount: %1 + + Amount: %1 + + + + Type: %1 + + Type: %1 + + + + Label: %1 + + Label: %1 + + + + Address: %1 + + Address: %1 + + + + Sent transaction + Sent transaction + + + Incoming transaction + Incoming transaction + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Wallet is <b>encrypted</b> and currently <b>locked</b> + + + + ClientModel + + Network Alert + Network Alert + + + + CoinControlDialog + + Coin Selection + Coin Selection + + + Quantity: + Quantity: + + + Bytes: + Bytes: + + + Amount: + Amount: + + + Priority: + Priority: + + + Fee: + Fee: + + + Dust: + Dust: + + + After Fee: + After Fee: + + + Change: + Change: + + + (un)select all + (un)select all + + + Tree mode + Tree mode + + + List mode + List mode + + + Amount + Amount + + + Received with label + Received with label + + + Received with address + Received with address + + + Date + Date + + + Confirmations + Confirmations + + + Confirmed + Confirmed + + + Priority + Priority + + + Copy address + Copy address + + + Copy label + Copy label + + + Copy amount + Copy amount + + + Copy transaction ID + Copy transaction ID + + + Lock unspent + Lock unspent + + + Unlock unspent + Unlock unspent + + + Copy quantity + Copy quantity + + + Copy fee + Copy fee + + + Copy after fee + Copy after fee + + + Copy bytes + Copy bytes + + + Copy priority + Copy priority + + + Copy dust + Copy dust + + + Copy change + Copy change + + + highest + highest + + + higher + higher + + + high + high + + + medium-high + medium-high + + + medium + medium + + + low-medium + low-medium + + + low + low + + + lower + lower + + + lowest + lowest + + + (%1 locked) + (%1 locked) + + + none + none + + + This label turns red if the transaction size is greater than 1000 bytes. + This label turns red if the transaction size is greater than 1000 bytes. + + + This label turns red if the priority is smaller than "medium". + This label turns red if the priority is smaller than "medium". + + + This label turns red if any recipient receives an amount smaller than %1. + This label turns red if any recipient receives an amount smaller than %1. + + + Can vary +/- %1 satoshi(s) per input. + Can vary +/- %1 satoshi(s) per input. + + + yes + yes + + + no + no + + + This means a fee of at least %1 per kB is required. + This means a fee of at least %1 per kB is required. + + + Can vary +/- 1 byte per input. + Can vary +/- 1 byte per input. + + + Transactions with higher priority are more likely to get included into a block. + Transactions with higher priority are more likely to get included into a block. + + + (no label) + (no label) + + + change from %1 (%2) + change from %1 (%2) + + + (change) + (change) + + + + EditAddressDialog + + Edit Address + Edit Address + + + &Label + &Label + + + The label associated with this address list entry + The label associated with this address list entry + + + The address associated with this address list entry. This can only be modified for sending addresses. + The address associated with this address list entry. This can only be modified for sending addresses. + + + &Address + &Address + + + New receiving address + New receiving address + + + New sending address + New sending address + + + Edit receiving address + Edit receiving address + + + Edit sending address + Edit sending address + + + The entered address "%1" is already in the address book. + The entered address "%1" is already in the address book. + + + The entered address "%1" is not a valid Bitcoin address. + The entered address "%1" is not a valid Bitcoin address. + + + Could not unlock wallet. + Could not unlock wallet. + + + New key generation failed. + New key generation failed. + + + + FreespaceChecker + + A new data directory will be created. + A new data directory will be created. + + + name + name + + + Directory already exists. Add %1 if you intend to create a new directory here. + Directory already exists. Add %1 if you intend to create a new directory here. + + + Path already exists, and is not a directory. + Path already exists, and is not a directory. + + + Cannot create data directory here. + Cannot create data directory here. + + + + HelpMessageDialog + + Bitcoin Core + Bitcoin Core + + + version + version + + + (%1-bit) + (%1-bit) + + + About Bitcoin Core + About Bitcoin Core + + + Command-line options + Command-line options + + + Usage: + Usage: + + + command-line options + command-line options + + + UI Options: + UI Options: + + + Choose data directory on startup (default: %u) + Choose data directory on startup (default: %u) + + + Set language, for example "de_DE" (default: system locale) + Set language, for example "de_DE" (default: system locale) + + + Start minimized + Start minimised + + + Set SSL root certificates for payment request (default: -system-) + Set SSL root certificates for payment request (default: -system-) + + + Show splash screen on startup (default: %u) + Show splash screen on startup (default: %u) + + + Reset all settings changes made over the GUI + Reset all settings changes made over the GUI + + + + Intro + + Welcome + Welcome + + + Welcome to Bitcoin Core. + Welcome to Bitcoin Core. + + + As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. + As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. + + + Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + + + Use the default data directory + Use the default data directory + + + Use a custom data directory: + Use a custom data directory: + + + Bitcoin Core + Bitcoin Core + + + Error: Specified data directory "%1" cannot be created. + Error: Specified data directory "%1" cannot be created. + + + Error + Error + + + %n GB of free space available + %n GB of free space available%n GB of free space available + + + (of %n GB needed) + (of %n GB needed)(of %n GB needed) + + + + OpenURIDialog + + Open URI + Open URI + + + Open payment request from URI or file + Open payment request from URI or file + + + URI: + URI: + + + Select payment request file + Select payment request file + + + Select payment request file to open + Select payment request file to open + + + + OptionsDialog + + Options + Options + + + &Main + &Main + + + Size of &database cache + Size of &database cache + + + MB + MB + + + Number of script &verification threads + Number of script &verification threads + + + Accept connections from outside + Accept connections from outside + + + Allow incoming connections + Allow incoming connections + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + + + Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu. + Minimise instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu. + + + The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. + The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. + + + Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. + Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. + + + Third party transaction URLs + Third party transaction URLs + + + Active command-line options that override above options: + Active command-line options that override above options: + + + Reset all client options to default. + Reset all client options to default. + + + &Reset Options + &Reset Options + + + &Network + &Network + + + Automatically start Bitcoin Core after logging in to the system. + Automatically start Bitcoin Core after logging in to the system. + + + &Start Bitcoin Core on system login + &Start Bitcoin Core on system login + + + (0 = auto, <0 = leave that many cores free) + (0 = auto, <0 = leave that many cores free) + + + W&allet + W&allet + + + Expert + Expert + + + Enable coin &control features + Enable coin &control features + + + If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed. + If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed. + + + &Spend unconfirmed change + &Spend unconfirmed change + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + + + Map port using &UPnP + Map port using &UPnP + + + Connect to the Bitcoin network through a SOCKS5 proxy. + Connect to the Bitcoin network through a SOCKS5 proxy. + + + &Connect through SOCKS5 proxy (default proxy): + &Connect through SOCKS5 proxy (default proxy): + + + Proxy &IP: + Proxy &IP: + + + &Port: + &Port: + + + Port of the proxy (e.g. 9050) + Port of the proxy (e.g. 9050) + + + Used for reaching peers via: + Used for reaching peers via: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + + + &Window + &Window + + + Show only a tray icon after minimizing the window. + Show on a tray icon after minimising the window. + + + &Minimize to the tray instead of the taskbar + &Minimise to the tray instead of the task bar + + + M&inimize on close + M&inimise on close + + + &Display + &Display + + + User Interface &language: + User Interface &language: + + + &Unit to show amounts in: + &Unit to show amounts in: + + + Choose the default subdivision unit to show in the interface and when sending coins. + Choose the default subdivision unit to show in the interface and when sending coins. + + + Whether to show coin control features or not. + Whether to show coin control features or not. + + + &OK + &OK + + + &Cancel + &Cancel + + + default + default + + + none + none + + + Confirm options reset + Confirm options reset + + + Client restart required to activate changes. + Client restart required to activate changes. + + + Client will be shut down. Do you want to proceed? + Client will be shut down. Do you want to proceed? + + + This change would require a client restart. + This change would require a client restart. + + + The supplied proxy address is invalid. + The supplied proxy address is invalid. + + + + OverviewPage + + Form + Form + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + The displayed information may be out of date. Your Wallet automatically synchronises with the Bitcoin Network after a connection is established, but this process has not been completed yet. + + + Watch-only: + Watch-only: + + + Available: + Available: + + + Your current spendable balance + Your current spendable balance + + + Pending: + Pending: + + + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + + + Immature: + Immature: + + + Mined balance that has not yet matured + Mined balance that has not yet matured + + + Balances + Balances + + + Total: + Total: + + + Your current total balance + Your current total balance + + + Your current balance in watch-only addresses + Your current balance in watch-only addresses + + + Spendable: + Spendable: + + + Recent transactions + Recent transactions + + + Unconfirmed transactions to watch-only addresses + Unconfirmed transactions to watch-only addresses + + + Mined balance in watch-only addresses that has not yet matured + Mined balance in watch-only addresses that has not yet matured + + + Current total balance in watch-only addresses + Current total balance in watch-only addresses + + + + PaymentServer + + URI handling + URI handling + + + Invalid payment address %1 + Invalid payment address %1 + + + Payment request rejected + Payment request rejected + + + Payment request network doesn't match client network. + Payment request network doesn't match client network. + + + Payment request is not initialized. + Payment request is not initialised. + + + Requested payment amount of %1 is too small (considered dust). + Requested payment amount of %1 is too small (considered dust). + + + Payment request error + Payment request error + + + Cannot start bitcoin: click-to-pay handler + Cannot start bitcoin: click-to-pay handler + + + Payment request fetch URL is invalid: %1 + Payment request fetch URL is invalid: %1 + + + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. + + + Payment request file handling + Payment request file handling + + + Payment request file cannot be read! This can be caused by an invalid payment request file. + Payment request file cannot be read! This can be caused by an invalid payment request file. + + + Payment request expired. + Payment request expired. + + + Unverified payment requests to custom payment scripts are unsupported. + Unverified payment requests to custom payment scripts are unsupported. + + + Invalid payment request. + Invalid payment request. + + + Refund from %1 + Refund from %1 + + + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + Payment request %1 is too large (%2 bytes, allowed %3 bytes). + + + Error communicating with %1: %2 + Error communicating with %1: %2 + + + Payment request cannot be parsed! + Payment request cannot be parsed! + + + Bad response from server %1 + Bad response from server %1 + + + Payment acknowledged + Payment acknowledged + + + Network request error + Network request error + + + + PeerTableModel + + User Agent + User Agent + + + Node/Service + Node/Service + + + Ping Time + Ping Time + + + + QObject + + Amount + Amount + + + Enter a Bitcoin address (e.g. %1) + Enter a Bitcoin address (e.g. %1) + + + %1 d + %1 d + + + %1 h + %1 h + + + %1 m + %1 m + + + %1 s + %1 s + + + None + None + + + N/A + N/A + + + %1 ms + %1 ms + + + + QRImageWidget + + &Save Image... + &Save Image... + + + &Copy Image + &Copy Image + + + Save QR Code + Save QR Code + + + PNG Image (*.png) + PNG Image (*.png) + + + + RPCConsole + + Client name + Client name + + + N/A + N/A + + + Client version + Client version + + + &Information + &Information + + + Debug window + Debug window + + + General + General + + + Using OpenSSL version + Using OpenSSL version + + + Using BerkeleyDB version + Using BerkeleyDB version + + + Startup time + Startup time + + + Network + Network + + + Name + Name + + + Number of connections + Number of connections + + + Block chain + Block chain + + + Current number of blocks + Current number of blocks + + + Memory Pool + Memory Pool + + + Current number of transactions + Current number of transactions + + + Memory usage + Memory usage + + + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. + + + Received + Received + + + Sent + Sent + + + &Peers + &Peers + + + Banned peers + Banned peers + + + Select a peer to view detailed information. + Select a peer to view detailed information. + + + Whitelisted + Whitelisted + + + Direction + Direction + + + Version + Version + + + Starting Block + Starting Block + + + Synced Headers + Synced Headers + + + Synced Blocks + Synced Blocks + + + User Agent + User Agent + + + Services + Services + + + Ban Score + Ban Score + + + Connection Time + Connection Time + + + Last Send + Last Send + + + Last Receive + Last Receive + + + Ping Time + Ping Time + + + The duration of a currently outstanding ping. + The duration of a currently outstanding ping. + + + Ping Wait + Ping Wait + + + Time Offset + Time Offset + + + Last block time + Last block time + + + &Open + &Open + + + &Console + &Console + + + &Network Traffic + &Network Traffic + + + &Clear + &Clear + + + Totals + Totals + + + In: + In: + + + Out: + Out: + + + Build date + Build date + + + Debug log file + Debug log file + + + Clear console + Clear console + + + &Disconnect Node + &Disconnect Node + + + Ban Node for + Ban Node for + + + 1 &hour + 1 &hour + + + 1 &day + 1 &day + + + 1 &week + 1 &week + + + 1 &year + 1 &year + + + &Unban Node + &Unban Node + + + Welcome to the Bitcoin Core RPC console. + Welcome to the Bitcoin Core RPC console. + + + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. + + + Type <b>help</b> for an overview of available commands. + Type <b>help</b> for an overview of available commands. + + + %1 B + %1 B + + + %1 KB + %1 KB + + + %1 MB + %1 MB + + + %1 GB + %1 GB + + + (node id: %1) + (node id: %1) + + + via %1 + via %1 + + + never + never + + + Inbound + Inbound + + + Outbound + Outbound + + + Yes + Yes + + + No + No + + + Unknown + Unknown + + + + ReceiveCoinsDialog + + &Amount: + &Amount: + + + &Label: + &Label: + + + &Message: + &Message: + + + Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before. + Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before. + + + R&euse an existing receiving address (not recommended) + R&euse an existing receiving address (not recommended) + + + An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network. + An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network. + + + An optional label to associate with the new receiving address. + An optional label to associate with the new receiving address. + + + Use this form to request payments. All fields are <b>optional</b>. + Use this form to request payments. All fields are <b>optional</b>. + + + An optional amount to request. Leave this empty or zero to not request a specific amount. + An optional amount to request. Leave this empty or zero to not request a specific amount. + + + Clear all fields of the form. + Clear all fields of the form. + + + Clear + Clear + + + Requested payments history + Requested payments history + + + &Request payment + &Request payment + + + Show the selected request (does the same as double clicking an entry) + Show the selected request (does the same as double clicking an entry) + + + Show + Show + + + Remove the selected entries from the list + Remove the selected entries from the list + + + Remove + Remove + + + Copy label + Copy label + + + Copy message + Copy message + + + Copy amount + Copy amount + + + + ReceiveRequestDialog + + QR Code + QR Code + + + Copy &URI + Copy &URI + + + Copy &Address + Copy &Address + + + &Save Image... + &Save Image... + + + Request payment to %1 + Request payment to %1 + + + Payment information + Payment information + + + URI + URI + + + Address + Address + + + Amount + Amount + + + Label + Label + + + Message + Message + + + Resulting URI too long, try to reduce the text for label / message. + Resulting URI too long, try to reduce the text for label / message. + + + Error encoding URI into QR Code. + Error encoding URI into QR Code. + + + + RecentRequestsTableModel + + Date + Date + + + Label + Label + + + Message + Message + + + Amount + Amount + + + (no label) + (no label) + + + (no message) + (no message) + + + (no amount) + (no amount) + + + + SendCoinsDialog + + Send Coins + Send Coins + + + Coin Control Features + Coin Control Features + + + Inputs... + Inputs... + + + automatically selected + automatically selected + + + Insufficient funds! + Insufficient funds! + + + Quantity: + Quantity: + + + Bytes: + Bytes: + + + Amount: + Amount: + + + Priority: + Priority: + + + Fee: + Fee: + + + After Fee: + After Fee: + + + Change: + Change: + + + If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. + If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. + + + Custom change address + Custom change address + + + Transaction Fee: + Transaction Fee: + + + Choose... + Choose... + + + collapse fee-settings + collapse fee-settings + + + per kilobyte + per kilobyte + + + If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte. + If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte. + + + Hide + Hide + + + total at least + total at least + + + Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process. + Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process. + + + (read the tooltip) + (read the tooltip) + + + Recommended: + Recommended: + + + Custom: + Custom: + + + (Smart fee not initialized yet. This usually takes a few blocks...) + (Smart fee not initialised yet. This usually takes a few blocks...) + + + Confirmation time: + Confirmation time: + + + normal + normal + + + fast + fast + + + Send as zero-fee transaction if possible + Send as zero-fee transaction if possible + + + (confirmation may take longer) + (confirmation may take longer) + + + Send to multiple recipients at once + Send to multiple recipients at once + + + Add &Recipient + Add &Recipient + + + Clear all fields of the form. + Clear all fields of the form. + + + Dust: + Dust: + + + Clear &All + Clear &All + + + Balance: + Balance: + + + Confirm the send action + Confirm the send action + + + S&end + S&end + + + Confirm send coins + Confirm send coins + + + %1 to %2 + %1 to %2 + + + Copy quantity + Copy quantity + + + Copy amount + Copy amount + + + Copy fee + Copy fee + + + Copy after fee + Copy after fee + + + Copy bytes + Copy bytes + + + Copy priority + Copy priority + + + Copy change + Copy change + + + Total Amount %1 + Total Amount %1 + + + or + or + + + The amount to pay must be larger than 0. + The amount to pay must be larger than 0. + + + The amount exceeds your balance. + The amount exceeds your balance. + + + The total exceeds your balance when the %1 transaction fee is included. + The total exceeds your balance when the %1 transaction fee is included. + + + Transaction creation failed! + Transaction creation failed! + + + The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + + + A fee higher than %1 is considered an absurdly high fee. + A fee higher than %1 is considered an absurdly high fee. + + + Payment request expired. + Payment request expired. + + + Pay only the required fee of %1 + Pay only the required fee of %1 + + + Estimated to begin confirmation within %n block(s). + Estimated to begin confirmation within %n block.Estimated to begin confirmation within %n blocks. + + + The recipient address is not valid. Please recheck. + The recipient address is not valid. Please recheck. + + + Duplicate address found: addresses should only be used once each. + Duplicate address found: addresses should only be used once each. + + + Warning: Invalid Bitcoin address + Warning: Invalid Bitcoin address + + + (no label) + (no label) + + + Warning: Unknown change address + Warning: Unknown change address + + + Copy dust + Copy dust + + + Are you sure you want to send? + Are you sure you want to send? + + + added as transaction fee + added as transaction fee + + + + SendCoinsEntry + + A&mount: + A&mount: + + + Pay &To: + Pay &To: + + + Enter a label for this address to add it to your address book + Enter a label for this address to add it to your address book + + + &Label: + &Label: + + + Choose previously used address + Choose previously used address + + + This is a normal payment. + This is a normal payment. + + + The Bitcoin address to send the payment to + The Bitcoin address to send the payment to + + + Alt+A + Alt+A + + + Paste address from clipboard + Paste address from clipboard + + + Alt+P + Alt+P + + + Remove this entry + Remove this entry + + + 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. + 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. + + + S&ubtract fee from amount + S&ubtract fee from amount + + + Message: + Message: + + + This is an unauthenticated payment request. + This is an unauthenticated payment request. + + + This is an authenticated payment request. + This is an authenticated payment request. + + + Enter a label for this address to add it to the list of used addresses + Enter a label for this address to add it to the list of used addresses + + + A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network. + A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network. + + + Pay To: + Pay To: + + + Memo: + Memo: + + + + ShutdownWindow + + Bitcoin Core is shutting down... + Bitcoin Core is shutting down... + + + Do not shut down the computer until this window disappears. + Do not shut down the computer until this window disappears. + + + + SignVerifyMessageDialog + + Signatures - Sign / Verify a Message + Signatures - Sign / Verify a Message + + + &Sign Message + &Sign Message + + + You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + + + The Bitcoin address to sign the message with + The Bitcoin address to sign the message with + + + Choose previously used address + Choose previously used address + + + Alt+A + Alt+A + + + Paste address from clipboard + Paste address from clipboard + + + Alt+P + Alt+P + + + Enter the message you want to sign here + Enter the message you want to sign here + + + Signature + Signature + + + Copy the current signature to the system clipboard + Copy the current signature to the system clipboard + + + Sign the message to prove you own this Bitcoin address + Sign the message to prove you own this Bitcoin address + + + Sign &Message + Sign &Message + + + Reset all sign message fields + Reset all sign message fields + + + Clear &All + Clear &All + + + &Verify Message + &Verify Message + + + Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction! + Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction! + + + The Bitcoin address the message was signed with + The Bitcoin address the message was signed with + + + Verify the message to ensure it was signed with the specified Bitcoin address + Verify the message to ensure it was signed with the specified Bitcoin address + + + Verify &Message + Verify &Message + + + Reset all verify message fields + Reset all verify message fields + + + Click "Sign Message" to generate signature + Click "Sign Message" to generate signature + + + The entered address is invalid. + The entered address is invalid. + + + Please check the address and try again. + Please check the address and try again. + + + The entered address does not refer to a key. + The entered address does not refer to a key. + + + Wallet unlock was cancelled. + Wallet unlock was cancelled. + + + Private key for the entered address is not available. + Private key for the entered address is not available. + + + Message signing failed. + Message signing failed. + + + Message signed. + Message signed. + + + The signature could not be decoded. + The signature could not be decoded. + + + Please check the signature and try again. + Please check the signature and try again. + + + The signature did not match the message digest. + The signature did not match the message digest. + + + Message verification failed. + Message verification failed. + + + Message verified. + Message verified. + + + + SplashScreen + + Bitcoin Core + Bitcoin Core + + + The Bitcoin Core developers + The Bitcoin Core developers + + + [testnet] + [testnet] + + + + TrafficGraphWidget + + KB/s + KB/s + + + + TransactionDesc + + Open until %1 + Open until %1 + + + conflicted + conflicted + + + %1/offline + %1/offline + + + %1/unconfirmed + %1/unconfirmed + + + %1 confirmations + %1 confirmations + + + Status + Status + + + , broadcast through %n node(s) + , broadcast through %n node, broadcast through %n nodes + + + Date + Date + + + Source + Source + + + Generated + Generated + + + From + From + + + To + To + + + own address + own address + + + watch-only + watch-only + + + label + label + + + Credit + Credit + + + matures in %n more block(s) + matures in %n more blockmatures in %n more blocks + + + not accepted + not accepted + + + Debit + Debit + + + Total debit + Total debit + + + Total credit + Total credit + + + Transaction fee + Transaction fee + + + Net amount + Net amount + + + Message + Message + + + Comment + Comment + + + Transaction ID + Transaction ID + + + Merchant + Merchant + + + Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. + Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. + + + Debug information + Debug information + + + Transaction + Transaction + + + Inputs + Inputs + + + Amount + Amount + + + true + true + + + false + false + + + , has not been successfully broadcast yet + , has not been successfully broadcast yet + + + Open for %n more block(s) + Open for %n more blockOpen for %n more blocks + + + unknown + unknown + + + + TransactionDescDialog + + Transaction details + Transaction details + + + This pane shows a detailed description of the transaction + This pane shows a detailed description of the transaction + + + + TransactionTableModel + + Date + Date + + + Type + Type + + + Immature (%1 confirmations, will be available after %2) + Immature (%1 confirmations, will be available after %2) + + + Open for %n more block(s) + Open for %n more blockOpen for %n more blocks + + + Open until %1 + Open until %1 + + + Confirmed (%1 confirmations) + Confirmed (%1 confirmations) + + + This block was not received by any other nodes and will probably not be accepted! + This block was not received by any other nodes and will probably not be accepted! + + + Generated but not accepted + Generated but not accepted + + + Offline + Offline + + + Label + Label + + + Unconfirmed + Unconfirmed + + + Confirming (%1 of %2 recommended confirmations) + Confirming (%1 of %2 recommended confirmations) + + + Conflicted + Conflicted + + + Received with + Received with + + + Received from + Received from + + + Sent to + Sent to + + + Payment to yourself + Payment to yourself + + + Mined + Mined + + + watch-only + watch-only + + + (n/a) + (n/a) + + + Transaction status. Hover over this field to show number of confirmations. + Transaction status. Hover over this field to show number of confirmations. + + + Date and time that the transaction was received. + Date and time that the transaction was received. + + + Type of transaction. + Type of transaction. + + + Whether or not a watch-only address is involved in this transaction. + Whether or not a watch-only address is involved in this transaction. + + + User-defined intent/purpose of the transaction. + User-defined intent/purpose of the transaction. + + + Amount removed from or added to balance. + Amount removed from or added to balance. + + + + TransactionView + + All + All + + + Today + Today + + + This week + This week + + + This month + This month + + + Last month + Last month + + + This year + This year + + + Range... + Range... + + + Received with + Received with + + + Sent to + Sent to + + + To yourself + To yourself + + + Mined + Mined + + + Other + Other + + + Enter address or label to search + Enter address or label to search + + + Min amount + Min amount + + + Copy address + Copy address + + + Copy label + Copy label + + + Copy amount + Copy amount + + + Copy transaction ID + Copy transaction ID + + + Copy raw transaction + Copy raw transaction + + + Edit label + Edit label + + + Show transaction details + Show transaction details + + + Export Transaction History + Export Transaction History + + + Watch-only + Watch-only + + + Exporting Failed + Exporting Failed + + + There was an error trying to save the transaction history to %1. + There was an error trying to save the transaction history to %1. + + + Exporting Successful + Exporting Successful + + + The transaction history was successfully saved to %1. + The transaction history was successfully saved to %1. + + + Comma separated file (*.csv) + Comma separated file (*.csv) + + + Confirmed + Confirmed + + + Date + Date + + + Type + Type + + + Label + Label + + + Address + Address + + + ID + ID + + + Range: + Range: + + + to + to + + + + UnitDisplayStatusBarControl + + Unit to show amounts in. Click to select another unit. + Unit to show amounts in. Click to select another unit. + + + + WalletFrame + + No wallet has been loaded. + No wallet has been loaded. + + + + WalletModel + + Send Coins + Send Coins + + + + WalletView + + &Export + &Export + + + Export the data in the current tab to a file + Export the data in the current tab to a file + + + Backup Wallet + Backup Wallet + + + Wallet Data (*.dat) + Wallet Data (*.dat) + + + Backup Failed + Backup Failed + + + There was an error trying to save the wallet data to %1. + There was an error trying to save the wallet data to %1. + + + The wallet data was successfully saved to %1. + The wallet data was successfully saved to %1. + + + Backup Successful + Backup Successful + + + + bitcoin-core + + Options: + Options: + + + Specify data directory + Specify data directory + + + Connect to a node to retrieve peer addresses, and disconnect + Connect to a node to retrieve peer addresses, and disconnect + + + Specify your own public address + Specify your own public address + + + Accept command line and JSON-RPC commands + Accept command line and JSON-RPC commands + + + If <category> is not supplied or if <category> = 1, output all debugging information. + If <category> is not supplied or if <category> = 1, output all debugging information. + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Prune configured below the minimum of %d MiB. Please use a higher number. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + + + Error: A fatal internal error occurred, see debug.log for details + Error: A fatal internal error occurred, see debug.log for details + + + Fee (in %s/kB) to add to transactions you send (default: %s) + Fee (in %s/kB) to add to transactions you send (default: %s) + + + Pruning blockstore... + Pruning blockstore... + + + Run in the background as a daemon and accept commands + Run in the background as a daemon and accept commands + + + Unable to start HTTP server. See debug log for details. + Unable to start HTTP server. See debug log for details. + + + Accept connections from outside (default: 1 if no -proxy or -connect) + Accept connections from outside (default: 1 if no -proxy or -connect) + + + Bind to given address and always listen on it. Use [host]:port notation for IPv6 + Bind to given address and always listen on it. Use [host]:port notation for IPv6 + + + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup + + + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + + + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) + + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) + + + The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct + The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct + + + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications + + + Unable to bind to %s on this computer. Bitcoin Core is probably already running. + Unable to bind to %s on this computer. Bitcoin Core is probably already running. + + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + + + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) + + + WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) + WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) + + + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. + + + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. + + + 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. + 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. + + + Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. + Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. + + + -maxmempool must be at least %d MB + -maxmempool must be at least %d MB + + + <category> can be: + <category> can be: + + + Block creation options: + Block creation options: + + + Connect only to the specified node(s) + Connect only to the specified node(s) + + + Connection options: + Connection options: + + + Corrupted block database detected + Corrupted block database detected + + + Debugging/Testing options: + Debugging/Testing options: + + + Do not load the wallet and disable wallet RPC calls + Do not load the wallet and disable wallet RPC calls + + + Do you want to rebuild the block database now? + Do you want to rebuild the block database now? + + + Enable publish hash block in <address> + Enable publish hash block in <address> + + + Enable publish hash transaction in <address> + Enable publish hash transaction in <address> + + + Enable publish raw block in <address> + Enable publish raw block in <address> + + + Enable publish raw transaction in <address> + Enable publish raw transaction in <address> + + + Error initializing block database + Error initialising block database + + + Error initializing wallet database environment %s! + Error initialising wallet database environment %s! + + + Error loading block database + Error loading block database + + + Error opening block database + Error opening block database + + + Error: Disk space is low! + Error: Disk space is low! + + + Failed to listen on any port. Use -listen=0 if you want this. + Failed to listen on any port. Use -listen=0 if you want this. + + + Importing... + Importing... + + + Incorrect or no genesis block found. Wrong datadir for network? + Incorrect or no genesis block found. Wrong datadir for network? + + + Invalid -onion address: '%s' + Invalid -onion address: '%s' + + + Keep the transaction memory pool below <n> megabytes (default: %u) + Keep the transaction memory pool below <n> megabytes (default: %u) + + + Not enough file descriptors available. + Not enough file descriptors available. + + + Only connect to nodes in network <net> (ipv4, ipv6 or onion) + Only connect to nodes in network <net> (ipv4, ipv6 or onion) + + + Prune cannot be configured with a negative value. + Prune cannot be configured with a negative value. + + + Prune mode is incompatible with -txindex. + Prune mode is incompatible with -txindex. + + + Set database cache size in megabytes (%d to %d, default: %d) + Set database cache size in megabytes (%d to %d, default: %d) + + + Set maximum block size in bytes (default: %d) + Set maximum block size in bytes (default: %d) + + + Specify wallet file (within data directory) + Specify wallet file (within data directory) + + + Unsupported argument -benchmark ignored, use -debug=bench. + Unsupported argument -benchmark ignored, use -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Unsupported argument -debugnet ignored, use -debug=net. + + + Unsupported argument -tor found, use -onion. + Unsupported argument -tor found, use -onion. + + + Use UPnP to map the listening port (default: %u) + Use UPnP to map the listening port (default: %u) + + + User Agent comment (%s) contains unsafe characters. + User Agent comment (%s) contains unsafe characters. + + + Verifying blocks... + Verifying blocks... + + + Verifying wallet... + Verifying wallet... + + + Wallet %s resides outside data directory %s + Wallet %s resides outside data directory %s + + + Wallet options: + Wallet options: + + + Warning: This version is obsolete; upgrade required! + Warning: This version is obsolete; upgrade required! + + + You need to rebuild the database using -reindex to change -txindex + You need to rebuild the database using -reindex to change -txindex + + + 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 + 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 + + + Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 + Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 + + + 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) + 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) + + + Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. + Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. + + + Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) + Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) + + + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + + + Error: Listening for incoming connections failed (listen returned error %s) + Error: Listening for incoming connections failed (listen returned error %s) + + + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) + + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + + + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + + + Maximum size of data in data carrier transactions we relay and mine (default: %u) + Maximum size of data in data carrier transactions we relay and mine (default: %u) + + + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect) + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect) + + + Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) + Randomise credentials for every proxy connection. This enables Tor stream isolation (default: %u) + + + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) + + + Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) + Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) + + + The transaction amount is too small to send after the fee has been deducted + The transaction amount is too small to send after the fee has been deducted + + + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + + + 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 + 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 + + + You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain + You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain + + + (default: %u) + (default: %u) + + + Accept public REST requests (default: %u) + Accept public REST requests (default: %u) + + + Activating best chain... + Activating best chain... + + + Always relay transactions received from whitelisted peers (default: %d) + Always relay transactions received from whitelisted peers (default: %d) + + + Attempt to recover private keys from a corrupt wallet.dat on startup + Attempt to recover private keys from a corrupt wallet.dat on startup + + + Automatically create Tor hidden service (default: %d) + Automatically create Tor hidden service (default: %d) + + + Cannot resolve -whitebind address: '%s' + Cannot resolve -whitebind address: '%s' + + + Connect through SOCKS5 proxy + Connect through SOCKS5 proxy + + + Copyright (C) 2009-%i The Bitcoin Core Developers + Copyright (C) 2009-%i The Bitcoin Core Developers + + + Error loading wallet.dat: Wallet requires newer version of Bitcoin Core + Error loading wallet.dat: Wallet requires newer version of Bitcoin Core + + + Error reading from database, shutting down. + Error reading from database, shutting down. + + + Imports blocks from external blk000??.dat file on startup + Imports blocks from external blk000??.dat file on startup + + + Information + Information + + + Initialization sanity check failed. Bitcoin Core is shutting down. + Initialisation sanity check failed. Bitcoin Core is shutting down. + + + Invalid amount for -maxtxfee=<amount>: '%s' + Invalid amount for -maxtxfee=<amount>: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + Invalid amount for -mintxfee=<amount>: '%s' + + + Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) + Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) + + + Invalid netmask specified in -whitelist: '%s' + Invalid netmask specified in -whitelist: '%s' + + + Keep at most <n> unconnectable transactions in memory (default: %u) + Keep at most <n> unconnectable transactions in memory (default: %u) + + + Need to specify a port with -whitebind: '%s' + Need to specify a port with -whitebind: '%s' + + + Node relay options: + Node relay options: + + + RPC server options: + RPC server options: + + + Rebuild block chain index from current blk000??.dat files on startup + Rebuild block chain index from current blk000??.dat files on startup + + + Receive and display P2P network alerts (default: %u) + Receive and display P2P network alerts (default: %u) + + + Reducing -maxconnections from %d to %d, because of system limitations. + Reducing -maxconnections from %d to %d, because of system limitations. + + + Rescan the block chain for missing wallet transactions on startup + Rescan the block chain for missing wallet transactions on startup + + + Send trace/debug info to console instead of debug.log file + Send trace/debug info to console instead of debug.log file + + + Send transactions as zero-fee transactions if possible (default: %u) + Send transactions as zero-fee transactions if possible (default: %u) + + + Show all debugging options (usage: --help -help-debug) + Show all debugging options (usage: --help -help-debug) + + + Shrink debug.log file on client startup (default: 1 when no -debug) + Shrink debug.log file on client startup (default: 1 when no -debug) + + + Signing transaction failed + Signing transaction failed + + + The transaction amount is too small to pay the fee + The transaction amount is too small to pay the fee + + + This is experimental software. + This is experimental software. + + + Tor control port password (default: empty) + Tor control port password (default: empty) + + + Tor control port to use if onion listening enabled (default: %s) + Tor control port to use if onion listening enabled (default: %s) + + + Transaction amount too small + Transaction amount too small + + + Transaction amounts must be positive + Transaction amounts must be positive + + + Transaction too large for fee policy + Transaction too large for fee policy + + + Transaction too large + Transaction too large + + + Unable to bind to %s on this computer (bind returned error %s) + Unable to bind to %s on this computer (bind returned error %s) + + + Upgrade wallet to latest format on startup + Upgrade wallet to latest format on startup + + + Username for JSON-RPC connections + Username for JSON-RPC connections + + + Wallet needed to be rewritten: restart Bitcoin Core to complete + Wallet needed to be rewritten: restart Bitcoin Core to complete + + + Warning + Warning + + + Whether to operate in a blocks only mode (default: %u) + Whether to operate in a blocks only mode (default: %u) + + + Zapping all transactions from wallet... + Zapping all transactions from wallet... + + + ZeroMQ notification options: + ZeroMQ notification options: + + + wallet.dat corrupt, salvage failed + wallet.dat corrupt, salvage failed + + + Password for JSON-RPC connections + Password for JSON-RPC connections + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Execute command when the best block changes (%s in cmd is replaced by block hash) + + + This help message + This help message + + + Allow DNS lookups for -addnode, -seednode and -connect + Allow DNS lookups for -addnode, -seednode and -connect + + + Loading addresses... + Loading addresses... + + + Error loading wallet.dat: Wallet corrupted + Error loading wallet.dat: Wallet corrupted + + + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Do not keep transactions in the mempool longer than <n> hours (default: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + + + How thorough the block verification of -checkblocks is (0-4, default: %u) + How thorough the block verification of -checkblocks is (0-4, default: %u) + + + Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) + Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) + + + Number of seconds to keep misbehaving peers from reconnecting (default: %u) + Number of seconds to keep misbehaving peers from reconnecting (default: %u) + + + Output debugging information (default: %u, supplying <category> is optional) + Output debugging information (default: %u, supplying <category> is optional) + + + Support filtering of blocks and transaction with bloom filters (default: %u) + Support filtering of blocks and transaction with bloom filters (default: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + + + (default: %s) + (default: %s) + + + Always query for peer addresses via DNS lookup (default: %u) + Always query for peer addresses via DNS lookup (default: %u) + + + Error loading wallet.dat + Error loading wallet.dat + + + Generate coins (default: %u) + Generate coins (default: %u) + + + How many blocks to check at startup (default: %u, 0 = all) + How many blocks to check at startup (default: %u, 0 = all) + + + Include IP addresses in debug output (default: %u) + Include IP addresses in debug output (default: %u) + + + Invalid -proxy address: '%s' + Invalid -proxy address: '%s' + + + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) + + + Listen for connections on <port> (default: %u or testnet: %u) + Listen for connections on <port> (default: %u or testnet: %u) + + + Maintain at most <n> connections to peers (default: %u) + Maintain at most <n> connections to peers (default: %u) + + + Make the wallet broadcast transactions + Make the wallet broadcast transactions + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) + + + Maximum per-connection send buffer, <n>*1000 bytes (default: %u) + Maximum per-connection send buffer, <n>*1000 bytes (default: %u) + + + Prepend debug output with timestamp (default: %u) + Prepend debug output with timestamp (default: %u) + + + Relay and mine data carrier transactions (default: %u) + Relay and mine data carrier transactions (default: %u) + + + Relay non-P2SH multisig (default: %u) + Relay non-P2SH multisig (default: %u) + + + Set key pool size to <n> (default: %u) + Set key pool size to <n> (default: %u) + + + Set minimum block size in bytes (default: %u) + Set minimum block size in bytes (default: %u) + + + Set the number of threads to service RPC calls (default: %d) + Set the number of threads to service RPC calls (default: %d) + + + Specify configuration file (default: %s) + Specify configuration file (default: %s) + + + Specify connection timeout in milliseconds (minimum: 1, default: %d) + Specify connection timeout in milliseconds (minimum: 1, default: %d) + + + Specify pid file (default: %s) + Specify pid file (default: %s) + + + Spend unconfirmed change when sending transactions (default: %u) + Spend unconfirmed change when sending transactions (default: %u) + + + Threshold for disconnecting misbehaving peers (default: %u) + Threshold for disconnecting misbehaving peers (default: %u) + + + Unknown network specified in -onlynet: '%s' + Unknown network specified in -onlynet: '%s' + + + Cannot resolve -bind address: '%s' + Cannot resolve -bind address: '%s' + + + Cannot resolve -externalip address: '%s' + Cannot resolve -externalip address: '%s' + + + Invalid amount for -paytxfee=<amount>: '%s' + Invalid amount for -paytxfee=<amount>: '%s' + + + Insufficient funds + Insufficient funds + + + Loading block index... + Loading block index... + + + Add a node to connect to and attempt to keep the connection open + Add a node to connect to and attempt to keep the connection open + + + Loading wallet... + Loading wallet... + + + Cannot downgrade wallet + Cannot downgrade wallet + + + Cannot write default address + Cannot write default address + + + Rescanning... + Rescanning... + + + Done loading + Done loading + + + Error + Error + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_eo.ts b/src/qt/locale/bitcoin_eo.ts index 4bd64f68d..ab8dd65f8 100644 --- a/src/qt/locale/bitcoin_eo.ts +++ b/src/qt/locale/bitcoin_eo.ts @@ -409,10 +409,22 @@ No block source available... Neniu fonto de blokoj trovebla... + + %n day(s) + %n tago%n tagoj + + + %n week(s) + %n semajno%n semajnoj + %1 and %2 %1 kaj %2 + + %n year(s) + %n jaro%n jaroj + %1 behind mankas %1 @@ -445,6 +457,30 @@ Catching up... Ĝisdatigante... + + Date: %1 + + Dato: %1 + + + + Amount: %1 + + Sumo: %1 + + + + Type: %1 + + Tipo: %1 + + + + Label: %1 + + Etikedo: %1 + + Sent transaction Sendita transakcio @@ -776,7 +812,7 @@ command-line options komandliniaj agordaĵoj - + Intro @@ -853,6 +889,14 @@ MB MB + + Accept connections from outside + Akcepti konektojn el ekstere + + + Allow incoming connections + Permesi envenantajn konektojn + Reset all client options to default. Reagordi ĉion al defaŭlataj valoroj. @@ -865,6 +909,10 @@ &Network &Reto + + W&allet + Monujo + Expert Fakulo @@ -889,6 +937,14 @@ Port of the proxy (e.g. 9050) la pordo de la prokurilo (ekz. 9050) + + IPv4 + IPv4 + + + IPv6 + IPv6 + &Window &Fenestro @@ -976,6 +1032,10 @@ Mined balance that has not yet matured Minita saldo, kiu ankoraŭ ne maturiĝis + + Balances + Saldoj + Total: Totalo: @@ -984,6 +1044,14 @@ Your current total balance via aktuala totala saldo + + Spendable: + Elspezebla: + + + Recent transactions + Lastaj transakcioj + PaymentServer @@ -1045,6 +1113,10 @@ %1 m %1 m + + None + Neniu + N/A neaplikebla @@ -1123,6 +1195,22 @@ Current number of blocks Aktuala nombro de blokoj + + Received + Ricevita + + + Sent + Sendita + + + Version + Versio + + + Services + Servoj + Last block time Horo de la lasta bloko @@ -1375,6 +1463,10 @@ Change: Restmono: + + Transaction Fee: + Krompago: + Send to multiple recipients at once Sendi samtempe al pluraj ricevantoj @@ -2210,13 +2302,17 @@ Plenumi komandon kiam rilata alerto riceviĝas, aŭ kiam ni vidas tre longan forkon (%s en cms anstataŭiĝas per mesaĝo) - Choose data directory on startup (default: 0) - Elekti dosierujon por datumoj dum lanĉo (defaŭlte: 0) + Cannot resolve -whitebind address: '%s' + Ne eblas trovi la adreson -whitebind: '%s' Information Informoj + + Invalid amount for -maxtxfee=<amount>: '%s' + Nevalida sumo por -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Nevalida sumo por -minrelaytxfee=<amount>: '%s' @@ -2229,14 +2325,6 @@ Send trace/debug info to console instead of debug.log file Sendi spurajn/sencimigajn informojn al la konzolo anstataŭ al dosiero debug.log - - Set language, for example "de_DE" (default: system locale) - Agordi lingvon, ekzemple "de_DE" (defaŭlte: tiu de la sistemo) - - - Show splash screen on startup (default: 1) - Montri salutŝildon dum lanĉo (defaŭlte: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Malpligrandigi la sencimigan protokol-dosieron kiam kliento lanĉiĝas (defaŭlte: 1 kiam mankas -debug) @@ -2245,10 +2333,6 @@ Signing transaction failed Subskriba transakcio fiaskis - - Start minimized - Lanĉiĝi plejete - This is experimental software. ĝi estas eksperimenta programo diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index ec8261173..936074210 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -23,7 +23,7 @@ C&lose - &Cerrar + C&errar &Copy Address @@ -55,7 +55,7 @@ C&hoose - &Escoger + E&scoger Sending addresses @@ -93,7 +93,11 @@ Exporting Failed Fallo al exportar - + + There was an error trying to save the address list to %1. Please try again. + Hubo un error al tratar de guardar en la lista de direcciones a %1 . Por favor, vuelve a intentarlo . + + AddressTableModel @@ -259,7 +263,7 @@ E&xit - &Salir + S&alir Quit application @@ -878,7 +882,23 @@ command-line options opciones de la consola de comandos - + + Choose data directory on startup (default: %u) + Elegir directorio de datos al iniciar (predeterminado: %u) + + + Set language, for example "de_DE" (default: system locale) + Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema) + + + Start minimized + Arrancar minimizado + + + Set SSL root certificates for payment request (default: -system-) + Establecer los certificados raíz SSL para solicitudes de pago (predeterminado: -system-) + + Intro @@ -1087,6 +1107,10 @@ Tor Tor + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Usar distintos proxys SOCKS5 para comunicarse vía Tor de forma anónima: + &Window &Ventana @@ -2021,6 +2045,10 @@ Copy change Copiar Cambio + + Total Amount %1 + Monto Total %1 + or o @@ -2045,6 +2073,10 @@ The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. ¡La transacción fue rechazada! Esto puede haber ocurrido si alguno de los bitcoins de su monedero ya estaba gastado o si ha usado una copia de wallet.dat y los bitcoins estaban gastados en la copia pero no se habían marcado como gastados aqui. + + A fee higher than %1 is considered an absurdly high fee. + Una comisión mayor al %1 se considera demasiado alta. + Payment request expired. Solicitud de pago caducada. @@ -2854,6 +2886,10 @@ Ejecutar en segundo plano como daemon y aceptar comandos + + Unable to start HTTP server. See debug log for details. + No se ha podido comenzar el servidor HTTP. Ver debug log para detalles. + Accept connections from outside (default: 1 if no -proxy or -connect) Aceptar conexiones desde el exterior (predeterminado: 1 si no -proxy o -connect) @@ -2911,8 +2947,8 @@ Poner en lista blanca a los equipos que se conecten desde la máscara de subred o dirección IP especificada. Se puede especificar múltiples veces. - (default: 1) - (predeterminado: 1) + -maxmempool must be at least %d MB + -maxmempool debe ser por lo menos de %d MB <category> can be: @@ -3074,6 +3110,10 @@ If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Si el pago de comisión no está establecido, incluir la cuota suficiente para que las transacciones comiencen la confirmación en una media de n bloques ( por defecto :%u) + + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + Cantidad no válida para -maxtxfee=<amount>: '%s' (debe ser por lo menos la cuota de comisión mínima de %s para prevenir transacciones atascadas) + Maximum size of data in data carrier transactions we relay and mine (default: %u) El tamaño máximo de los datos en las operaciones de transporte de datos que transmitimos y el mio (default: %u) @@ -3127,12 +3167,12 @@ Intento de recuperar claves privadas de un wallet.dat corrupto - Cannot resolve -whitebind address: '%s' - No se puede resolver -whitebind address: '%s' + Automatically create Tor hidden service (default: %d) + Automáticamente crea el servicio Tor oculto (por defecto: %d) - Choose data directory on startup (default: 0) - Elegir directorio de datos al iniciar (predeterminado: 0) + Cannot resolve -whitebind address: '%s' + No se puede resolver -whitebind address: '%s' Connect through SOCKS5 proxy @@ -3218,22 +3258,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Mandar transacciones como comisión-cero si es posible (por defecto: %u) - - Set SSL root certificates for payment request (default: -system-) - Establecer los certificados raíz SSL para solicitudes de pago (predeterminado: -system-) - - - Set language, for example "de_DE" (default: system locale) - Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema) - Show all debugging options (usage: --help -help-debug) Muestra todas las opciones de depuración (uso: --help -help-debug) - - Show splash screen on startup (default: 1) - Mostrar pantalla de bienvenida en el inicio (predeterminado: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Reducir el archivo debug.log al iniciar el cliente (predeterminado: 1 sin -debug) @@ -3242,10 +3270,6 @@ Signing transaction failed Transacción falló - - Start minimized - Arrancar minimizado - The transaction amount is too small to pay the fee Cantidad de la transacción demasiado pequeña para pagar la comisión @@ -3270,10 +3294,6 @@ Transaction too large Transacción demasiado grande - - UI Options: - Opciones de interfaz de usuario - Unable to bind to %s on this computer (bind returned error %s) No es posible conectar con %s en este sistema (bind ha dado el error %s) diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index df17411ab..e6d48a29f 100644 --- a/src/qt/locale/bitcoin_es_CL.ts +++ b/src/qt/locale/bitcoin_es_CL.ts @@ -301,6 +301,10 @@ Bitcoin Core bitcoin core + + %1 and %2 + %1 y %2 + Error Error @@ -351,6 +355,10 @@ Amount: Cantidad: + + Priority: + prioridad: + Amount Cantidad @@ -505,6 +513,10 @@ &Network &Red + + W&allet + Cartera + Expert experto @@ -636,6 +648,10 @@ &Information &Información + + Debug window + Ventana Debug + General General @@ -684,6 +700,10 @@ ReceiveCoinsDialog + + &Amount: + Cantidad: + &Label: &Etiqueta: @@ -761,10 +781,22 @@ Send Coins Enviar monedas + + Insufficient funds! + Fondos insuficientes + Amount: Cantidad: + + Priority: + prioridad: + + + Transaction Fee: + Comisión transacción: + Send to multiple recipients at once Enviar a múltiples destinatarios @@ -848,6 +880,10 @@ Message: Mensaje: + + Pay To: + Pagar a: + ShutdownWindow @@ -902,6 +938,10 @@ Click "Sign Message" to generate signature Click en "Firmar Mensage" para conseguir firma + + The entered address is invalid. + La dirección introducida no es una valida. + Please check the address and try again. Por favor, revise la dirección Bitcoin e inténtelo denuevo @@ -1309,13 +1349,20 @@ Información - Send trace/debug info to console instead of debug.log file - Enviar informacion de seguimiento a la consola en vez del archivo debug.log + Invalid amount for -maxtxfee=<amount>: '%s' + Cantidad inválida para -maxtxfee=<amount>: '%s' - Start minimized - Arranca minimizado - + Invalid amount for -minrelaytxfee=<amount>: '%s' + Cantidad inválida para -minrelaytxfee=<amount>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + Cantidad inválida para -mintxfee=<amount>: '%s' + + + Send trace/debug info to console instead of debug.log file + Enviar informacion de seguimiento a la consola en vez del archivo debug.log Username for JSON-RPC connections diff --git a/src/qt/locale/bitcoin_es_DO.ts b/src/qt/locale/bitcoin_es_DO.ts index c67d642de..0463c0f6e 100644 --- a/src/qt/locale/bitcoin_es_DO.ts +++ b/src/qt/locale/bitcoin_es_DO.ts @@ -740,7 +740,7 @@ command-line options opciones de la línea de órdenes - + Intro @@ -829,6 +829,10 @@ &Network &Red + + W&allet + Monedero + Expert Experto @@ -1367,6 +1371,10 @@ Custom change address Dirección propia + + Transaction Fee: + Comisión de transacción: + Send to multiple recipients at once Enviar a múltiples destinatarios de una vez @@ -1518,6 +1526,10 @@ Remove this entry Eliminar esta transacción + + Message: + Mensaje: + Enter a label for this address to add it to the list of used addresses Introduce una etiqueta para esta dirección para añadirla a la lista de direcciones utilizadas @@ -2221,13 +2233,17 @@ Establecer tamaño máximo de las transacciones de alta prioridad/comisión baja en bytes (por defecto: %d) - Choose data directory on startup (default: 0) - Elegir directorio de datos al iniciar (predeterminado: 0) + Cannot resolve -whitebind address: '%s' + No se puede resolver la dirección de -whitebind: '%s' Information Información + + Invalid amount for -maxtxfee=<amount>: '%s' + Inválido por el monto -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Inválido por el monto -minrelaytxfee=<amount>: '%s' @@ -2244,18 +2260,10 @@ Send trace/debug info to console instead of debug.log file Enviar información de trazas/depuración a la consola en lugar de al archivo debug.log - - Set language, for example "de_DE" (default: system locale) - Establecer el idioma, por ejemplo, "es_ES" (predeterminado: configuración regional del sistema) - Show all debugging options (usage: --help -help-debug) Mostrar todas las opciones de depuración (uso: --help -help-debug) - - Show splash screen on startup (default: 1) - Mostrar pantalla de bienvenida en el inicio (predeterminado: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Reducir el archivo debug.log al iniciar el cliente (predeterminado: 1 sin -debug) @@ -2264,10 +2272,6 @@ Signing transaction failed Transacción falló - - Start minimized - Arrancar minimizado - Transaction amount too small Monto de la transacción muy pequeño diff --git a/src/qt/locale/bitcoin_es_ES.ts b/src/qt/locale/bitcoin_es_ES.ts new file mode 100644 index 000000000..bdbfed4ec --- /dev/null +++ b/src/qt/locale/bitcoin_es_ES.ts @@ -0,0 +1,481 @@ + + + AddressBookPage + + Right-click to edit address or label + Haz clic derecho para editar la dirección o la etiqueta + + + Create a new address + Crea una nueva direccióon + + + &New + &Nuevo + + + Copy the currently selected address to the system clipboard + Copia la direccón seleccionada al portapapeles del sistema + + + &Copy + &Copiar + + + C&lose + C&errar + + + &Copy Address + &Copiar Direccón + + + Delete the currently selected address from the list + Elimina la dirección seleccionada de la lista + + + Export the data in the current tab to a file + Exporta los datos de la pestaña actual a un archivo + + + &Export + &Exportar + + + &Delete + &Eliminar + + + Choose the address to send coins to + Elige la dirección a la que enviar las monedas + + + Choose the address to receive coins with + Elige la direccón con la que recibir monedas + + + C&hoose + E&legir + + + Sending addresses + Enviando direcciones + + + Receiving addresses + Recibiendo direcciones + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Estas son tus direcciones de Bitcoin para enviar pagos. Comprueba siempre la cantidad y la dirección receptora antes de enviar monedas. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Estas son tus direcciones de Bitcoin para recibir pagos. Se recomienda usar una nueva dirección receptora para cada transacción + + + Copy &Label + Copiar &Etiqueta + + + &Edit + &Editar + + + Export Address List + Exportar Lista de Direcciones + + + Comma separated file (*.csv) + Archivo separado por comas (*.csv) + + + Exporting Failed + Exportacón Fallida + + + There was an error trying to save the address list to %1. Please try again. + Ha ocurrido un error intentando guardar la lista de direcciones en %1. Por favor intentalo de nuevo. + + + + AddressTableModel + + Label + Etiqueta + + + Address + Dirección + + + (no label) + (sin etiqueta) + + + + AskPassphraseDialog + + Passphrase Dialog + Dialogo de Contraseña + + + Enter passphrase + Introduzca la contraseña + + + New passphrase + Nueva contraseña + + + Repeat new passphrase + Repite la nueva contraseña + + + Encrypt wallet + Encriptar cartera + + + This operation needs your wallet passphrase to unlock the wallet. + Esta operacón necesita tu contraseña de la cartera para desbloquear la cartera. + + + Unlock wallet + Desbloquear cartera + + + This operation needs your wallet passphrase to decrypt the wallet. + Esta operación requiere tu contraseña de la cartera para desencriptar la cartera. + + + Decrypt wallet + Desencriptar cartera + + + Change passphrase + Cambiar contraseña + + + Confirm wallet encryption + Confirmar encriptación de la cartera + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Advertencia: Si encriptas tu cartera y pierdes tu contraseña, <b>PERDERÁS TODOS TUS BITCOINS</B> + + + Are you sure you wish to encrypt your wallet? + Estás seguro ue deseas encriptar tu cartera? + + + Bitcoin Core will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer. + Bitcoin Core se cerrará ahora para finalizar el proceso de encriptación. Recuerda que encriptar tu cartera no protege completamente tus bitcoins de ser robados por malware infectando tu ordenador. + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + IMPORTANTE: Cualquier copia de seguridad anterior del archivo de tu cartera debería ser remplazado con el nuevo archivo encriptado. Por motivos de seguridad, las copias de seguridad anteriores de la cartera desencriptada quedaran inusables tan pronto como empieces a usar la nueva cartera encriptada. + + + Warning: The Caps Lock key is on! + Advertencia: La Tecla de Bloqueo de Mayusculas esta activada! + + + Wallet encrypted + Cartera encriptada + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Introduzca la nueva contraseña de la cartera. <br/>Por favor utilice una contraseña de <b>diez o mas caracteres aleatorios</b>, o <b>ocho o mas palabras</b>. + + + Enter the old passphrase and new passphrase to the wallet. + Introduzca la antigua contraseña y la nueva contraseña en la cartera. + + + Wallet encryption failed + Encriptación de la cartera fallida + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + La encriptación de la cartera ha fallado debido a un error interno. Tu cartera no ha sido encriptada. + + + The supplied passphrases do not match. + Las contraseñas proporcianadas no se corresponden. + + + Wallet unlock failed + Desbloqueo de la cartera fallido + + + The passphrase entered for the wallet decryption was incorrect. + La contraseña introducida para desencriptar la cartera es incorrecta. + + + Wallet decryption failed + Desencriptación de la cartera fallida + + + Wallet passphrase was successfully changed. + Contraseña de la cartera cambiada correctamente + + + + BanTableModel + + + BitcoinGUI + + Sign &message... + Firmar &mensaje... + + + Synchronizing with network... + Sincronizando con la red... + + + &Overview + &Vista general + + + Node + Nodo + + + Show general overview of wallet + Mostrar vista general de la cartera + + + &Transactions + &Transacciones + + + Browse transaction history + Navegar historial de transacciones + + + E&xit + S&alir + + + Quit application + Salir de la aplicación + + + About &Qt + Acerca de &Qt + + + Show information about Qt + Muestra información acerca de Qt + + + &Options... + &Opciones... + + + &Encrypt Wallet... + &Encriptar Cartera... + + + &Backup Wallet... + &Hacer copia de seguridad de la cartera... + + + &Change Passphrase... + &Cambiar contraseña... + + + &Sending addresses... + &Enviando direcciones... + + + &Receiving addresses... + &Recibiendo direcciones.. + + + Open &URI... + Abrir &URI... + + + Bitcoin Core client + Cliente Bitcoin Core + + + Importing blocks from disk... + Importando bloques desde disco... + + + Reindexing blocks on disk... + Reindexando bloques en el disco... + + + Send coins to a Bitcoin address + Envia monedas a una dirección Bitcoin + + + Backup wallet to another location + Crea una copia de seguridad de tu cartera en otra ubicación + + + + ClientModel + + + CoinControlDialog + + (no label) + (sin etiqueta) + + + + EditAddressDialog + + &Label + Etiqueta + + + &Address + Dirección + + + + FreespaceChecker + + + HelpMessageDialog + + + Intro + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + Copy &Address + &Copiar Direccón + + + Address + Dirección + + + Label + Etiqueta + + + + RecentRequestsTableModel + + Label + Etiqueta + + + (no label) + (sin etiqueta) + + + + SendCoinsDialog + + (no label) + (sin etiqueta) + + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDesc + + + TransactionDescDialog + + + TransactionTableModel + + Label + Etiqueta + + + + TransactionView + + Exporting Failed + Exportacón Fallida + + + Comma separated file (*.csv) + Archivo separado por comas (*.csv) + + + Label + Etiqueta + + + Address + Dirección + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + &Export + &Exportar + + + Export the data in the current tab to a file + Exporta los datos de la pestaña actual a un archivo + + + + bitcoin-core + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_es_MX.ts b/src/qt/locale/bitcoin_es_MX.ts index 1075fb08b..fa2b3c062 100644 --- a/src/qt/locale/bitcoin_es_MX.ts +++ b/src/qt/locale/bitcoin_es_MX.ts @@ -11,7 +11,7 @@ Copy the currently selected address to the system clipboard - Copiar el domicilio seleccionado al portapapeles del sistema + Copiar la dirección seleccionada al portapapeles del sistema &Copy @@ -83,7 +83,7 @@ Comma separated file (*.csv) - Arhchivo separado por comas (*.CSV) + Archivo separado por comas (*.CSV) Exporting Failed @@ -98,7 +98,7 @@ Address - Domicilio + Dirección (no label) @@ -165,7 +165,7 @@ Wallet encryption failed - Encriptación de la cartera fallida + La encriptación de la cartera fallo Wallet encryption failed due to an internal error. Your wallet was not encrypted. @@ -181,7 +181,7 @@ The passphrase entered for the wallet decryption was incorrect. - La contraseña ingresada para la desencriptación de la cartera es incorrecto + La contraseña ingresada para la desencriptación de la cartera es incorrecta Wallet decryption failed @@ -199,7 +199,7 @@ BitcoinGUI Sign &message... - Sign &mensaje + Firmar &mensaje Synchronizing with network... @@ -259,16 +259,20 @@ &Sending addresses... - &Enviando direcciones... + Direcciones de &envío... &Receiving addresses... - &Recibiendo direcciones... + Direcciones de &recepción... Open &URI... Abrir &URL... + + Bitcoin Core client + cliente Bitcoin Core + Importing blocks from disk... Importando bloques desde el disco... @@ -295,12 +299,28 @@ Open debugging and diagnostic console - Abrir la consola de depuración y disgnostico + Abrir consola de depuración y diagnostico &Verify message... &Verificar mensaje... + + Bitcoin + Bitcoin + + + Wallet + Cartera + + + &Send + &Enviar + + + &Receive + &Recibir + &File &Archivo @@ -321,6 +341,10 @@ Bitcoin Core nucleo Bitcoin + + &About Bitcoin Core + Acerca de Bitcoin Core + &Command-line options opciones de la &Linea de comandos @@ -335,7 +359,7 @@ Catching up... - Resiviendo... + Recibiendo... Sent transaction @@ -387,41 +411,45 @@ Confirmed Confirmado + + Priority + Prioridad + Copy address Copiar dirección Copy label - Copiar capa + Copiar etiqueta Copy amount - copiar monto + Copiar monto Copy quantity - copiar cantidad + Copiar cantidad Copy fee - copiar cuota + Copiar cuota Copy after fee - copiar despues de cuota + Copiar después de cuota Copy bytes - copiar bytes + Copiar bytes Copy priority - copiar prioridad + Copiar prioridad Copy change - copiar cambio + Copiar cambio (no label) @@ -444,23 +472,23 @@ New receiving address - Nueva dirección de entregas + Nueva dirección de recepción New sending address - Nueva dirección de entregas + Nueva dirección de envío Edit receiving address - Editar dirección de entregas + Editar dirección de recepción Edit sending address - Editar dirección de envios + Editar dirección de envío The entered address "%1" is already in the address book. - El domicilio ingresado "%1" ya existe en la libreta de direcciones + La dirección ingresada "%1" ya existe en la libreta de direcciones Could not unlock wallet. @@ -482,7 +510,7 @@ version - Versión + versión (%1-bit) @@ -492,6 +520,10 @@ About Bitcoin Core Acerca de Bitcoin Core + + Command-line options + opciones de la Linea de comandos + Usage: Uso: @@ -500,7 +532,7 @@ command-line options Opciones de comando de lineas - + Intro @@ -521,6 +553,10 @@ Active command-line options that override above options: Activar las opciones de linea de comando que sobre escriben las siguientes opciones: + + W&allet + Cartera + OverviewPage @@ -547,13 +583,25 @@ RPCConsole + + Debug window + Depurar ventana + ReceiveCoinsDialog + + &Amount: + Monto: + &Label: &Etiqueta + + &Message: + Mensaje: + An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network. Mensaje opcional para agregar a la solicitud de pago, el cual será mostrado cuando la solicitud este abierta. Nota: El mensaje no se manda con el pago a travéz de la red de Bitcoin. @@ -568,18 +616,22 @@ Copy label - Copiar capa + Copiar etiqueta Copy amount - copiar monto + Copiar monto ReceiveRequestDialog + + Copy &Address + &Copiar dirección + Address - Domicilio + Dirección Amount @@ -589,6 +641,10 @@ Label Etiqueta + + Message + Mensaje + RecentRequestsTableModel @@ -600,6 +656,10 @@ Label Etiqueta + + Message + Mensaje + Amount Monto @@ -613,7 +673,7 @@ SendCoinsDialog Send Coins - Mandar monedas + Enviar monedas Bytes: @@ -631,6 +691,10 @@ Fee: Cuota: + + fast + rápido + Send to multiple recipients at once Enviar a múltiples receptores a la vez @@ -645,35 +709,35 @@ Confirm send coins - Confirme para mandar monedas + Confirme para enviar monedas Copy quantity - copiar cantidad + Copiar cantidad Copy amount - copiar monto + Copiar monto Copy fee - copiar cuota + Copiar cuota Copy after fee - copiar despues de cuota + Copiar después de cuota Copy bytes - copiar bytes + Copiar bytes Copy priority - copiar prioridad + Copiar prioridad Copy change - copiar cambio + Copiar cambio or @@ -685,7 +749,7 @@ Transaction creation failed! - ¡La creación de transacion falló! + ¡La creación de la transación falló! The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. @@ -776,12 +840,16 @@ Alt+P Alt+P + + Signature + Firma + SplashScreen Bitcoin Core - nucleo Bitcoin + Bitcoin Core The Bitcoin Core developers @@ -805,14 +873,42 @@ %1 confirmations %1 confirmaciones + + Status + Estado + Date Fecha + + From + De + + + To + Para + + + label + etiqueta + + + Message + Mensaje + + + Comment + Comentario + Transaction ID ID + + Transaction + Transacción + Amount Monto @@ -869,7 +965,7 @@ Received with - Recivido con + Recibido con Sent to @@ -928,7 +1024,7 @@ Received with - Recivido con + Recibido con Sent to @@ -986,6 +1082,10 @@ Exporting Successful Exportacion satisfactoria + + The transaction history was successfully saved to %1. + el historial de transaciones ha sido guardado exitosamente en %1 + Comma separated file (*.csv) Arhchivo separado por comas (*.CSV) @@ -1050,33 +1150,33 @@ There was an error trying to save the wallet data to %1. Ocurrio un error tratando de guardar la información de la cartera %1 + + The wallet data was successfully saved to %1. + La información de la cartera fué guardada exitosamente a %1 + bitcoin-core + + Options: + Opciones: + <category> can be: <categoria> puede ser: + + Verifying blocks... + Verificando bloques... + + + Verifying wallet... + Verificando cartera... + Wallet options: Opciones de cartera: - - Choose data directory on startup (default: 0) - Escojer el directorio de información al iniciar (por defecto : 0) - - - Set language, for example "de_DE" (default: system locale) - Definir idioma, por ejemplo "de_DE" (por defecto: Sistema local) - - - Show splash screen on startup (default: 1) - Mostrar pantalla de arraque al iniciar (por defecto: 1) - - - Start minimized - Iniciar minimizado - Loading addresses... Cargando direcciones... diff --git a/src/qt/locale/bitcoin_es_UY.ts b/src/qt/locale/bitcoin_es_UY.ts index 5029333b5..32d433d6e 100644 --- a/src/qt/locale/bitcoin_es_UY.ts +++ b/src/qt/locale/bitcoin_es_UY.ts @@ -1,22 +1,71 @@ AddressBookPage + + Right-click to edit address or label + Clic derecho para editar dirección o etiqueta + Create a new address Crear una nueva dirección + + &New + Nuevo + Copy the currently selected address to the system clipboard Copia la dirección seleccionada al portapapeles del sistema + + &Copy + Copiar + + + C&lose + Cerrar + + + &Copy Address + Copiar Dirección + + + &Export + Exportar + &Delete &Borrar + + Choose the address to send coins to + Elige una dirección donde enviar monedas a + + + Sending addresses + Enviando direcciones + + + Receiving addresses + Recibiendo direcciones + + + + &Edit + Editar + + + Export Address List + Exportar Lista de Direcciones + Comma separated file (*.csv) Archivos separados por coma (*.csv) + + Exporting Failed + Exportación fallida + AddressTableModel @@ -75,6 +124,14 @@ Confirm wallet encryption Confirme el cifrado del monedero + + Are you sure you wish to encrypt your wallet? + Estas seguro que deseas encriptar tu billetera? + + + Warning: The Caps Lock key is on! + Atención: la tecla Mayusculas esta activa! + Wallet encrypted Monedero cifrado @@ -129,18 +186,58 @@ Browse transaction history Buscar en el historial de transacciones + + E&xit + Salida + Quit application Salir de la aplicacion + + Show information about Qt + Mostrar informacioón sobre + &Options... &Opciones... + + &Backup Wallet... + Respaldar Billetera + + + &Change Passphrase... + Cambiar contraseña + + + &Sending addresses... + Enviando direcciones + + + &Receiving addresses... + Recibiendo direcciones + + + Send coins to a Bitcoin address + Enviar monedas a una dirección BItCoin + Change the passphrase used for wallet encryption Cambie la clave utilizada para el cifrado del monedero + + Bitcoin + Bitcoin + + + Wallet + Billetera + + + &Show / Hide + Mostrar / Ocultar + &File &Archivo @@ -157,6 +254,18 @@ Tabs toolbar Barra de herramientas + + Error + Error + + + Warning + Alerta + + + Information + Información + Up to date A la fecha @@ -165,6 +274,17 @@ Catching up... Ponerse al dia... + + Type: %1 + + Tipo: %1 + + + + Address: %1 + + Dirección: %1 + Sent transaction Transaccion enviada @@ -187,10 +307,38 @@ CoinControlDialog + + Quantity: + Cantidad: + + + Bytes: + Bytes: + + + Amount: + AMonto: + + + Priority: + Prioridad: + + + Change: + Cambio: + Date Fecha + + Confirmed + Confirmado + + + Priority + Prioridad + (no label) (Sin etiqueta) @@ -226,6 +374,10 @@ Edit sending address Editar dirección de envío + + The entered address "%1" is already in the address book. + La dirección introducida "%1" ya está en la libreta de direcciones. + Could not unlock wallet. No se puede abrir el monedero. @@ -243,6 +395,10 @@ Intro + + Error + Error + OpenURIDialog @@ -253,6 +409,10 @@ Options Opciones + + W&allet + Billetera + OverviewPage @@ -275,6 +435,10 @@ RPCConsole + + &Information + Información + ReceiveCoinsDialog @@ -285,6 +449,10 @@ ReceiveRequestDialog + + Copy &Address + Copiar Dirección + Address Direccion @@ -315,6 +483,26 @@ Send Coins Enviar monedas + + Quantity: + Cantidad: + + + Bytes: + Bytes: + + + Amount: + AMonto: + + + Priority: + Prioridad: + + + Change: + Cambio: + Send to multiple recipients at once Enviar a varios destinatarios a la vez @@ -370,6 +558,10 @@ Alt+P Alt+P + + Pay To: + Pagar A: + ShutdownWindow @@ -409,6 +601,10 @@ Date Fecha + + Transaction + Transaccion + unknown desconocido @@ -434,10 +630,18 @@ TransactionView + + Exporting Failed + Exportación fallida + Comma separated file (*.csv) Archivos separados por coma (*.csv) + + Confirmed + Confirmado + Date Fecha @@ -466,8 +670,28 @@ WalletView + + &Export + Exportar + bitcoin-core - + + Options: + Opciones: + + + Information + Información + + + Warning + Alerta + + + Error + Error + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_es_VE.ts b/src/qt/locale/bitcoin_es_VE.ts new file mode 100644 index 000000000..582e72884 --- /dev/null +++ b/src/qt/locale/bitcoin_es_VE.ts @@ -0,0 +1,1133 @@ + + + AddressBookPage + + Right-click to edit address or label + Click derecho para editar la dirección o etiqueta + + + Create a new address + Crear una nueva dirección + + + &New + &Nuevo + + + Copy the currently selected address to the system clipboard + Copie las direcciones seleccionadas actualmente al portapapeles del sistema + + + &Copy + &Copiar + + + &Copy Address + &Copiar Dirección + + + Delete the currently selected address from the list + Borrar las direcciones seleccionadas recientemente de la lista + + + Export the data in the current tab to a file + Exportar los datos en la pestaña actual a un archivo + + + &Export + &Exportar + + + &Delete + &Borrar + + + Choose the address to send coins to + Elige la dirección para enviar monedas + + + Choose the address to receive coins with + Elige la dirección para recibir monedas + + + Sending addresses + Envío de direcciones + + + Receiving addresses + Recepción de direcciones + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Estas son tus direcciones Bitcoin para realizar pagos. Siempre checa el monto y la dirección de recepción antes de enviar monedas. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Estas son tus direcciones Bitcoin para recibir pagos. Es recomendable usar una nueva dirección para cada transacción. + + + Copy &Label + Copiar &Etiqueta + + + &Edit + &Editar + + + Export Address List + Exportar lista de direcciones + + + Comma separated file (*.csv) + Archivo separado por comas (*.csv) + + + Exporting Failed + Exportación fallida + + + There was an error trying to save the address list to %1. Please try again. + Hubo un error intentando guardar la lista de direcciones al %1. Por favor intente nuevamente. + + + + AddressTableModel + + Label + Etiqueta + + + Address + Dirección + + + (no label) + (sin etiqueta) + + + + AskPassphraseDialog + + Passphrase Dialog + Diálogo contraseña + + + Enter passphrase + Ingresa frase de contraseña + + + New passphrase + Nueva frase de contraseña + + + Repeat new passphrase + Repetir nueva frase de contraseña + + + Encrypt wallet + Encriptar billetera + + + This operation needs your wallet passphrase to unlock the wallet. + Esta operación necesita tu frase de contraseña de la billetera para desbloquearla. + + + Unlock wallet + Desbloquear billetera + + + This operation needs your wallet passphrase to decrypt the wallet. + Esta operacción necesita tu frase de contraseña para desepcriptar la billetera + + + Decrypt wallet + Desencriptar billetera + + + Change passphrase + Cambiar frase secreta + + + Confirm wallet encryption + Confirmar encriptación de billetera + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Aviso: Si encriptas tu billetera y pierdes tu frase secreta, ¡PERDERÁS TODOS TUS BITCOINS! + + + Are you sure you wish to encrypt your wallet? + ¿Está seguro que desea encriptar su billetera? + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + IMPORTANTE: Algunas copias de seguridad que hayas hecho de tu archivo de billetera deberían ser reemplazadas con la billetera encriptada generada recientemente. Por razones de seguridad, las copias de seguridad previas del archivo de billetera sin cifrar serán inútiles tan pronto uses la nueva billetera encriptada. + + + Warning: The Caps Lock key is on! + Aviso: El bloqueo de mayúsculas está activado. + + + Wallet encrypted + Billetera encriptada + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Introduce la nueva frase secreta a la billetera. Por favor use una frase secreta de diez o más caracteres aleatorios, u ocho o más palabras. + + + Wallet encryption failed + Encriptación de billetera fallida + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Encriptación de billetera fallida debido a un error interno. Tu billetera no fue encriptada. + + + The supplied passphrases do not match. + Las frases secretas introducidas no concuerdan. + + + Wallet unlock failed + Desbloqueo de billetera fallido + + + The passphrase entered for the wallet decryption was incorrect. + La frase secreta introducida para la desencriptación de la billetera fué incorrecta. + + + Wallet decryption failed + Desencriptación de billetera fallida + + + Wallet passphrase was successfully changed. + La frase secreta de la billetera fué cambiada exitosamente. + + + + BanTableModel + + + BitcoinGUI + + Sign &message... + Firmar &mensaje... + + + Synchronizing with network... + Sincronizando con la red... + + + Node + Nodo + + + Show general overview of wallet + Mostrar visión general de la billetera + + + &Transactions + &Transacciones + + + Browse transaction history + Buscar historial de transacciones + + + Quit application + Quitar aplicación + + + &Receiving addresses... + Recepción de direcciones + + + Bitcoin Core client + Cliente Bitcoin Core + + + Importing blocks from disk... + Importando bloques desde el disco... + + + Reindexing blocks on disk... + Reindexando bloques en el disco... + + + Send coins to a Bitcoin address + Enviar monedas a una dirección Bitcoin + + + Backup wallet to another location + Respaldar billetera en otra ubicación + + + Change the passphrase used for wallet encryption + Cambiar frase secreta usada para la encriptación de la billetera + + + Open debugging and diagnostic console + Abre la consola de depuración y diágnostico + + + Bitcoin + Bitcoin + + + Wallet + Billetera + + + &Send + &Enviar + + + &Receive + &Recibir + + + Show information about Bitcoin Core + Mostrar información acerca de Bitcoin Core + + + &Show / Hide + &Mostar / Ocultar + + + Show or hide the main Window + Mostar u ocultar la ventana principal + + + Encrypt the private keys that belong to your wallet + Encriptar las llaves privadas que pertenecen a tu billetera + + + Sign messages with your Bitcoin addresses to prove you own them + Firma mensajes con tus direcciones Bitcoin para probar que eres dueño de ellas + + + Verify messages to ensure they were signed with specified Bitcoin addresses + Verificar mensajes para asegurar que estaban firmados con direcciones Bitcoin especificas + + + &File + &Archivo + + + &Settings + &Configuración + + + Bitcoin Core + Bitcoin Core + + + &About Bitcoin Core + Acerca de Bitcoin Core + + + &Command-line options + Opciones de línea de comandos + + + %1 and %2 + %1 y %2 + + + %1 behind + %1 detrás + + + Last received block was generated %1 ago. + El último bloque recibido fue generado hace %1 hora(s). + + + Transactions after this will not yet be visible. + Transacciones después de esta no serán visibles todavía. + + + Error + Error + + + Warning + Advertencia + + + Information + Información + + + Up to date + Al día + + + Catching up... + Alcanzando... + + + Sent transaction + Transacción enviada + + + Incoming transaction + Transacción entrante + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + La billetera está encriptada y desbloqueada recientemente + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + La billetera está encriptada y bloqueada recientemente + + + + ClientModel + + Network Alert + Alerta de red + + + + CoinControlDialog + + Coin Selection + Selección de moneda + + + Quantity: + Cantidad: + + + Bytes: + Bytes: + + + Amount: + Monto: + + + Priority: + Prioridad: + + + Fee: + Comisión: + + + Dust: + Polvo: + + + Change: + Cambio: + + + (un)select all + (de)seleccionar todo + + + Tree mode + Modo de árbol + + + List mode + Modo de lista + + + Amount + Monto + + + Received with label + Recibido con etiqueta + + + Received with address + Recibido con dirección + + + Date + Fecha + + + Confirmations + Confirmaciones + + + Confirmed + Confirmado + + + Priority + Prioridad + + + Copy address + Copiar dirección + + + Copy label + Copiar etiqueta + + + Copy amount + Copiar monto + + + Copy transaction ID + Copiar ID de la transacción + + + Lock unspent + Bloqueo no gastado + + + Unlock unspent + Desbloqueo no gastado + + + Copy quantity + Copiar cantidad + + + Copy fee + Copiar comisión + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridad + + + Copy dust + Copiar dust + + + Copy change + Copiar cambio + + + highest + Más alto + + + higher + superior + + + high + alto + + + medium-high + medio-alto + + + medium + medio + + + low-medium + bajo-medio + + + low + bajo + + + lower + inferior + + + lowest + más bajo + + + (%1 locked) + (%1 bloqueado) + + + none + ninguno + + + Can vary +/- %1 satoshi(s) per input. + Puede variar +/- %1 satoshi(s) por entrada. + + + yes + si + + + no + no + + + This means a fee of at least %1 per kB is required. + Esto significa que se requiere al menos de una comisión de %1 por kB + + + Can vary +/- 1 byte per input. + Puede variar +/- 1 byte por entrada. + + + Transactions with higher priority are more likely to get included into a block. + Transacciones con mayor prioridad son más probables de ser incluidas en un bloque. + + + (no label) + (sin etiqueta) + + + change from %1 (%2) + Cambio desde %1 (%2) + + + (change) + (cambio) + + + + EditAddressDialog + + Edit Address + Editar dirección + + + &Label + &Etiqueta + + + The label associated with this address list entry + La etiqueta asociada con esta entrada de la lista de direcciones + + + The address associated with this address list entry. This can only be modified for sending addresses. + La dirección asociada con esta entrada de la lista de direcciones. Esta puede ser modificada solo para el envío de direcciones. + + + &Address + &Dirección + + + New receiving address + Nueva dirección de recibo + + + New sending address + Nueva dirección de envío + + + Edit receiving address + Editar dirección de envío + + + Edit sending address + Editar dirección de envío + + + The entered address "%1" is already in the address book. + La dirección introducida "%1" ya está en el libro de direcciones. + + + The entered address "%1" is not a valid Bitcoin address. + La dirección introducida "%1" no es una dirección Bitcoin válida. + + + Could not unlock wallet. + No se pudo desbloquear la billetera. + + + New key generation failed. + Creación de la nueva llave fallida + + + + FreespaceChecker + + A new data directory will be created. + Un nuevo directorio de datos será creado. + + + name + nombre + + + Directory already exists. Add %1 if you intend to create a new directory here. + El directorio ya existe. Agrega %1 si tiene la intención de crear un nuevo directorio aquí. + + + Path already exists, and is not a directory. + La ruta ya existe, y no es un directorio. + + + Cannot create data directory here. + No puede crear directorio de datos aquí. + + + + HelpMessageDialog + + Bitcoin Core + Bitcoin Core + + + version + versión + + + (%1-bit) + (%1-bit) + + + About Bitcoin Core + Acerca de Bitcoin Core + + + Command-line options + Opciones de línea de comandos + + + Usage: + Uso: + + + command-line options + opciones de línea de comandos + + + + Intro + + Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + Bitcoin Core descargará y almacenará una copia de la cadena de bloques Bitcoin. Al menos %1GB de datos serán almacenados en este directorio, y crecerá con el tiempo. La billetera será también almacenada en este directorio. + + + Use the default data directory + Usar el directorio de datos por defecto + + + Use a custom data directory: + Usa un directorio de datos personalizado: + + + Bitcoin Core + Bitcoin Core + + + Error: Specified data directory "%1" cannot be created. + Error: Directorio de datos especificado "%1" no puede ser creado. + + + Error + Error + + + + OpenURIDialog + + Open URI + Abrir URI + + + Open payment request from URI or file + Abrir solicitud de pago desde URI o archivo + + + URI: + URI: + + + Select payment request file + Seleccionar archivo de solicitud de pago + + + Select payment request file to open + Seleccionar archivo de solicitud de pago para abrir + + + + OptionsDialog + + Options + Opciones + + + &Main + &Main + + + W&allet + Billetera + + + none + ninguno + + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + Amount + Monto + + + + QRImageWidget + + + RPCConsole + + &Information + Información + + + + ReceiveCoinsDialog + + &Amount: + Monto: + + + &Label: + &Etiqueta: + + + Copy label + Copiar etiqueta + + + Copy amount + Copiar monto + + + + ReceiveRequestDialog + + Copy &Address + &Copiar Dirección + + + Address + Dirección + + + Amount + Monto + + + Label + Etiqueta + + + + RecentRequestsTableModel + + Date + Fecha + + + Label + Etiqueta + + + Amount + Monto + + + (no label) + (sin etiqueta) + + + + SendCoinsDialog + + Quantity: + Cantidad: + + + Bytes: + Bytes: + + + Amount: + Monto: + + + Priority: + Prioridad: + + + Fee: + Comisión: + + + Change: + Cambio: + + + Dust: + Polvo: + + + Copy quantity + Copiar cantidad + + + Copy amount + Copiar monto + + + Copy fee + Copiar comisión + + + Copy bytes + Copiar bytes + + + Copy priority + Copiar prioridad + + + Copy change + Copiar cambio + + + (no label) + (sin etiqueta) + + + Copy dust + Copiar dust + + + + SendCoinsEntry + + A&mount: + Monto: + + + &Label: + &Etiqueta: + + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + Bitcoin Core + Bitcoin Core + + + + TrafficGraphWidget + + + TransactionDesc + + Date + Fecha + + + Transaction + Transacción + + + Amount + Monto + + + + TransactionDescDialog + + + TransactionTableModel + + Date + Fecha + + + Label + Etiqueta + + + + TransactionView + + Copy address + Copiar dirección + + + Copy label + Copiar etiqueta + + + Copy amount + Copiar monto + + + Copy transaction ID + Copiar ID de la transacción + + + Exporting Failed + Exportación fallida + + + Comma separated file (*.csv) + Archivo separado por comas (*.csv) + + + Confirmed + Confirmado + + + Date + Fecha + + + Label + Etiqueta + + + Address + Dirección + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + &Export + &Exportar + + + Export the data in the current tab to a file + Exportar los datos en la pestaña actual a un archivo + + + Backup Failed + Copia de seguridad fallida + + + There was an error trying to save the wallet data to %1. + Hubo un error intentando guardar los datos de la billetera al %1 + + + The wallet data was successfully saved to %1. + Los datos de la billetera fueron guardados exitosamente al %1 + + + Backup Successful + Copia de seguridad completada + + + + bitcoin-core + + Options: + Opciones: + + + Specify data directory + Especifique directorio de datos + + + Connect to a node to retrieve peer addresses, and disconnect + Conecte un nodo para recuperar direcciones pares, y desconecte + + + Specify your own public address + Especifique su propia dirección pública + + + Accept command line and JSON-RPC commands + Aceptar linea de comando y comandos JSON-RPC + + + Run in the background as a daemon and accept commands + Correr en segundo plano como daemon y aceptar comandos + + + Bind to given address and always listen on it. Use [host]:port notation for IPv6 + Enlazar dirección dada y siempre escuchar en ella. Usar [host]:port notación para IPv6 + + + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup + Borrar todas las transacciones de la billetera y solo recuperar aquellas partes de la cadena de bloques a través de -rescan en el inicio del sistema. + + + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + Distribuido bajo la licensia de software MIT, ver el archivo adjunto COPYING o <http://www.opensource.org/licenses/mit-license.php>. + + + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) + Ejecutar comando cuando una transacción de la billetera cambia (%s en cmd es reemplazado por TxID) + + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) + Fija el número de verificación de hilos de script (%u a %d, 0 = auto, <0 = leave that many cores free, default: %d) + + + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications + Esta es una compilación de prueba pre-lanzamiento - use bajo su propio riesgo - no utilizar para aplicaciones de minería o mercantes + + + Unable to bind to %s on this computer. Bitcoin Core is probably already running. + Deshabilitar para enlezar a %s en esta computadora. Bitcoin Core probablemente ya está ejecutándose. + + + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. + Aviso: ¡La red no parece estar totalmente de acuerdo! Algunos mineros parecen estar teniendo inconvenientes. + + + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. + Aviso: ¡No parecen estar totalmente de acuerdo con nuestros compañeros! Puede que tengas que actualizar, u otros nodos tengan que actualizarce. + + + 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. + Aviso: wallet.dat está corrupto, ¡datos salvados! wallet.dat original guardado como wallet.{timestamp}.bak en %s; si tus transacciones o balance está incorrecto deberías restaurarlo desde una copia de seguridad. + + + Information + Información + + + Warning + Advertencia + + + Error + Error + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_et.ts b/src/qt/locale/bitcoin_et.ts index 9279834af..945e4cfa5 100644 --- a/src/qt/locale/bitcoin_et.ts +++ b/src/qt/locale/bitcoin_et.ts @@ -329,6 +329,14 @@ Bitcoin Core Bitcoini tuumik + + &About Bitcoin Core + Kirjeldus Bitcoini Tuumast + + + &Command-line options + Käsurea valikud + %n hour(s) %n tund%n tundi @@ -606,7 +614,7 @@ command-line options käsurea valikud - + Intro @@ -639,6 +647,10 @@ Options Valikud + + &Main + &Peamine + MB MB @@ -809,6 +821,10 @@ &Information &Informatsioon + + Debug window + Debugimise aken + General Üldine @@ -947,6 +963,10 @@ ReceiveRequestDialog + + Copy &Address + &Kopeeri Aadress + Address Aadress @@ -1009,6 +1029,10 @@ Send Coins Müntide saatmine + + Insufficient funds! + Liiga suur summa + Quantity: Kogus: @@ -1021,6 +1045,10 @@ Fee: Tasu: + + Transaction Fee: + Tehingu tasu: + Choose... Vali... @@ -1132,6 +1160,10 @@ Message: Sõnum: + + Pay To: + Maksa : + ShutdownWindow @@ -1283,6 +1315,10 @@ Open until %1 Avatud kuni %1 + + %1/offline + %1/offline'is + %1/unconfirmed %1/kinnitamata @@ -1731,10 +1767,30 @@ Wallet options: Rahakoti valikud: + + (default: %u) + (vaikimisi: %u) + + + Cannot resolve -whitebind address: '%s' + Tundmatu -whitebind aadress: '%s' + Information Informatsioon + + Invalid amount for -maxtxfee=<amount>: '%s' + -maxtxfee=<amount> jaoks vigane kogus: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + -minrelaytxfee=<amount> jaoks vigane kogus: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + -mintxfee=<amount> jaoks vigane kogus: '%s' + RPC server options: RPC serveri valikud: @@ -1743,14 +1799,6 @@ Send trace/debug info to console instead of debug.log file Saada jälitus/debug, debug.log faili asemel, konsooli - - Set language, for example "de_DE" (default: system locale) - Keele valik, nt "ee_ET" (vaikeväärtus: system locale) - - - Show splash screen on startup (default: 1) - Käivitamisel teabeakna kuvamine (vaikeväärtus: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Kahanda programmi käivitamisel debug.log faili (vaikeväärtus: 1, kui ei ole -debug) @@ -1759,10 +1807,6 @@ Signing transaction failed Tehingu allkirjastamine ebaõnnestus - - Start minimized - Käivitu tegumiribale - The transaction amount is too small to pay the fee Tehingu summa on tasu maksmiseks liiga väikene @@ -1775,10 +1819,6 @@ Transaction too large Tehing liiga suur - - UI Options: - UI Valikud: - Username for JSON-RPC connections JSON-RPC ühenduste kasutajatunnus diff --git a/src/qt/locale/bitcoin_eu_ES.ts b/src/qt/locale/bitcoin_eu_ES.ts index 4da6cc0dc..ca6b6489d 100644 --- a/src/qt/locale/bitcoin_eu_ES.ts +++ b/src/qt/locale/bitcoin_eu_ES.ts @@ -249,6 +249,10 @@ &Options... &Aukerak... + + &Receiving addresses... + Helbideak jasotzen + Change the passphrase used for wallet encryption Aldatu zorroa enkriptatzeko erabilitako pasahitza @@ -414,10 +418,18 @@ ReceiveCoinsDialog + + &Amount: + Kopurua + &Label: &Etiketa: + + &Message: + Mezua + Copy label Kopiatu etiketa @@ -425,6 +437,10 @@ ReceiveRequestDialog + + Copy &Address + &Kopiatu helbidea + Address Helbidea @@ -437,6 +453,10 @@ Label Etiketa + + Message + Mezua + RecentRequestsTableModel @@ -448,6 +468,10 @@ Label Etiketa + + Message + Mezua + Amount Kopurua @@ -526,6 +550,10 @@ Message: Mezua + + Pay To: + Ordaindu honi: + ShutdownWindow @@ -573,6 +601,14 @@ Date Data + + Message + Mezua + + + Transaction + Transakzioaren + Amount Kopurua diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index fb4e25dfb..7ab3b77da 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -397,6 +397,10 @@ Show the list of used receiving addresses and labels نمایش لیست آدرس های دریافت و لیبل ها + + &Command-line options + گزینه‌های خط‌فرمان + %n active connection(s) to Bitcoin network %n ارتباط فعال با شبکهٔ بیت‌کوین @@ -417,6 +421,14 @@ %n week(s) %n هفته + + %1 and %2 + %1 و %2 + + + %n year(s) + %n سال + %1 behind %1 عقب‌تر @@ -712,7 +724,7 @@ command-line options گزینه‌های خط فرمان - + Intro @@ -743,6 +755,10 @@ Error خطا + + %n GB of free space available + %n گیگابایت فضا موجود است + OpenURIDialog @@ -769,6 +785,10 @@ &Network &شبکه + + W&allet + کیف پول + Expert استخراج @@ -975,6 +995,10 @@ &Information &اطلاعات + + Debug window + پنجرهٔ اشکالزدایی + Using OpenSSL version نسخهٔ OpenSSL استفاده شده @@ -1066,10 +1090,18 @@ ReceiveCoinsDialog + + &Amount: + مبلغ: + &Label: &برچسب: + + &Message: + پیام: + Show نمایش @@ -1093,6 +1125,10 @@ QR Code کد QR + + Copy &Address + &کپی نشانی + Address نشانی @@ -1147,6 +1183,10 @@ Send Coins ارسال سکه + + Insufficient funds! + بود جه نا کافی + Quantity: تعداد: @@ -1175,6 +1215,10 @@ Change: پول خورد: + + Transaction Fee: + هزینهٔ تراکنش: + fast سریع @@ -1290,6 +1334,10 @@ Message: پیام: + + Pay To: + پرداخت به: + ShutdownWindow @@ -1925,38 +1973,30 @@ Verifying wallet... در حال بازبینی کیف پول... - - Choose data directory on startup (default: 0) - انتخاب مسیر داده‌ها در ابتدای اجرای برنامه (پیش‌فرض: 0) - Information اطلاعات + + Invalid amount for -maxtxfee=<amount>: '%s' + میزان وجه اشتباه برای maxtxfee=<میزان وجه>: %s + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + میزان وجه اشتباه برای minrelaytxfee=<میزان وجه>: %s + + + Invalid amount for -mintxfee=<amount>: '%s' + میزان وجه اشتباه برای mintxfee=<میزان وجه>: %s + Send trace/debug info to console instead of debug.log file اطلاعات ردگیری/اشکال‌زدایی را به جای فایل لاگ اشکال‌زدایی به کنسول بفرستید - - Set language, for example "de_DE" (default: system locale) - زبان را تنظیم کنید؛ برای مثال «de_DE» (زبان پیش‌فرض محلی) - - - Show splash screen on startup (default: 1) - نمایش پنجرهٔ خوشامدگویی در ابتدای اجرای برنامه (پیش‌فرض: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) فایل debug.log را در startup مشتری کوچک کن (پیش فرض:1 اگر اشکال زدایی روی نداد) - - Start minimized - اجرای برنامه به صورت کوچک‌شده - - - UI Options: - گزینه‌های رابط کاربری: - Username for JSON-RPC connections JSON-RPC شناسه برای ارتباطات diff --git a/src/qt/locale/bitcoin_fa_IR.ts b/src/qt/locale/bitcoin_fa_IR.ts index fd9de2e04..8bbfc7242 100644 --- a/src/qt/locale/bitcoin_fa_IR.ts +++ b/src/qt/locale/bitcoin_fa_IR.ts @@ -249,6 +249,10 @@ &Change Passphrase... تغییر رمز/پَس فرِیز + + &Receiving addresses... + دریافت آدرس ها + Backup wallet to another location گرفتن نسخه پیشتیبان در آدرسی دیگر @@ -391,6 +395,10 @@ Edit sending address ویرایش حساب ارسال کننده + + The entered address "%1" is already in the address book. + حساب وارد شده «%1» از پیش در دفترچه حساب ها موجود است. + The entered address "%1" is not a valid Bitcoin address. آدرس وارد شده "%1" یک آدرس صحیح برای bitcoin نسشت @@ -434,6 +442,14 @@ Options انتخاب/آپشن + + &Network + شبکه + + + W&allet + کیف پول + &OK و تایید @@ -503,10 +519,18 @@ ReceiveCoinsDialog + + &Amount: + میزان وجه: + &Label: و برچسب + + &Message: + پیام: + Copy label برچسب را کپی کنید @@ -518,6 +542,10 @@ ReceiveRequestDialog + + Copy &Address + کپی آدرس + Address حساب @@ -572,6 +600,10 @@ Send Coins سکه های ارسالی + + Insufficient funds! + وجوه ناکافی + Amount: میزان وجه: @@ -685,6 +717,10 @@ Alt+P Alt و P + + Sign &Message + و امضای پیام + SplashScreen @@ -999,6 +1035,18 @@ The transaction amount is too small to send after the fee has been deducted مبلغ تراکنش کمتر از آن است که پس از کسر هزینه تراکنش قابل ارسال باشد + + Invalid amount for -maxtxfee=<amount>: '%s' + میزان اشتباه است for -maxtxfee=<amount>: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + میزان اشتباه است for -minrelaytxfee=<amount>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + میزان اشتباه است for -mintxfee=<amount>: '%s' + RPC server options: گزینه های سرویس دهنده RPC: diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index 7026fff1f..57987b26e 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP/Verkon peite + + + Banned Until + Estetty kunnes + + BitcoinGUI @@ -874,6 +882,34 @@ command-line options komentorivi parametrit + + UI Options: + Käyttöliittymän asetukset: + + + Choose data directory on startup (default: %u) + Valitse datahakemisto käynnistyksen yhteydessä (oletus: %u) + + + Set language, for example "de_DE" (default: system locale) + Aseta kieli, esimerkiksi "de_DE" (oletus: järjestelmän kieli) + + + Start minimized + Käynnistä pienennettynä + + + Set SSL root certificates for payment request (default: -system-) + Aseta maksupyynnöille SSL-juurivarmenteet (oletus: -system-) + + + Show splash screen on startup (default: %u) + Näytä aloitusruutu käynnistyksen yhteydessä (oletus: %u) + + + Reset all settings changes made over the GUI + Nollaa kaikki graafisen käyttöliittymän kautta tehdyt muutokset + Intro @@ -979,6 +1015,14 @@ IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) IP osoite proxille (esim. IPv4: 127.0.0.1 / IPv6: ::1) + + Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu. + Minimoi ikkuna ohjelman sulkemisen sijasta kun ikkuna suljetaan. Kun tämä asetus on käytössä, ohjelma suljetaan vain valittaessa valikosta Poistu. + + + The user interface language can be set here. This setting will take effect after restarting Bitcoin Core. + Käyttöliittymän kieli voidaan asettaa tässä. Tämä asetus tulee käyttöön vasta kun Bitcoin Core käynnistetään uudelleen. + Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. Ulkopuoliset URL-osoitteet (esim. block explorer,) jotka esiintyvät siirrot-välilehdellä valikossa. %s URL-osoitteessa korvataan siirtotunnuksella. Useampi URL-osoite on eroteltu pystyviivalla |. @@ -1063,6 +1107,34 @@ Port of the proxy (e.g. 9050) Proxyn Portti (esim. 9050) + + Used for reaching peers via: + Vertaisten saavuttamiseen käytettävät verkkotyypit: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Ilmoittaa, mikäli oletetettua SOCKS5-välityspalvelinta käytetään tämän verkkotyypin kautta vertaisten saavuttamiseen. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Yhdistä Bitcoin-verkkoon erillisen SOCKS5-välityspalvelimen kautta piilotettuja Tor-palveluja varten. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Käytä erillistä SOCKS5-välityspalvelinta saavuttaaksesi vertaisia piilotettujen Tor-palveluiden kautta: + &Window &Ikkuna @@ -1433,6 +1505,22 @@ Current number of blocks Nykyinen Lohkojen määrä + + Memory Pool + Muistiallas + + + Current number of transactions + Tämänhetkinen rahansiirtojen määrä + + + Memory usage + Muistin käyttö + + + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. + Avaa Bitcoin Coren debug-loki tämänhetkisestä datahakemistosta. Tämä voi viedä muutaman sekunnin suurille lokitiedostoille. + Received Vastaanotetut @@ -1445,10 +1533,18 @@ &Peers &Vertaiset + + Banned peers + Estetyt vertaiset + Select a peer to view detailed information. Valitse vertainen eriteltyjä tietoja varten. + + Whitelisted + Sallittu + Direction Suunta @@ -1457,6 +1553,18 @@ Version Versio + + Starting Block + Alkaen lohkosta + + + Synced Headers + Synkronoidut ylätunnisteet + + + Synced Blocks + Synkronoidut lohkot + User Agent Käyttöliittymä @@ -1485,6 +1593,14 @@ Ping Time Vasteaika + + The duration of a currently outstanding ping. + Tämänhetkisen merkittävän yhteyskokeilun kesto. + + + Ping Wait + Yhteyskokeilun odotus + Time Offset Ajan poikkeama @@ -1533,6 +1649,34 @@ Clear console Tyhjennä konsoli + + &Disconnect Node + &Katkaise yhteys solmukohtaan + + + Ban Node for + Estä solmukohta + + + 1 &hour + 1 &tunti + + + 1 &day + 1 &päivä + + + 1 &week + 1 &viikko + + + 1 &year + 1 &vuosi + + + &Unban Node + &Poista solmukohdan esto + Welcome to the Bitcoin Core RPC console. Tervetuloa Bitcoin Coren RPC-konsoliin. @@ -1561,6 +1705,10 @@ %1 GB %1 GB + + (node id: %1) + (solmukohdan id: %1) + via %1 %1 kautta @@ -1941,6 +2089,10 @@ Copy change Kopioi vaihtoraha + + Total Amount %1 + Kokonaismäärä %1 + or tai @@ -1973,10 +2125,22 @@ Payment request expired. Maksupyyntö on vanhentunut. + + Pay only the required fee of %1 + Maksa vain vaadittu kulu kooltaan %1 + + + Estimated to begin confirmation within %n block(s). + Vahvistuminen alkaa arviolta %n lohkon päästä.Vahvistuminen alkaa arviolta %n lohkon päästä. + The recipient address is not valid. Please recheck. Vastaanottajan osoite ei ole kelvollinen. Tarkistathan uudelleen. + + Duplicate address found: addresses should only be used once each. + Duplikaattiosoite löytyi: kutakin osoitetta pitäisi käyttää vain kerran. + Warning: Invalid Bitcoin address Varoitus: Virheellinen Bitcoin osoite @@ -2505,6 +2669,10 @@ Whether or not a watch-only address is involved in this transaction. Onko rahansiirrossa mukana ainoastaan katseltava osoite vai ei. + + User-defined intent/purpose of the transaction. + Käyttäjän määrittämä käyttötarkoitus rahansiirrolle. + Amount removed from or added to balance. Saldoon lisätty tai siitä vähennetty määrä. @@ -2584,6 +2752,10 @@ Copy transaction ID Kopioi siirtotunnus + + Copy raw transaction + Kopioi rahansiirron raakavedos + Edit label Muokkaa nimeä @@ -2731,10 +2903,22 @@ Accept command line and JSON-RPC commands Hyväksy merkkipohjaiset- ja JSON-RPC-käskyt + + If <category> is not supplied or if <category> = 1, output all debugging information. + Jos <category> on toimittamatta tai jos <category> = 1, tulosta kaikki debug-tieto. + + + Error: A fatal internal error occurred, see debug.log for details + Virhe: Kriittinen sisäinen virhe kohdattiin, katso debug.log lisätietoja varten + Run in the background as a daemon and accept commands Aja taustalla daemonina ja hyväksy komennot + + Unable to start HTTP server. See debug log for details. + HTTP-palvelinta ei voitu käynnistää. Katso debug-lokista lisätietoja. + Accept connections from outside (default: 1 if no -proxy or -connect) Hyväksy yhteyksiä ulkopuolelta (vakioasetus: 1 jos -proxy tai -connect ei määritelty) @@ -2759,6 +2943,18 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Ei voida yhdistää %s tässä tietokoneessa. Bitcoin Core on luultavasti jo käynnissä. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Käytä UPnP:ta kuuntelevan portin kartoitukseen (oletus: 1 kun kuunnellaan ja -proxy ei käytössä) + + + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) + VAROITUS: epätavallisen monta lohkoa generoitu, vastaanotettu %d lohkoa viimeisen %d tunnin aikana (odotettavissa %d) + + + WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) + VAROITUS: tarkista verkkoyhteytesi, vastaanotettu %d lohkoa viimeisen %d tunnin aikana (odotettavissa %d) + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. Varoitus: Tietoverkko ei ole sovussa! Luohijat näyttävät kokevan virhetilanteita. @@ -2772,8 +2968,8 @@ Varoitus: wallet.dat -lompakkotiedosto on korruptoitunut, tiedot pelastettu. Alkuperäinen wallet.dat -lompakkotiedosto on tallennettu wallet.{timestamp}.bak kansioon %s; jos balanssisi tai siirtohistoria on virheellinen, sinun tulisi palauttaa lompakkotiedosto varmuuskopiosta. - (default: 1) - (oletus: 1) + -maxmempool must be at least %d MB + -maxmempool on oltava vähintään %d MB <category> can be: @@ -2807,6 +3003,10 @@ Do you want to rebuild the block database now? Haluatko uudelleenrakentaa lohkotietokannan nyt? + + Enable publish raw transaction in <address> + Ota rahansiirtojen raakavedosten julkaisu käyttöön osoitteessa <address> + Error initializing block database Virhe alustaessa lohkotietokantaa @@ -2924,12 +3124,12 @@ Aktivoidaan parhainta ketjua... - Cannot resolve -whitebind address: '%s' - -whitebind -osoitetta '%s' ei voida jäsentää + Attempt to recover private keys from a corrupt wallet.dat on startup + Yritä palauttaa yksityiset avaimet korruptoituneesta wallet.dat-tiedostosta käynnistyksen yhteydessä - Choose data directory on startup (default: 0) - Valitse data-hakemisto käynnistyksessä (oletus: 0) + Cannot resolve -whitebind address: '%s' + -whitebind -osoitetta '%s' ei voida jäsentää Connect through SOCKS5 proxy @@ -2951,6 +3151,10 @@ Information Tietoa + + Invalid amount for -maxtxfee=<amount>: '%s' + Virheellinen määrä -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Virheellinen määrä -minrelaytxfee=<amount>: '%s' @@ -2971,26 +3175,18 @@ Receive and display P2P network alerts (default: %u) Vastaanota ja näytä P2P-verkon hälytyksiä (oletus: %u) + + Rescan the block chain for missing wallet transactions on startup + Uudelleenskannaa lohkoketju käynnistyksen yhteydessä puuttuvien lompakon rahansiirtojen vuoksi + Send trace/debug info to console instead of debug.log file Lähetä jäljitys/debug-tieto konsoliin, debug.log-tiedoston sijaan - - Set SSL root certificates for payment request (default: -system-) - Aseta SSL root varmenne maksupyynnöille (oletus: -system-) - - - Set language, for example "de_DE" (default: system locale) - Set language, for example "de_DE" (default: system locale) - Show all debugging options (usage: --help -help-debug) Näytä kaikki debuggaus valinnat: (käyttö: --help -help-debug) - - Show splash screen on startup (default: 1) - Näytä aloitusruutu käynnistettäessä (oletus: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Pienennä debug.log tiedosto käynnistyksen yhteydessä (vakioasetus: 1 kun ei -debug) @@ -3000,13 +3196,21 @@ Siirron vahvistus epäonnistui - Start minimized - Käynnistä pienennettynä + The transaction amount is too small to pay the fee + Rahansiirron määrä on liian pieni kattaakseen maksukulun This is experimental software. Tämä on ohjelmistoa kokeelliseen käyttöön. + + Tor control port password (default: empty) + Tor-hallintaportin salasana (oletus: tyhjä) + + + Tor control port to use if onion listening enabled (default: %s) + Tor-hallintaportti jota käytetään jos onion-kuuntelu on käytössä (oletus: %s) + Transaction amount too small Siirtosumma liian pieni @@ -3015,13 +3219,17 @@ Transaction amounts must be positive Siirtosumman tulee olla positiivinen + + Transaction too large for fee policy + Rahansiirto on liian suuri maksukulukäytännölle + Transaction too large Siirtosumma liian iso - UI Options: - Ulkoasun asetukset: + Upgrade wallet to latest format on startup + Päivitä lompakko viimeisimpään formaattiin käynnistyksen yhteydessä Username for JSON-RPC connections @@ -3035,10 +3243,18 @@ Warning Varoitus + + Whether to operate in a blocks only mode (default: %u) + Toimitaanko tilassa jossa ainoastaan lohkot sallitaan (oletus: %u) + Zapping all transactions from wallet... Tyhjennetään kaikki rahansiirrot lompakosta.... + + ZeroMQ notification options: + ZeroMQ-ilmoitusasetukset: + wallet.dat corrupt, salvage failed wallet.dat -lompakkotiedosto korruptoitunut, korjaaminen epäonnistui @@ -3067,6 +3283,14 @@ Error loading wallet.dat: Wallet corrupted Virhe ladattaessa wallet.dat-tiedostoa: Lompakko vioittunut + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Älä pidä rahansiirtoja muistivarannoissa kauemmin kuin <n> tuntia (oletus: %u) + + + How thorough the block verification of -checkblocks is (0-4, default: %u) + Kuinka läpikäyvä lohkojen -checkblocks -todennus on (0-4, oletus: %u) + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Käytä erillistä SOCKS5-proxyä tavoittaaksesi vertaisia Tor-piilopalveluiden kautta (oletus: %s) @@ -3095,6 +3319,10 @@ Invalid -proxy address: '%s' Virheellinen proxy-osoite '%s' + + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) + Kuuntele JSON-RPC-yhteyksiä portissa <port> (oletus: %u tai testnet: %u) + Listen for connections on <port> (default: %u or testnet: %u) Kuuntele yhteyksiä portissa <port> (oletus: %u tai testnet: %u) @@ -3103,6 +3331,18 @@ Make the wallet broadcast transactions Aseta lompakko kuuluttamaan rahansiirtoja + + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) + Maksimi yhteyttä kohden käytettävä vastaanottopuskurin koko, <n>*1000 tavua (oletus: %u) + + + Maximum per-connection send buffer, <n>*1000 bytes (default: %u) + Maksimi yhteyttä kohden käytettävä lähetyspuskurin koko, <n>*1000 tavua (oletus: %u) + + + Relay and mine data carrier transactions (default: %u) + Välitä ja louhi dataa kantavia rahansiirtoja (oletus: %u) + Relay non-P2SH multisig (default: %u) Välitä ei-P2SH-multisig (oletus: %u) diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index 97dccdac0..a0b9feb9a 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP/masque réseau + + + Banned Until + Banni jusqu'au + + BitcoinGUI @@ -725,6 +733,10 @@ This label turns red if the priority is smaller than "medium". Cette étiquette devient rouge si la priorité est plus basse que « moyenne ». + + This label turns red if any recipient receives an amount smaller than %1. + Cette étiquette devient rouge si un destinataire reçoit un montant inférieur à %1. + Can vary +/- %1 satoshi(s) per input. Peut varier +/- %1 satoshi(s) par entrée. @@ -870,6 +882,34 @@ command-line options options de ligne de commande + + UI Options: + Options de l'IU : + + + Choose data directory on startup (default: %u) + Choisir un répertoire de données au démarrage (par défaut : %u) + + + Set language, for example "de_DE" (default: system locale) + Définir la langue, par exemple « fr_CA » (par défaut : la langue du système) + + + Start minimized + Démarrer minimisé + + + Set SSL root certificates for payment request (default: -system-) + Définir les certificats SSL racine pour les requêtes de paiement (par défaut : -system-) + + + Show splash screen on startup (default: %u) + Afficher l'écran d'accueil au démarrage (par défaut : %u) + + + Reset all settings changes made over the GUI + Réinitialiser tous les changements de paramètres appliqués à l'IUG + Intro @@ -913,7 +953,11 @@ %n GB of free space available %n Go d'espace libre disponible%n Go d'espace libre disponibles - + + (of %n GB needed) + (sur %n Go nécessaire)(sur %n Go nécessaires) + + OpenURIDialog @@ -1063,6 +1107,34 @@ Port of the proxy (e.g. 9050) Port du serveur mandataire (par ex. 9050) + + Used for reaching peers via: + Utilisé pour rejoindre les pairs par : + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + S'affiche, si le mandataire SOCKS5 par défaut fourni est utilisé pour atteindre les pairs par ce type de réseau. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Se connecter au réseau Bitcoin au travers d'un mandataire SOCKS5 séparé pour les services cachés de Tor. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Utiliser un mandataire SOCKS5 séparé pour atteindre les pairs grâce aux services cachés de Tor : + &Window &Fenêtre @@ -1329,7 +1401,7 @@ %1 d - %1 d + %1 j %1 h @@ -1433,6 +1505,18 @@ Current number of blocks Nombre actuel de blocs + + Memory Pool + Réserve de mémoire + + + Current number of transactions + Nombre actuel de transactions + + + Memory usage + Utilisation de la mémoire + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Ouvrir le journal de débogage du répertoire de données actuel. Ceci pourrait prendre quelques secondes pour les gros fichiers de journalisation. @@ -1449,10 +1533,18 @@ &Peers &Pairs + + Banned peers + Pairs bannis + Select a peer to view detailed information. Choisir un pair pour voir l'information détaillée. + + Whitelisted + Dans la liste blanche + Direction Direction @@ -1461,6 +1553,18 @@ Version Version + + Starting Block + Bloc de départ + + + Synced Headers + En-têtes synchronisés + + + Synced Blocks + Blocs synchronisés + User Agent Agent utilisateur @@ -1489,6 +1593,14 @@ Ping Time Temps de ping + + The duration of a currently outstanding ping. + La durée d'un ping actuellement en cours. + + + Ping Wait + Attente du ping + Time Offset Décalage temporel @@ -1537,6 +1649,34 @@ Clear console Nettoyer la console + + &Disconnect Node + &Déconnecter le nœud + + + Ban Node for + Bannir le nœud pendant + + + 1 &hour + 1 &heure + + + 1 &day + 1 &jour + + + 1 &week + 1 &semaine + + + 1 &year + 1 &an + + + &Unban Node + &Réhabiliter le nœud + Welcome to the Bitcoin Core RPC console. Bienvenue dans le console RPC de Bitcoin Core. @@ -1565,6 +1705,10 @@ %1 GB %1 Go + + (node id: %1) + (ID de nœud : %1) + via %1 par %1 @@ -1957,6 +2101,10 @@ Copy change Copier la monnaie + + Total Amount %1 + Montant total %1 + or ou @@ -1989,6 +2137,10 @@ Payment request expired. Demande de paiement expirée. + + Pay only the required fee of %1 + Payer seulement les frais exigés de %1 + Estimated to begin confirmation within %n block(s). Il est estimé que la confirmation commencera dans %n bloc.Il est estimé que la confirmation commencera dans %n blocs. @@ -2624,6 +2776,10 @@ Copy transaction ID Copier l'ID de la transaction + + Copy raw transaction + Copier la transaction brute + Edit label Modifier l’étiquette @@ -2771,14 +2927,54 @@ Accept command line and JSON-RPC commands Accepter les commandes de JSON-RPC et de la ligne de commande + + If <category> is not supplied or if <category> = 1, output all debugging information. + Si <category> n'est pas indiqué ou si <category> = 1, extraire toutes les données de débogage. + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Frais totaux maximaux (en %s) à utiliser en une seule transaction de portefeuille. Les définir trop bas pourrait interrompre les grosses transactions (par défaut : %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Veuillez vérifier que l'heure et la date de votre ordinateur sont justes ! Si votre horloge n'est pas à l'heure, Bitcoin Core ne fonctionnera pas correctement. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + L'élagage est configuré au-dessous du minimum de %d Mio. Veuillez utiliser un nombre plus élevé. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Élagage : la dernière synchronisation de portefeuille va par-delà les données élaguées. Vous devez -reindex (réindexer, télécharger de nouveau toute la chaîne de blocs en cas de nœud élagué) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Réduire les exigences de stockage en élaguant (supprimant) les anciens blocs. Ce mode est incompatible avec -txindex et -rescan. Avertissement : ramener ce paramètre à sa valeur antérieure exige un nouveau téléchargement de la chaîne de blocs en entier (par défaut : 0 = désactiver l'élagage des blocs, >%u = taille cible en Mio à utiliser pour les fichiers de blocs). + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Les rebalayages sont impossibles en mode élagage. Vous devrez utiliser -reindex, ce qui téléchargera de nouveau la chaîne de blocs en entier. + Error: A fatal internal error occurred, see debug.log for details Erreur : une erreur interne fatale s'est produite. Voir debug.log pour plus de détails + + Fee (in %s/kB) to add to transactions you send (default: %s) + Les frais (en %s/ko) à ajouter aux transactions que vous envoyez (par défaut : %s) + + + Pruning blockstore... + Élagage du magasin de blocs... + Run in the background as a daemon and accept commands Fonctionner en arrière-plan en tant que démon et accepter les commandes + + Unable to start HTTP server. See debug log for details. + Impossible de démarrer le serveur HTTP. Voir le journal de débogage pour plus de détails. + Accept connections from outside (default: 1 if no -proxy or -connect) Accepter les connexions entrantes (par défaut : 1 si aucun -proxy ou -connect ) @@ -2789,7 +2985,7 @@ Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup - Supprimer toutes les transactions du portefeuille et ne récupérer que ces parties de la chaîne de bloc avec -rescan au démarrage + Supprimer toutes les transactions du portefeuille et ne récupérer que ces parties de la chaîne de blocs avec -rescan au démarrage Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. @@ -2803,6 +2999,10 @@ Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Définir le nombre d'exétrons de vérification des scripts (%u à %d, 0 = auto, < 0 = laisser ce nombre de cœurs inutilisés, par défaut : %d) + + The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct + La base de données de blocs contient un bloc qui semble provenir du futur. Cela pourrait être causé par la date et l'heure erronées de votre ordinateur. Ne reconstruisez la base de données de blocs que si vous êtes certain que la date et l'heure de votre ordinateur sont justes. + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Ceci est une pré-version de test - l'utiliser à vos risques et périls - ne pas l'utiliser pour miner ou pour des applications marchandes @@ -2811,6 +3011,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Impossible de se lier à %s sur cet ordinateur. Bitcoin Core fonctionne probablement déjà. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Utiliser l'UPnP pour mapper le port d'écoute (par défaut : 1 lors de l'écoute et pas de mandataire -proxy) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) AVERTISSEMENT : un nombre anormalement élevé de blocs a été généré, %d blocs reçus durant les %d dernières heures (%d attendus) @@ -2836,8 +3040,8 @@ Pairs de la liste blanche se connectant à partir du masque réseau ou de l'IP donné. Peut être spécifié plusieurs fois. - (default: 1) - (par défaut : 1) + -maxmempool must be at least %d MB + -maxmempool doit être d'au moins %d Mo <category> can be: @@ -2871,6 +3075,22 @@ Do you want to rebuild the block database now? Voulez-vous reconstruire la base de données des blocs maintenant ? + + Enable publish hash block in <address> + Activer la publication du bloc de hachage dans <address> + + + Enable publish hash transaction in <address> + Activer la publication de la transaction de hachage dans <address> + + + Enable publish raw block in <address> + Activer la publication du bloc brut dans <address> + + + Enable publish raw transaction in <address> + Activer la publication de la transaction brute dans <address> + Error initializing block database Erreur lors de l'initialisation de la base de données des blocs @@ -2907,6 +3127,10 @@ Invalid -onion address: '%s' Adresse -onion invalide : « %s » + + Keep the transaction memory pool below <n> megabytes (default: %u) + Garder la réserve de mémoire transactionnelle sous <n> mégaoctets (par défaut : %u) + Not enough file descriptors available. Pas assez de descripteurs de fichiers proposés. @@ -2935,10 +3159,26 @@ Specify wallet file (within data directory) Spécifiez le fichier de portefeuille (dans le répertoire de données) + + Unsupported argument -benchmark ignored, use -debug=bench. + Argument non pris en charge -benchmark ignoré, utiliser -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Argument non pris en charge -debugnet ignoré, utiliser -debug=net. + + + Unsupported argument -tor found, use -onion. + Argument non pris en charge -tor trouvé, utiliser -onion + Use UPnP to map the listening port (default: %u) Utiliser l'UPnP pour mapper le port d'écoute (par défaut : %u) + + User Agent comment (%s) contains unsafe characters. + Le commentaire d'agent utilisateur (%s) contient des caractères dangereux. + Verifying blocks... Vérification des blocs en cours... @@ -2995,6 +3235,10 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Exécuter une commande lorsqu'une alerte pertinente est reçue ou si nous voyons une bifurcation vraiment étendue (%s dans la commande est remplacé par le message) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Les frais (en %s/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour le relais, le minage et la création de transactions (par défaut : %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Si paytxfee n'est pas défini, inclure suffisamment de frais afin que les transactions commencent la confirmation en moyenne avant n blocs (par défaut : %u) @@ -3052,12 +3296,20 @@ Activation de la meilleure chaîne... - Cannot resolve -whitebind address: '%s' - Impossible de résoudre l'adresse -whitebind : « %s » + Always relay transactions received from whitelisted peers (default: %d) + Toujours relayer les transactions reçues des pairs de la liste blanche (par défaut : %d) - Choose data directory on startup (default: 0) - Choisir un répertoire de données au démarrage (par défaut : 0) + Attempt to recover private keys from a corrupt wallet.dat on startup + Tenter de récupérer les clefs privées d'un wallet.dat corrompu lors du démarrage + + + Automatically create Tor hidden service (default: %d) + Créer automatiquement un service caché Tor (par défaut : %d) + + + Cannot resolve -whitebind address: '%s' + Impossible de résoudre l'adresse -whitebind : « %s » Connect through SOCKS5 proxy @@ -3075,6 +3327,10 @@ Error reading from database, shutting down. Erreur de lecture de la base de données, fermeture en cours. + + Imports blocks from external blk000??.dat file on startup + Importe des blocs depuis un fichier blk000??.dat externe lors du démarrage + Information Informations @@ -3127,6 +3383,14 @@ Receive and display P2P network alerts (default: %u) Recevoir et afficher les alertes du réseau poste à poste (%u par défaut) + + Reducing -maxconnections from %d to %d, because of system limitations. + Réduction de -maxconnections de %d à %d, due aux restrictions du système + + + Rescan the block chain for missing wallet transactions on startup + Réanalyser la chaîne de blocs au démarrage, à la recherche de transactions de portefeuille manquantes + Send trace/debug info to console instead of debug.log file Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log @@ -3135,22 +3399,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Envoyer si possible les transactions comme étant sans frais (par défaut : %u) - - Set SSL root certificates for payment request (default: -system-) - Définir les certificats racine SSL pour les demandes de paiement (par défaut : -système-) - - - Set language, for example "de_DE" (default: system locale) - Définir la langue, par exemple « fr_CA » (par défaut : la langue du système) - Show all debugging options (usage: --help -help-debug) Montrer toutes les options de débogage (utilisation : --help --help-debug) - - Show splash screen on startup (default: 1) - Afficher la page de garde au démarrage (par défaut : 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Réduire le fichier debug.log lors du démarrage du client (par défaut : 1 lorsque -debug n'est pas présent) @@ -3159,10 +3411,6 @@ Signing transaction failed La signature de la transaction a échoué - - Start minimized - Démarrer minimisé - The transaction amount is too small to pay the fee Le montant de la transaction est trop bas pour que les frais soient payés @@ -3171,6 +3419,14 @@ This is experimental software. Ceci est un logiciel expérimental. + + Tor control port password (default: empty) + Mot de passe du port de contrôle Tor (par défaut : vide) + + + Tor control port to use if onion listening enabled (default: %s) + Port de contrôle Tor à utiliser si l'écoute onion est activée (par défaut :%s) + Transaction amount too small Montant de la transaction trop bas @@ -3187,14 +3443,14 @@ Transaction too large Transaction trop volumineuse - - UI Options: - Options de l'IU : - Unable to bind to %s on this computer (bind returned error %s) Impossible de se lier à %s sur cet ordinateur (bind a retourné l'erreur %s) + + Upgrade wallet to latest format on startup + Mettre à niveau le portefeuille au démarrage vers le format le plus récent + Username for JSON-RPC connections Nom d'utilisateur pour les connexions JSON-RPC @@ -3207,10 +3463,18 @@ Warning Avertissement + + Whether to operate in a blocks only mode (default: %u) + Faut-il fonctionner en mode blocs seulement (par défaut : %u) + Zapping all transactions from wallet... Supprimer toutes les transactions du portefeuille... + + ZeroMQ notification options: + Options de notification ZeroMQ + wallet.dat corrupt, salvage failed wallet.dat corrompu, la récupération a échoué @@ -3243,6 +3507,26 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = conserver les métadonnées de transmission, par ex. les informations du propriétaire du compte et de la demande de paiement, 2 = abandonner les métadonnées de transmission) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee est défini très haut ! Des frais aussi élevés pourraient être payés en une seule transaction. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee est réglé sur un montant très élevé ! Il s'agit des frais de transaction que vous payerez si vous envoyez une transaction. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Ne pas conserver de transactions dans la réserve de mémoire plus de <n> heures (par défaut : %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Une erreur est survenue lors de la lecture de wallet.dat ! Toutes les clefs ont été lues correctement, mais les données transactionnelles ou les entrées du carnet d'adresses sont peut-être manquantes ou incorrectes. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Les frais (en %s/Ko) inférieurs à ce seuil sont considérés comme étant nuls pour la création de transactions (par défaut : %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Degré de profondeur de la vérification des blocs -checkblocks (0-4, par défaut : %u) @@ -3259,10 +3543,30 @@ Output debugging information (default: %u, supplying <category> is optional) Extraire les informations de débogage (par défaut : %u, fournir <category> est optionnel) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Prendre en charge le filtrage des blocs et des transactions avec les filtres bloom (par défaut : %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + La taille totale de la chaîne de version de réseau (%i) dépasse la longueur maximale (%i). Réduire le nombre ou la taille des commentaires uacomments. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Tente de garder le trafic sortant sous la cible donnée (en Mio par 24 h), 0 = sans limite (par défaut : %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + L'argument non pris en charge -socks a été trouvé. Il n'est plus possible de définir la version de SOCKS, seuls les mandataires SOCKS5 sont pris en charge. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Utiliser un serveur mandataire SOCKS5 séparé pour atteindre les pairs par les services cachés de Tor (par défaut : %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Nom d'utilisateur et mot de passe haché pour les connexions JSON-RPC. Le champ <userpw> vient au format : <USERNAME>:<SALT>$<HASH>. Un script python canonique est inclus dans share/rpcuser. Cette option peut être spécifiée plusieurs fois. + (default: %s) (par défaut : %s) @@ -3335,6 +3639,10 @@ Set minimum block size in bytes (default: %u) Définir la taille de bloc minimale en octets (par défaut : %u) + + Set the number of threads to service RPC calls (default: %d) + Définir le nombre d'exétrons pour desservir les appels RPC (par défaut : %d) + Specify configuration file (default: %s) Spécifier le fichier de configuration (par défaut : %s) diff --git a/src/qt/locale/bitcoin_fr_CA.ts b/src/qt/locale/bitcoin_fr_CA.ts index 75f970f55..7e6925f96 100644 --- a/src/qt/locale/bitcoin_fr_CA.ts +++ b/src/qt/locale/bitcoin_fr_CA.ts @@ -13,6 +13,10 @@ &Delete &Supprimer + + Sending addresses + envoyer adresse de reception + Comma separated file (*.csv) Fichier séparé par une virgule (*.csv) @@ -75,6 +79,14 @@ CoinControlDialog + + (un)select all + Toute sélectionner + + + Copy address + copier l'adresse + (no label) (pas de record) @@ -82,6 +94,14 @@ EditAddressDialog + + &Label + Record + + + &Address + Addresse + FreespaceChecker @@ -91,6 +111,10 @@ Intro + + Welcome + Bienvenue + OpenURIDialog @@ -178,6 +202,10 @@ TransactionView + + Copy address + copier l'adresse + Comma separated file (*.csv) Fichier séparé par une virgule (*.csv) diff --git a/src/qt/locale/bitcoin_fr_FR.ts b/src/qt/locale/bitcoin_fr_FR.ts new file mode 100644 index 000000000..df6324335 --- /dev/null +++ b/src/qt/locale/bitcoin_fr_FR.ts @@ -0,0 +1,897 @@ + + + AddressBookPage + + Create a new address + Créer une nouvelle adresse + + + Copy the currently selected address to the system clipboard + Copier l'adresse surlignée dans votre presse-papiers + + + Export the data in the current tab to a file + Exporter les données de l'onglet courant vers un fichier + + + &Delete + &Supprimer + + + Comma separated file (*.csv) + Valeurs séparées par des virgules (*.csv) + + + + AddressTableModel + + Label + Étiquette + + + Address + Adresse + + + (no label) + (aucune étiquette) + + + + AskPassphraseDialog + + Enter passphrase + Entrez la phrase de passe + + + New passphrase + Nouvelle phrase de passe + + + Repeat new passphrase + Répétez la phrase de passe + + + Encrypt wallet + Chiffrer le porte-monnaie + + + This operation needs your wallet passphrase to unlock the wallet. + Cette opération nécessite votre phrase de passe pour déverrouiller le porte-monnaie. + + + Unlock wallet + Déverrouiller le porte-monnaie + + + This operation needs your wallet passphrase to decrypt the wallet. + Cette opération nécessite votre phrase de passe pour décrypter le porte-monnaie. + + + Decrypt wallet + Décrypter le porte-monnaie + + + Change passphrase + Changer la phrase de passe + + + Confirm wallet encryption + Confirmer le chiffrement du porte-monnaie + + + Wallet encrypted + Porte-monnaie chiffré + + + Wallet encryption failed + Le chiffrement du porte-monnaie a échoué + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Le chiffrement du porte-monnaie a échoué en raison d'une erreur interne. Votre porte-monnaie n'a pas été chiffré. + + + The supplied passphrases do not match. + Les phrases de passe entrées ne correspondent pas. + + + Wallet unlock failed + Le déverrouillage du porte-monnaie a échoué + + + The passphrase entered for the wallet decryption was incorrect. + La phrase de passe entrée pour décrypter le porte-monnaie était erronée. + + + Wallet decryption failed + Le décryptage du porte-monnaie a échoué + + + + BanTableModel + + + BitcoinGUI + + Synchronizing with network... + Synchronisation avec le réseau... + + + &Overview + &Vue d'ensemble + + + Show general overview of wallet + Affiche une vue d'ensemble du porte-monnaie + + + &Transactions + &Transactions + + + Browse transaction history + Permet de parcourir l'historique des transactions + + + E&xit + Qui&tter + + + Quit application + Quitter l'application + + + About &Qt + À propos de &Qt + + + Show information about Qt + Afficher des informations sur Qt + + + &Options... + &Options... + + + Backup wallet to another location + Sauvegarder le porte-monnaie à un autre emplacement + + + Change the passphrase used for wallet encryption + Modifier la phrase de passe utilisée pour le cryptage du porte-monnaie + + + Bitcoin + Bitcoin + + + &Send + &Envoyer + + + &File + &Fichier + + + &Settings + &Réglages + + + &Help + &Aide + + + Tabs toolbar + Barre d'outils des onglets + + + Up to date + À jour + + + Catching up... + Rattrapage... + + + Sent transaction + Transaction envoyée + + + Incoming transaction + Transaction entrante + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Le porte-monnaie est <b>chiffré</b> et est actuellement <b>déverrouillé</b> + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Le porte-monnaie est <b>chiffré</b> et est actuellement <b>verrouillé</b> + + + + ClientModel + + + CoinControlDialog + + Amount: + Montant : + + + Amount + Montant + + + Date + Date + + + Confirmed + Confirmée + + + Copy address + Copier l'adresse + + + Copy label + Copier l'étiquette + + + Copy amount + Copier le montant + + + (no label) + (aucune étiquette) + + + + EditAddressDialog + + Edit Address + Éditer l'adresse + + + &Label + &Étiquette + + + &Address + &Adresse + + + New receiving address + Nouvelle adresse de réception + + + New sending address + Nouvelle adresse d'envoi + + + Edit receiving address + Éditer l'adresse de réception + + + Edit sending address + Éditer l'adresse d'envoi + + + The entered address "%1" is already in the address book. + L'adresse fournie « %1 » est déjà présente dans le carnet d'adresses. + + + Could not unlock wallet. + Impossible de déverrouiller le porte-monnaie. + + + New key generation failed. + Échec de la génération de la nouvelle clef. + + + + FreespaceChecker + + + HelpMessageDialog + + Usage: + Utilisation : + + + + Intro + + + OpenURIDialog + + + OptionsDialog + + Options + Options + + + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Ouvrir le port du client Bitcoin automatiquement sur le routeur. Cela ne fonctionne que si votre routeur supporte l'UPnP et si la fonctionnalité est activée. + + + Map port using &UPnP + Ouvrir le port avec l'&UPnP + + + &Minimize to the tray instead of the taskbar + &Minimiser dans la barre système au lieu de la barre des tâches + + + M&inimize on close + Mi&nimiser lors de la fermeture + + + + OverviewPage + + Form + Formulaire + + + + PaymentServer + + + PeerTableModel + + + QObject + + Amount + Montant + + + + QRImageWidget + + + RPCConsole + + Name + Nom + + + + ReceiveCoinsDialog + + &Amount: + Montant : + + + &Label: + &Étiquette : + + + &Message: + Message : + + + Copy label + Copier l'étiquette + + + Copy amount + Copier le montant + + + + ReceiveRequestDialog + + QR Code + QR Code + + + Address + Adresse + + + Amount + Montant + + + Label + Étiquette + + + Message + Message + + + + RecentRequestsTableModel + + Date + Date + + + Label + Étiquette + + + Message + Message + + + Amount + Montant + + + (no label) + (aucune étiquette) + + + + SendCoinsDialog + + Send Coins + Envoyer des pièces + + + Insufficient funds! + Fonds insuffisants + + + Amount: + Montant : + + + Send to multiple recipients at once + Envoyer des pièces à plusieurs destinataires à la fois + + + Balance: + Solde : + + + Confirm the send action + Confirmer l'action d'envoi + + + Confirm send coins + Confirmer l'envoi des pièces + + + Copy amount + Copier le montant + + + The amount to pay must be larger than 0. + Le montant à payer doit être supérieur à 0. + + + (no label) + (aucune étiquette) + + + + SendCoinsEntry + + A&mount: + &Montant : + + + Pay &To: + Payer &à : + + + Enter a label for this address to add it to your address book + Entrez une étiquette pour cette adresse afin de l'ajouter à votre carnet d'adresses + + + &Label: + &Étiquette : + + + Alt+A + Alt+A + + + Paste address from clipboard + Coller une adresse depuis le presse-papiers + + + Alt+P + Alt+P + + + Message: + Message : + + + Pay To: + Payer à : + + + + ShutdownWindow + + + SignVerifyMessageDialog + + &Sign Message + &Signer le message + + + Alt+A + Alt+A + + + Paste address from clipboard + Coller une adresse depuis le presse-papiers + + + Alt+P + Alt+P + + + Enter the message you want to sign here + Entrez ici le message que vous désirez signer + + + Sign &Message + &Signer le message + + + + SplashScreen + + [testnet] + [testnet] + + + + TrafficGraphWidget + + + TransactionDesc + + Open until %1 + Ouvert jusqu'à %1 + + + %1/unconfirmed + %1/non confirmée + + + %1 confirmations + %1 confirmations + + + Status + État + + + Date + Date + + + Generated + Généré + + + Credit + Crédit + + + Debit + Débit + + + Message + Message + + + Amount + Montant + + + , has not been successfully broadcast yet + , n'a pas encore été diffusée avec succès + + + unknown + inconnue + + + + TransactionDescDialog + + Transaction details + Détails de la transaction + + + This pane shows a detailed description of the transaction + Ce panneau affiche une description détaillée de la transaction + + + + TransactionTableModel + + Date + Date + + + Type + Type + + + Open until %1 + Ouvert jusqu'à %1 + + + Confirmed (%1 confirmations) + Confirmée (%1 confirmations) + + + This block was not received by any other nodes and will probably not be accepted! + Ce bloc n'a été reçu par aucun autre nœud et ne sera probablement pas accepté ! + + + Generated but not accepted + Généré mais pas accepté + + + Label + Étiquette + + + Received with + Reçues avec + + + Received from + Reçue de + + + Sent to + Envoyées à + + + Payment to yourself + Paiement à vous-même + + + Mined + Extraction + + + (n/a) + (indisponible) + + + Transaction status. Hover over this field to show number of confirmations. + État de la transaction. Laissez le pointeur de la souris sur ce champ pour voir le nombre de confirmations. + + + Date and time that the transaction was received. + Date et heure de réception de la transaction. + + + Type of transaction. + Type de transaction. + + + Amount removed from or added to balance. + Montant ajouté au ou enlevé du solde. + + + + TransactionView + + All + Toutes + + + Today + Aujourd'hui + + + This week + Cette semaine + + + This month + Ce mois + + + Last month + Mois dernier + + + This year + Cette année + + + Range... + Intervalle... + + + Received with + Reçues avec + + + Sent to + Envoyées à + + + To yourself + À vous-même + + + Mined + Extraction + + + Other + Autres + + + Enter address or label to search + Entrez une adresse ou une étiquette à rechercher + + + Min amount + Montant min + + + Copy address + Copier l'adresse + + + Copy label + Copier l'étiquette + + + Copy amount + Copier le montant + + + Edit label + Éditer l'étiquette + + + Comma separated file (*.csv) + Valeurs séparées par des virgules (*.csv) + + + Confirmed + Confirmée + + + Date + Date + + + Type + Type + + + Label + Étiquette + + + Address + Adresse + + + ID + ID + + + Range: + Intervalle : + + + to + à + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + Send Coins + Envoyer des pièces + + + + WalletView + + Export the data in the current tab to a file + Exporter les données de l'onglet courant vers un fichier + + + Backup Wallet + Sauvegarder le porte-monnaie + + + Wallet Data (*.dat) + Données de porte-monnaie (*.dat) + + + Backup Failed + La sauvegarde a échoué + + + + bitcoin-core + + Options: + Options : + + + Specify data directory + Spécifier le répertoire de données + + + Accept command line and JSON-RPC commands + Accepter les commandes de JSON-RPC et de la ligne de commande + + + Run in the background as a daemon and accept commands + Fonctionner en arrière-plan en tant que démon et accepter les commandes + + + Send trace/debug info to console instead of debug.log file + Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log + + + Username for JSON-RPC connections + Nom d'utilisateur pour les connexions JSON-RPC + + + Password for JSON-RPC connections + Mot de passe pour les connexions JSON-RPC + + + This help message + Ce message d'aide + + + Loading addresses... + Chargement des adresses... + + + Error loading wallet.dat: Wallet corrupted + Erreur lors du chargement de wallet.dat : porte-monnaie corrompu + + + Error loading wallet.dat + Erreur lors du chargement de wallet.dat + + + Insufficient funds + Fonds insuffisants + + + Loading block index... + Chargement de l'index des blocs... + + + Loading wallet... + Chargement du porte-monnaie... + + + Rescanning... + Nouvelle analyse... + + + Done loading + Chargement terminé + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_gl.ts b/src/qt/locale/bitcoin_gl.ts index 79f0d46d3..96d4adeba 100644 --- a/src/qt/locale/bitcoin_gl.ts +++ b/src/qt/locale/bitcoin_gl.ts @@ -261,6 +261,10 @@ &Change Passphrase... &Cambiar contrasinal... + + &Receiving addresses... + Direccións para recibir + Importing blocks from disk... Importando bloques de disco... @@ -369,6 +373,10 @@ Open a bitcoin: URI or payment request Abrir un bitcoin: URI ou solicitude de pago + + &Command-line options + Opcións da liña de comandos + No block source available... Non hai orixe de bloques dispoñible... @@ -696,7 +704,7 @@ command-line options opcións da liña de comandos - + Intro @@ -765,6 +773,10 @@ &Network &Rede + + W&allet + Moedeiro + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. Abrir automáticamente o porto do cliente Bitcoin no router. Esto so funciona se o teu router soporta UPnP e está habilitado. @@ -967,6 +979,10 @@ &Information &Información + + Debug window + Ventana de Depuración + Using OpenSSL version Usar versión OpenSSL @@ -1187,6 +1203,10 @@ Send Coins Moedas Enviadas + + Insufficient funds! + Fondos insuficientes + Quantity: Cantidade: @@ -1211,6 +1231,10 @@ Change: Cambiar: + + Transaction Fee: + Tarifa de transacción: + Send to multiple recipients at once Enviar a múltiples receptores á vez @@ -1350,6 +1374,10 @@ Remove this entry Eliminar esta entrada + + Message: + Mensaxe: + Enter a label for this address to add it to the list of used addresses Introduce unha etiqueta para esta dirección para engadila á listaxe de direccións empregadas @@ -2042,13 +2070,17 @@ Executar comando cando se recibe unha alerta relevante ou vemos un fork realmente longo (%s no cmd é substituído pola mensaxe) - Choose data directory on startup (default: 0) - Escolle directorio de datos ao arrancar (por defecto: 0) + Cannot resolve -whitebind address: '%s' + Non se pode resolver dirección -whitebind: '%s' Information Información + + Invalid amount for -maxtxfee=<amount>: '%s' + Cantidade inválida para -maxtxfee=<cantidade>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Cantidade inválida para -minrelaytxfee=<cantidade>: '%s' @@ -2061,14 +2093,6 @@ Send trace/debug info to console instead of debug.log file Enviar traza/información de depuración á consola en lugar de ao arquivo debug.log - - Set language, for example "de_DE" (default: system locale) - Fixar idioma, por exemplo "de_DE" (por defecto: locale del sistema) - - - Show splash screen on startup (default: 1) - Amosar pantalla splash no arranque (por defecto: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Recortar o arquivo debug.log ao arrancar o cliente (por defecto: 1 cando no-debug) @@ -2077,10 +2101,6 @@ Signing transaction failed Fallou a sinatura da transacción - - Start minimized - Comezar minimizado - Transaction amount too small A cantidade da transacción é demasiado pequena diff --git a/src/qt/locale/bitcoin_gu_IN.ts b/src/qt/locale/bitcoin_gu_IN.ts deleted file mode 100644 index 5de6a6109..000000000 --- a/src/qt/locale/bitcoin_gu_IN.ts +++ /dev/null @@ -1,113 +0,0 @@ - - - AddressBookPage - - - AddressTableModel - - - AskPassphraseDialog - - - BanTableModel - - - BitcoinGUI - - - ClientModel - - - CoinControlDialog - - - EditAddressDialog - - - FreespaceChecker - - - HelpMessageDialog - - - Intro - - - OpenURIDialog - - - OptionsDialog - - - OverviewPage - - - PaymentServer - - - PeerTableModel - - - QObject - - - QRImageWidget - - - RPCConsole - - - ReceiveCoinsDialog - - - ReceiveRequestDialog - - - RecentRequestsTableModel - - - SendCoinsDialog - - - SendCoinsEntry - - - ShutdownWindow - - - SignVerifyMessageDialog - - - SplashScreen - - - TrafficGraphWidget - - - TransactionDesc - - - TransactionDescDialog - - - TransactionTableModel - - - TransactionView - - - UnitDisplayStatusBarControl - - - WalletFrame - - - WalletModel - - - WalletView - - - bitcoin-core - - \ No newline at end of file diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts index 048b26820..926d20620 100644 --- a/src/qt/locale/bitcoin_he.ts +++ b/src/qt/locale/bitcoin_he.ts @@ -417,6 +417,10 @@ %1 and %2 %1 ו%2 + + %1 behind + %1 מאחור + Last received block was generated %1 ago. המקטע האחרון שהתקבל נוצר לפני %1. @@ -623,6 +627,10 @@ lowest הנמוך ביותר + + (%1 locked) + (%1 נעול) + none ללא @@ -772,7 +780,7 @@ command-line options אפשרויות שורת פקודה - + Intro @@ -1659,6 +1667,10 @@ Custom change address כתובת לעודף מותאמת אישית + + Transaction Fee: + עמלת העברה: + Send to multiple recipients at once שליחה למספר מוטבים בו־זמנית @@ -2517,10 +2529,6 @@ 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. אזהרה: הקובץ wallet.dat הושחת, המידע חולץ! קובץ ה־wallet.dat המקורי נשמר בשם wallet.{timestamp}.bak במיקום %s; אם המאזן או ההעברות שגויים עליך לשחזר גיבוי. - - (default: 1) - (בררת מחדל: 1) - <category> can be: <קטגוריה> יכולה להיות: @@ -2637,10 +2645,6 @@ Cannot resolve -whitebind address: '%s' לא ניתן לפתור את הכתובת ‎-whitebind:‏ '%s' - - Choose data directory on startup (default: 0) - בחירת תיקיית נתונים עם ההפעלה (בררת מחדל: 0) - Connect through SOCKS5 proxy התחברות דרך מתווך SOCKS5 @@ -2661,6 +2665,10 @@ Initialization sanity check failed. Bitcoin Core is shutting down. בדיקת התקינות ההתחלתית נכשלה. ליבת ביטקוין תיסגר כעת. + + Invalid amount for -maxtxfee=<amount>: '%s' + כמות לא תקינה עבור -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' כמות לא תקינה עבור -paytxfee=<amount>: '%s' @@ -2693,22 +2701,10 @@ Send trace/debug info to console instead of debug.log file שלח מידע דיבאג ועקבה לקונסולה במקום לקובץ debug.log - - Set SSL root certificates for payment request (default: -system-) - הגדרות אישורי בסיס של SSL לבקשות תשלום (בררת המחדל: -מערכת-) - - - Set language, for example "de_DE" (default: system locale) - הגדרת שפה, למשל „he_il“ (בררת מחדל: שפת המערכת) - Show all debugging options (usage: --help -help-debug) הצגת כל אפשרויות הניפוי (שימוש: ‎--help -help-debug) - - Show splash screen on startup (default: 1) - הצגת מסך פתיחה בעת הפעלה (בררת מחדל: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) כיווץ הקובץ debug.log בהפעלת הלקוח (בררת מחדל: 1 ללא ‎-debug) @@ -2717,10 +2713,6 @@ Signing transaction failed החתימה על ההעברה נכשלה - - Start minimized - התחלה במצב ממוזער - This is experimental software. זוהי תכנית נסיונית. diff --git a/src/qt/locale/bitcoin_hi_IN.ts b/src/qt/locale/bitcoin_hi_IN.ts index fbdaf1ba7..377ff3a3f 100644 --- a/src/qt/locale/bitcoin_hi_IN.ts +++ b/src/qt/locale/bitcoin_hi_IN.ts @@ -334,6 +334,10 @@ Options विकल्प + + W&allet + वॉलेट + &OK &ओके @@ -385,6 +389,10 @@ ReceiveCoinsDialog + + &Amount: + राशि : + &Label: लेबल: @@ -400,6 +408,10 @@ ReceiveRequestDialog + + Copy &Address + &पता कॉपी करे + Address पता @@ -501,6 +513,10 @@ Alt+P Alt-P + + Pay To: + प्राप्तकर्ता: + ShutdownWindow diff --git a/src/qt/locale/bitcoin_hr.ts b/src/qt/locale/bitcoin_hr.ts index aa28ecf24..413dc2185 100644 --- a/src/qt/locale/bitcoin_hr.ts +++ b/src/qt/locale/bitcoin_hr.ts @@ -774,7 +774,7 @@ command-line options opcije programa u naredbenoj liniji - + Intro @@ -1013,6 +1013,10 @@ &Information &Informacije + + Debug window + Konzola za dijagnostiku + Using OpenSSL version OpenSSL verzija u upotrebi @@ -1213,6 +1217,10 @@ Send Coins Slanje novca + + Insufficient funds! + Nedovoljna sredstva + Quantity: Količina: @@ -1237,6 +1245,10 @@ Change: Vraćeno: + + Transaction Fee: + Naknada za transakciju: + Send to multiple recipients at once Pošalji novce većem broju primatelja u jednoj transakciji @@ -1366,6 +1378,10 @@ Signature Potpis + + Sign &Message + &Potpišite poruku + Clear &All Obriši &sve @@ -1374,6 +1390,10 @@ &Verify Message &Potvrdite poruku + + Verify &Message + &Potvrdite poruku + Wallet unlock was cancelled. Otključavanje novčanika je otkazano. @@ -1780,12 +1800,20 @@ Informacija - Send trace/debug info to console instead of debug.log file - Šalji trace/debug informacije na konzolu umjesto u debug.log datoteku + Invalid amount for -maxtxfee=<amount>: '%s' + Nevaljali iznos za opciju -maxtxfee=<iznos>: '%s' - Start minimized - Pokreni minimiziran + Invalid amount for -minrelaytxfee=<amount>: '%s' + Nevaljali iznos za opciju -minrelaytxfee=<iznos>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + Nevaljali iznos za opciju -mintxfee=<iznos>: '%s' + + + Send trace/debug info to console instead of debug.log file + Šalji trace/debug informacije na konzolu umjesto u debug.log datoteku Username for JSON-RPC connections diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index 27cfedc72..ab4517ccf 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -866,7 +866,7 @@ command-line options parancssoros opciók - + Intro @@ -1011,6 +1011,18 @@ Port of the proxy (e.g. 9050) Proxy portja (pl.: 9050) + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + &Window &Ablak @@ -1277,6 +1289,10 @@ Current number of blocks Aktuális blokkok száma + + Memory usage + Memóriahasználat + Received Fogadott @@ -1365,6 +1381,22 @@ Clear console Konzol törlése + + 1 &hour + 1 &óra + + + 1 &day + 1 &nap + + + 1 &week + 1 &hét + + + 1 &year + 1 &év + Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. Navigálhat a fel és le nyilakkal, és <b>Ctrl-L</b> -vel törölheti a képernyőt. @@ -1621,6 +1653,14 @@ Hide Elrejtés + + Recommended: + Ajánlott: + + + Custom: + Egyéni: + normal normál @@ -1773,6 +1813,10 @@ Message: Üzenet: + + Pay To: + Címzett: + Memo: Jegyzet: @@ -1843,6 +1887,10 @@ &Verify Message Üzenet ellenőrzése + + Verify &Message + Üzenet ellenőrzése + The entered address is invalid. A megadott cím nem érvényes. @@ -2185,6 +2233,10 @@ Show transaction details Tranzakciós részletek megjelenítése + + Watch-only + Csak megfigyelés + Exporting Failed Az exportálás sikertelen volt @@ -2373,8 +2425,8 @@ Az adatbázist újra kell építeni -reindex használatával (módosítás -tindex). - Choose data directory on startup (default: 0) - Adatkönyvtár kiválasztása induláskor (alapbeállítás: 0) + Cannot resolve -whitebind address: '%s' + Külső cím (-whitebind address) feloldása nem sikerült: '%s' Copyright (C) 2009-%i The Bitcoin Core Developers @@ -2388,6 +2440,10 @@ Information Információ + + Invalid amount for -maxtxfee=<amount>: '%s' + Érvénytelen -maxtxfee=<amount>: '%s' összeg + Invalid amount for -minrelaytxfee=<amount>: '%s' Érvénytelen -minrelaytxfee=<amount>: '%s' összeg @@ -2400,27 +2456,10 @@ Send trace/debug info to console instead of debug.log file trace/debug információ küldése a konzolra a debog.log fájl helyett - - Set SSL root certificates for payment request (default: -system-) - SLL gyökér-igazolások megadása fizetési kérelmekhez (alapértelmezett: -system-) - - - Set language, for example "de_DE" (default: system locale) - Nyelvbeállítás, például "de_DE" (alapértelmezett: rendszer nyelve) - - - Show splash screen on startup (default: 1) - Indítóképernyő mutatása induláskor (alapértelmezett: 1) - Signing transaction failed Tranzakció aláírása sikertelen - - Start minimized - Indítás lekicsinyítve - - This is experimental software. Ez egy kísérleti szoftver. @@ -2437,10 +2476,6 @@ Transaction too large Túl nagy tranzakció - - UI Options: - Kezelőfelület beállításai: - Username for JSON-RPC connections Felhasználói név JSON-RPC csatlakozásokhoz diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts index 22ce3efec..1b626fbf2 100644 --- a/src/qt/locale/bitcoin_id_ID.ts +++ b/src/qt/locale/bitcoin_id_ID.ts @@ -253,6 +253,10 @@ &Options... &Pilihan... + + &Encrypt Wallet... + &Enkripsi Dompet... + &Backup Wallet... &Cadangkan Dompet... @@ -794,6 +798,10 @@ About Bitcoin Core Mengenai Bitcoin Core + + Command-line options + pilihan Perintah-baris + Usage: Penggunaan: @@ -802,7 +810,7 @@ command-line options pilihan perintah-baris - + Intro @@ -1555,6 +1563,10 @@ Custom change address Alamat uang kembali yang kustom + + Transaction Fee: + Biaya Transaksi: + Recommended: Disarankan @@ -1583,6 +1595,10 @@ Clear all fields of the form. Hapus informasi dari form. + + Clear &All + Hapus &Semua + Balance: Saldo: @@ -1804,6 +1820,10 @@ Reset all sign message fields Hapus semua bidang penanda pesan + + Clear &All + Hapus &Semua + &Verify Message &Verifikasi Pesan @@ -2361,10 +2381,6 @@ Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. Peringatan: Kami tidak bersetujuh dengan peer-peer kami! Kemungkinan Anda harus upgrade, atau node-node lain yang harus diupgrade. - - (default: 1) - (pengaturan awal: 1) - Block creation options: Pilihan pembuatan blok: @@ -2457,6 +2473,10 @@ Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. Tidak bisa mengunci data directory %s. Kemungkinan Bitcoin Core sudah mulai. + + Cannot resolve -whitebind address: '%s' + Tidak dapat menyelesaikan alamat -whitebind: '%s' + Connect through SOCKS5 proxy Hubungkan melalui proxy SOCKS5 @@ -2465,6 +2485,10 @@ Information Informasi + + Invalid amount for -maxtxfee=<amount>: '%s' + Nilai salah untuk -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Nilai yang salah untuk -minrelaytxfee=<amount>: '%s' @@ -2481,14 +2505,6 @@ Send trace/debug info to console instead of debug.log file Kirim info jejak/debug ke konsol bukan berkas debug.log - - Set language, for example "de_DE" (default: system locale) - Atur bahasa, sebagai contoh "id_ID" (standar: system locale) - - - Show splash screen on startup (default: 1) - Tampilkan layar pembuka saat nyala (standar: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Mengecilkan berkas debug.log saat klien berjalan (Standar: 1 jika tidak -debug) @@ -2497,10 +2513,6 @@ Signing transaction failed Tandatangani transaksi tergagal - - Start minimized - Memulai terminimalisi - Transaction amount too small Nilai transaksi terlalu kecil diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index 7a2b7bd84..d510b1063 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP/Netmask + + + Banned Until + Bannato fino a + + BitcoinGUI @@ -874,6 +882,34 @@ command-line options opzioni della riga di comando + + UI Options: + Opzioni interfaccia: + + + Choose data directory on startup (default: %u) + Seleziona la directory dei dati all'avvio (default: %u) + + + Set language, for example "de_DE" (default: system locale) + Imposta la lingua, ad esempio "it_IT" (default: locale di sistema) + + + Start minimized + Avvia ridotto a icona + + + Set SSL root certificates for payment request (default: -system-) + Imposta un certificato SSL root per le richieste di pagamento (default: -system-) + + + Show splash screen on startup (default: %u) + Mostra schermata iniziale all'avvio (default: %u) + + + Reset all settings changes made over the GUI + Reset di tutte le modifiche alle impostazioni eseguite da interfaccia grafica + Intro @@ -913,7 +949,11 @@ Error Errore - + + (of %n GB needed) + (di %nGB richiesti)(%n GB richiesti) + + OpenURIDialog @@ -1064,6 +1104,34 @@ Per specificare più URL separarli con una barra verticale "|". Port of the proxy (e.g. 9050) Porta del proxy (ad es. 9050) + + Used for reaching peers via: + Utilizzata per connettersi attraverso: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Mostra se la proxy SOCKS5 fornita viene utilizzata per raggiungere i peers attraverso questo tipo di rete. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Connette alla rete Bitcoin attraverso un proxy SOCKS5 separato per Tor. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Usa un proxy SOCKS5 separato per connettersi ai peers attraverso Tor: + &Window &Finestra @@ -1434,6 +1502,18 @@ Per specificare più URL separarli con una barra verticale "|". Current number of blocks Numero attuale di blocchi + + Memory Pool + Memory Pool + + + Current number of transactions + Numero attuale di transazioni + + + Memory usage + Utilizzo memoria + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Apre il file log di debug di Bitcoin Core dalla cartella dati attuale. Questa azione può richiedere alcuni secondi per file log di grandi dimensioni. @@ -1450,10 +1530,18 @@ Per specificare più URL separarli con una barra verticale "|". &Peers &Peer + + Banned peers + Peers bannati + Select a peer to view detailed information. Seleziona un peer per visualizzare informazioni più dettagliate. + + Whitelisted + Whitelisted/sicuri + Direction Direzione @@ -1462,6 +1550,18 @@ Per specificare più URL separarli con una barra verticale "|". Version Versione + + Starting Block + Blocco di partenza + + + Synced Headers + Headers sincronizzati + + + Synced Blocks + Blocchi sincronizzati + User Agent User Agent @@ -1490,6 +1590,14 @@ Per specificare più URL separarli con una barra verticale "|". Ping Time Tempo di Ping + + The duration of a currently outstanding ping. + La durata di un ping attualmente in corso. + + + Ping Wait + Attesa ping + Time Offset Scarto Temporale @@ -1538,6 +1646,34 @@ Per specificare più URL separarli con una barra verticale "|". Clear console Cancella console + + &Disconnect Node + &Nodo Disconnesso + + + Ban Node for + Nodo Bannato perché + + + 1 &hour + 1 &ora + + + 1 &day + 1 &giorno + + + 1 &week + 1 &settimana + + + 1 &year + 1 &anno + + + &Unban Node + &Elimina Ban Nodo + Welcome to the Bitcoin Core RPC console. Benvenuto nella console RPC di Bitcoin Core. @@ -1566,6 +1702,10 @@ Per specificare più URL separarli con una barra verticale "|". %1 GB %1 GB + + (node id: %1) + (id nodo: %1) + via %1 via %1 @@ -1958,6 +2098,10 @@ Per specificare più URL separarli con una barra verticale "|". Copy change Copia resto + + Total Amount %1 + Ammontare Totale %1 + or o @@ -1990,6 +2134,14 @@ Per specificare più URL separarli con una barra verticale "|". Payment request expired. Richiesta di pagamento scaduta. + + Pay only the required fee of %1 + Paga solamente la commissione richiesta di %1 + + + Estimated to begin confirmation within %n block(s). + Inizio delle conferme stimato entro %n blocco.Inizio delle conferme stimato entro %n blocchi. + The recipient address is not valid. Please recheck. L'indirizzo del beneficiario non è valido. Si prega di ricontrollare. @@ -2621,6 +2773,10 @@ Per specificare più URL separarli con una barra verticale "|". Copy transaction ID Copia l'ID transazione + + Copy raw transaction + Copia la transazione raw + Edit label Modifica l'etichetta @@ -2768,14 +2924,54 @@ Per specificare più URL separarli con una barra verticale "|". Accept command line and JSON-RPC commands Accetta comandi da riga di comando e JSON-RPC + + If <category> is not supplied or if <category> = 1, output all debugging information. + Se <category> non è specificato oppure se <category> = 1, mostra tutte le informazioni di debug. + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Totale massimo di commissioni (in %s) da usare in una singola transazione del wallet; valori troppo bassi possono abortire grandi transazioni (default: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Per favore controllate che la data del computer e l'ora siano corrette. Se il vostro orologio è sbagliato Bitcoin non funzionerà correttamente. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + La modalità prune è configurata al di sotto del minimo di %d MB. Si prega di utilizzare un valore più elevato. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Prune: l'ultima sincronizzazione del wallet risulta essere oltre la riduzione dei dati. È necessario eseguire un -reindex (scaricare nuovamente la blockchain in caso di nodo pruned) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Riduce i requisiti di spazio di archiviazione attraverso la rimozione dei vecchi blocchi (pruning). Questa modalità è incompatibile con l'opzione -txindex e -rescan. Attenzione: ripristinando questa opzione l'intera blockchain dovrà essere riscaricata. (default: 0 = disabilita il pruning, >%u = dimensione desiderata in MiB per i file dei blocchi) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Non è possibile un Rescan in modalità pruned. Sarà necessario utilizzare -reindex che farà scaricare nuovamente tutta la blockchain. + Error: A fatal internal error occurred, see debug.log for details Errore: si è presentato un errore interno fatale, consulta il file debug.log per maggiori dettagli + + Fee (in %s/kB) to add to transactions you send (default: %s) + Commissione (in %s/kB) da aggiungere alle transazioni inviate (default: %s) + + + Pruning blockstore... + Pruning del blockstore... + Run in the background as a daemon and accept commands Esegui in background come demone ed accetta i comandi + + Unable to start HTTP server. See debug log for details. + Impossibile avviare il server HTTP. Dettagli nel log di debug. + Accept connections from outside (default: 1 if no -proxy or -connect) Accetta connessioni dall'esterno (predefinito: 1 se -proxy o -connect non sono utilizzati) @@ -2800,6 +2996,10 @@ Per specificare più URL separarli con una barra verticale "|". Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Imposta il numero di thread per la verifica degli script (da %u a %d, 0 = automatico, <0 = lascia questo numero di core liberi, predefinito: %d) + + The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct + Il database dei blocchi contiene un blocco che sembra provenire dal futuro. Questo può essere dovuto alla data e ora del tuo computer impostate in modo scorretto. Ricostruisci il database dei blocchi se sei certo che la data e l'ora sul tuo computer siano corrette + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Questa versione è una compilazione pre-rilascio - usala a tuo rischio - non utilizzarla per la generazione o per applicazioni di commercio @@ -2808,6 +3008,10 @@ Per specificare più URL separarli con una barra verticale "|". Unable to bind to %s on this computer. Bitcoin Core is probably already running. Impossibile associarsi a %s su questo computer. Probabilmente Bitcoin Core è già in esecuzione. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Utilizza UPnP per mappare la porta in ascolto (default: 1 quando in ascolto e -proxy non è specificato) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) ATTENZIONE, il numero di blocchi generati è insolitamente elevato: %d blocchi ricevuti nelle ultime %d ore (%d previsti) @@ -2833,8 +3037,8 @@ Per specificare più URL separarli con una barra verticale "|". Inserisce in whitelist i peer che si connettono da un dato indirizzo IP o netmask. Può essere specificato più volte. - (default: 1) - (predefinito: 1) + -maxmempool must be at least %d MB + -maxmempool deve essere almeno %d MB <category> can be: @@ -2868,6 +3072,22 @@ Per specificare più URL separarli con una barra verticale "|". Do you want to rebuild the block database now? Vuoi ricostruire ora il database dei blocchi? + + Enable publish hash block in <address> + Abilita pubblicazione hash blocco in <address> + + + Enable publish hash transaction in <address> + Abilità pubblicazione hash transazione in <address> + + + Enable publish raw block in <address> + Abilita pubblicazione blocchi raw in <address> + + + Enable publish raw transaction in <address> + Abilita pubblicazione transazione raw in <address> + Error initializing block database Errore durante l'inizializzazione del database dei blocchi @@ -2904,6 +3124,10 @@ Per specificare più URL separarli con una barra verticale "|". Invalid -onion address: '%s' Indirizzo -onion non valido: '%s' + + Keep the transaction memory pool below <n> megabytes (default: %u) + Mantieni la memory pool delle transazioni al di sotto di <n> megabytes (default: %u) + Not enough file descriptors available. Non ci sono abbastanza descrittori di file disponibili. @@ -2932,10 +3156,26 @@ Per specificare più URL separarli con una barra verticale "|". Specify wallet file (within data directory) Specifica il file del portamonete (all'interno della cartella dati) + + Unsupported argument -benchmark ignored, use -debug=bench. + Ignorata opzione -benchmark non supportata, utilizzare -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Argomento -debugnet ignorato in quanto non supportato, usare -debug=net. + + + Unsupported argument -tor found, use -onion. + Rilevato argomento -tor non supportato, utilizzare -onion. + Use UPnP to map the listening port (default: %u) Usa UPnP per mappare la porta di ascolto (predefinito: %u) + + User Agent comment (%s) contains unsafe characters. + Il commento del User Agent (%s) contiene caratteri non sicuri. + Verifying blocks... Verifica blocchi... @@ -2992,6 +3232,10 @@ Per specificare più URL separarli con una barra verticale "|". Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Esegue un comando in caso di ricezione di un allarme pertinente o se si rileva un fork molto lungo (%s in cmd è sostituito dal messaggio) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Le commissioni (in %s/kB) inferiori a questo valore sono considerate pari a zero per trasmissione, mining e creazione della transazione (default: %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Nel caso in cui paytxfee non sia impostato, include una commissione tale da ottenere un avvio delle conferme entro una media di n blocchi (predefinito: %u) @@ -3049,12 +3293,20 @@ Per specificare più URL separarli con una barra verticale "|". Attivazione della blockchain migliore... - Cannot resolve -whitebind address: '%s' - Impossibile risolvere indirizzo -whitebind: '%s' + Always relay transactions received from whitelisted peers (default: %d) + Trasmetti sempre le transazioni ricevute da peers whitelisted (default: %d) - Choose data directory on startup (default: 0) - Seleziona la cartella dati all'avvio (predefinito: 0) + Attempt to recover private keys from a corrupt wallet.dat on startup + Prova a recuperare le chiavi private da un wallet corrotto all'avvio + + + Automatically create Tor hidden service (default: %d) + Crea automaticamente il servizio Tor (default: %d) + + + Cannot resolve -whitebind address: '%s' + Impossibile risolvere indirizzo -whitebind: '%s' Connect through SOCKS5 proxy @@ -3072,6 +3324,10 @@ Per specificare più URL separarli con una barra verticale "|". Error reading from database, shutting down. Errore durante lalettura del database. Arresto in corso. + + Imports blocks from external blk000??.dat file on startup + Importa blocchi da un file blk000??.dat esterno all'avvio + Information Informazioni @@ -3124,6 +3380,14 @@ Per specificare più URL separarli con una barra verticale "|". Receive and display P2P network alerts (default: %u) Ricevi e visualizza gli alerts della rete P2P (default: %u) + + Reducing -maxconnections from %d to %d, because of system limitations. + Riduzione -maxconnections da %d a %d a causa di limitazioni di sistema. + + + Rescan the block chain for missing wallet transactions on startup + Ripete la scansione della block chain per individuare le transazioni che mancano dal wallet all'avvio + Send trace/debug info to console instead of debug.log file Invia le informazioni di trace/debug alla console invece che al file debug.log @@ -3132,22 +3396,10 @@ Per specificare più URL separarli con una barra verticale "|". Send transactions as zero-fee transactions if possible (default: %u) Invia transazioni a zero commissioni se possibile (predefinito: %u) - - Set SSL root certificates for payment request (default: -system-) - Imposta i certificati radice SSL per le richieste di pagamento (predefinito: -system-) - - - Set language, for example "de_DE" (default: system locale) - Imposta lingua, ad esempio "it_IT" (predefinito: lingua di sistema) - Show all debugging options (usage: --help -help-debug) Mostra tutte le opzioni di debug (utilizzo: --help -help-debug) - - Show splash screen on startup (default: 1) - Mostra finestra di presentazione all'avvio (predefinito: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Riduce il file debug.log all'avvio del client (predefinito: 1 se -debug non è impostato) @@ -3156,10 +3408,6 @@ Per specificare più URL separarli con una barra verticale "|". Signing transaction failed Firma transazione fallita - - Start minimized - Avvia ridotto a icona - The transaction amount is too small to pay the fee L'importo della transazione è troppo basso per pagare la commissione @@ -3168,6 +3416,14 @@ Per specificare più URL separarli con una barra verticale "|". This is experimental software. Questo è un software sperimentale. + + Tor control port password (default: empty) + Password porta controllo Tor (default: empty) + + + Tor control port to use if onion listening enabled (default: %s) + Porta di controllo Tor da usare se in ascolto su onion (default: %s) + Transaction amount too small Importo transazione troppo piccolo @@ -3184,14 +3440,14 @@ Per specificare più URL separarli con una barra verticale "|". Transaction too large Transazione troppo grande - - UI Options: - Opzioni Interfaccia Utente: - Unable to bind to %s on this computer (bind returned error %s) Impossibile associarsi a %s su questo computer (l'associazione ha restituito l'errore %s) + + Upgrade wallet to latest format on startup + Aggiorna il wallet all'ultimo formato all'avvio + Username for JSON-RPC connections Nome utente per connessioni JSON-RPC @@ -3204,10 +3460,18 @@ Per specificare più URL separarli con una barra verticale "|". Warning Attenzione + + Whether to operate in a blocks only mode (default: %u) + Imposta se operare in modalità solo blocchi (default: %u) + Zapping all transactions from wallet... Eliminazione dal portamonete di tutte le transazioni... + + ZeroMQ notification options: + Opzioni di notifica ZeroMQ + wallet.dat corrupt, salvage failed wallet.dat corrotto, recupero fallito @@ -3240,6 +3504,26 @@ Per specificare più URL separarli con una barra verticale "|". (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = mantiene metadati tx, ad es. proprietario account ed informazioni di richiesta di pagamento, 2 = scarta metadati tx) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee è impostato molto alto! Commissioni così alte possono venir pagate anche su una singola transazione. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee è impostato su un valore molto elevato. Questa è la commissione che si paga quando si invia una transazione. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Non mantenere le transazioni nella mempool più a lungo di <n> ore (default: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Errore di lettura di wallet.dat! Tutte le chiavi sono state lette correttamente, ma i dati delle transazioni o della rubrica potrebbero essere mancanti o non corretti. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Le commissioni (in %s/kB) inferiori a questo valore sono considerate pari a zero per la creazione della transazione (default: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Determina quanto sarà approfondita la verifica da parte di -checkblocks (0-4, predefinito: %u) @@ -3256,10 +3540,30 @@ Per specificare più URL separarli con una barra verticale "|". Output debugging information (default: %u, supplying <category> is optional) Emette informazioni di debug (predefinito: %u, fornire <category> è opzionale) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Supporta filtraggio di blocchi e transazioni con filtri bloom (default: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + La lunghezza totale della stringa di network version (%i) eccede la lunghezza massima (%i). Ridurre il numero o la dimensione di uacomments. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Cerca di mantenere il traffico in uscita al di sotto della soglia scelta (in MiB ogni 24h), 0 = nessun limite (default: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Argomento -socks non supportato. Non è più possibile impostare la versione SOCKS, solamente i proxy SOCKS5 sono supportati. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Usa un proxy SOCKS5 a parte per raggiungere i peer attraverso gli hidden services di Tor (predefinito: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Username e hash password per connessioni JSON-RPC. Il campo <userpw> utilizza il formato: <USERNAME>:<SALT>$<HASH>. Uno script python standard è incluso in share/rpcuser. Questa opzione può essere specificata più volte + (default: %s) (predefinito: %s) diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 140ed2445..4344fd043 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -882,6 +882,34 @@ command-line options コマンドライン オプション + + UI Options: + UIオプション: + + + Choose data directory on startup (default: %u) + 起動時にデータ ディレクトリを選ぶ (初期値: %u) + + + Set language, for example "de_DE" (default: system locale) + 言語設定 例: "de_DE" (初期値: システムの言語) + + + Start minimized + 最小化された状態で起動する + + + Set SSL root certificates for payment request (default: -system-) + 支払いリクエスト用にSSLルート証明書を設定する (デフォルト:-system-) + + + Show splash screen on startup (default: %u) + 起動時にスプラッシュ画面を表示する (初期値: %u) + + + Reset all settings changes made over the GUI + GUI 経由で行われた設定の変更を全てリセット + Intro @@ -1477,6 +1505,18 @@ Current number of blocks 現在のブロック数 + + Memory Pool + メモリ・プール + + + Current number of transactions + 現在のトランザクション数 + + + Memory usage + メモリ使用量 + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. 現在のデータディレクトリからBitcoin Coreのデバッグ用ログファイルを開きます。ログファイルが巨大な場合、数秒かかることがあります。 @@ -2736,6 +2776,10 @@ Copy transaction ID 取引 ID をコピー + + Copy raw transaction + 生トランザクションをコピー + Edit label ラベルの編集 @@ -2995,10 +3039,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. 与えられたネットマスクやIPアドレスから接続を行う、ホワイトリストのピア。複数回指定できます。 - - (default: 1) - (デフォルト: 1) - -maxmempool must be at least %d MB -maxmempoolは最低でも %d MB必要です @@ -3256,17 +3296,21 @@ Activating best chain... 最優良のチェインを有効化しています... + + Always relay transactions received from whitelisted peers (default: %d) + ホワイトリストにあるピアから受け取ったトランザクションを常にリレーする (初期値: %d) + Attempt to recover private keys from a corrupt wallet.dat on startup 起動時に壊れた wallet.dat から秘密鍵を復旧することを試す - Cannot resolve -whitebind address: '%s' - -whitebind アドレス '%s' を解決できません + Automatically create Tor hidden service (default: %d) + Tor秘匿サービスを自動的に作成する (初期値: %d) - Choose data directory on startup (default: 0) - 起動時にデータ ディレクトリを選ぶ (初期値: 0) + Cannot resolve -whitebind address: '%s' + -whitebind アドレス '%s' を解決できません Connect through SOCKS5 proxy @@ -3356,22 +3400,10 @@ Send transactions as zero-fee transactions if possible (default: %u) 可能な場合には手数料ゼロのトランザクションとしてトランザクションを送信する (初期値: %u) - - Set SSL root certificates for payment request (default: -system-) - 支払いリクエスト用にSSLルート証明書を設定する(デフォルト:-system-) - - - Set language, for example "de_DE" (default: system locale) - 言語設定 例: "de_DE" (初期値: システムの言語) - Show all debugging options (usage: --help -help-debug) すべてのデバッグオプションを表示する (使い方: --help -help-debug) - - Show splash screen on startup (default: 1) - 起動時にスプラッシュ画面を表示する (初期値: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) クライアント起動時に debug.log ファイルを縮小 (初期値: -debug オプションを指定しない場合は1) @@ -3380,10 +3412,6 @@ Signing transaction failed 取引の署名に失敗しました - - Start minimized - 最小化された状態で起動する - The transaction amount is too small to pay the fee トランザクションの金額が小さすぎて手数料を支払えません @@ -3392,6 +3420,14 @@ This is experimental software. これは実験的なソフトウェアです。 + + Tor control port password (default: empty) + Tor管理ポートのパスワード (初期値: 空文字) + + + Tor control port to use if onion listening enabled (default: %s) + Onion のリッスンが有効になっている場合に使用するTor管理ポート (初期値: %s) + Transaction amount too small 取引の額が小さ過ぎます @@ -3408,10 +3444,6 @@ Transaction too large 取引が大き過ぎます - - UI Options: - UIオプション: - Unable to bind to %s on this computer (bind returned error %s) このコンピュータの %s にバインドすることができません (バインドが返したエラーは %s) @@ -3432,6 +3464,10 @@ Warning 警告 + + Whether to operate in a blocks only mode (default: %u) + ブロック限定モードにおいて動作を行うかどうか (初期値: %u) + Zapping all transactions from wallet... ウォレットからすべてのトランザクションを消去しています... @@ -3488,6 +3524,10 @@ Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. wallet.dat の読み込みエラー! すべてのキーは正しく読み取れますが、取引データやアドレス帳のエントリが失われたか、正しくない可能性があります。 + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + トランザクション作成の際、この値未満の手数料 (%s/kB単位) はゼロであるとみなす (デフォルト: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) -checkblocks のブロックの検証レベル (0-4, 初期値: %u) @@ -3504,6 +3544,10 @@ Output debugging information (default: %u, supplying <category> is optional) デバッグ情報を出力する (初期値: %u, <category> の指定は任意です) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Bloomフィルタによる、ブロックおよびトランザクションのフィルタリングを有効化する (初期値: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. ネットワークバージョン文字 (%i) の長さが最大の長さ (%i) を超えています。UAコメントの数や長さを削減してください。 @@ -3520,6 +3564,10 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Tor 秘匿サービスを通し、別々の SOCKS5 プロキシを用いることでピアに到達する (初期値: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + JSON-RPC接続時のユーザ名とハッシュ化されたパスワード。<userpw> フィールドのフォーマットは <USERNAME>:<SALT>$<HASH>。標準的な Python スクリプトが share/rpcuser 内に含まれています。このオプションは複数回指定できます。 + (default: %s) (デフォルト: %s) diff --git a/src/qt/locale/bitcoin_ka.ts b/src/qt/locale/bitcoin_ka.ts index e8f528669..11c73ec76 100644 --- a/src/qt/locale/bitcoin_ka.ts +++ b/src/qt/locale/bitcoin_ka.ts @@ -748,7 +748,7 @@ command-line options კომანდების ზოლის ოპციები - + Intro @@ -763,6 +763,10 @@ As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. ეს პროგრამის პირველი გაშვებაა; შეგიძლიათ მიუთითოთ, სად შეინახოს მონაცემები Bitcoin Core-მ. + + Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + Bitcoin Core გადმოტვირთავს და შეინახავს Bitcoin-ის ბლოკთა ჯაჭვს. მითითებულ კატალოგში დაგროვდება სულ ცოტა %1 გბ მონაცემები, და მომავალში უფრო გაიზრდება. საფულეც ამავე კატალოგში შეინახება. + Use the default data directory ნაგულისხმევი კატალოგის გამოყენება @@ -1431,6 +1435,10 @@ Custom change address ხურდის მისამართი + + Transaction Fee: + ტრანსაქციის საფასური - საკომისიო: + Send to multiple recipients at once გაგზავნა რამდენიმე რეციპიენტთან ერთდროულად @@ -1507,6 +1515,10 @@ The amount exceeds your balance. თანხა აღემატება თქვენს ბალანსს + + The total exceeds your balance when the %1 transaction fee is included. + საკომისიო %1-ის დამატების შემდეგ თანხა აჭარბებს თქვენს ბალანსს + Transaction creation failed! შეცდომა ტრანსაქციის შექმნისას! @@ -2326,13 +2338,17 @@ მაღალპრიორიტეტული/დაბალსაკომისიოიანი ტრანსაქციების მაქსიმალური ზომა ბაიტებში (ნაგულისხმევი: %d) - Choose data directory on startup (default: 0) - მონაცემთა კატალოგის მითითება ყოველი გაშვებისას (ნაგულისხმევი: 0) + Cannot resolve -whitebind address: '%s' + ვერ ხერხდება -whitebind მისამართის გარკვევა: '%s' Information ინფორმაცია + + Invalid amount for -maxtxfee=<amount>: '%s' + დაუშვებელი მნიშვნელობა -pmaxtxfee<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' დაუშვებელი მნიშვნელობა -minrelaytxfee=<amount>: '%s' @@ -2345,14 +2361,6 @@ Send trace/debug info to console instead of debug.log file ტრასირების/დახვეწის ინფოს გაგზავნა კონსოლზე debug.log ფაილის ნაცვლად - - Set language, for example "de_DE" (default: system locale) - აირჩიეთ ენა, მაგალითად "de_DE" (ნაგულისხმევია სისტემური ლოკალი) - - - Show splash screen on startup (default: 1) - მისალმების ეკრანის ჩვენება გაშვებისას (ნაგულისხმევი:1) - Shrink debug.log file on client startup (default: 1 when no -debug) debug.log ფაილის შეკუმშვა გაშვებისას (ნაგულისხმევია: 1 როცა არ აყენია -debug) @@ -2361,10 +2369,6 @@ Signing transaction failed ტრანსაქციების ხელმოწერა ვერ მოხერხდა - - Start minimized - გაშვება მინიმიზებული ეკრანით - Transaction amount too small ტრანსაქციების რაოდენობა ძალიან ცოტაა diff --git a/src/qt/locale/bitcoin_kk_KZ.ts b/src/qt/locale/bitcoin_kk_KZ.ts index 4de8f1b57..cfa19d13f 100644 --- a/src/qt/locale/bitcoin_kk_KZ.ts +++ b/src/qt/locale/bitcoin_kk_KZ.ts @@ -230,6 +230,10 @@ EditAddressDialog + + &Label + таңба + &Address Адрес @@ -253,6 +257,10 @@ OptionsDialog + + W&allet + Әмиян + OverviewPage @@ -275,9 +283,17 @@ RPCConsole + + &Information + Информация + ReceiveCoinsDialog + + &Amount: + Саны + ReceiveRequestDialog @@ -342,6 +358,10 @@ SendCoinsEntry + + A&mount: + Саны + ShutdownWindow diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 8243618f1..ce48ce249 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -3,7 +3,7 @@ AddressBookPage Right-click to edit address or label - 지갑 주소나 이름을 수정하려면 우클릭하세요. + 지갑 주소나 라벨을 수정하려면 우클릭하세요. Create a new address @@ -27,7 +27,7 @@ &Copy Address - 계좌 복사(&C) + 주소 복사(&C) Delete the currently selected address from the list @@ -59,11 +59,11 @@ Sending addresses - 보내는 주소들 + 타인 계좌 주소목록 Receiving addresses - 받은 주소들 + 내 계좌 주소목록 These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. @@ -75,7 +75,7 @@ Copy &Label - 표 복사 + 라벨 복사 &Edit @@ -87,7 +87,7 @@ Comma separated file (*.csv) - 각각의 파일에 쉼표하기(*.csv) + 쉼표로 구분된 파일(*.csv) Exporting Failed @@ -95,14 +95,14 @@ There was an error trying to save the address list to %1. Please try again. - %1으로 주소 리스트를 저장하는 동안 오류가 발생했습니다. 다시 시도해주세요. + %1으로 주소 목록을 저장하는 동안 오류가 발생했습니다. 다시 시도해주세요. AddressTableModel Label - + 라벨 Address @@ -110,7 +110,7 @@ (no label) - (표 없음) + (라벨 없음) @@ -129,7 +129,7 @@ Repeat new passphrase - 새 암호 반복 + 새로운 암호 재확인 Encrypt wallet @@ -141,7 +141,7 @@ Unlock wallet - 지갑 열기 + 지갑 잠금해제 This operation needs your wallet passphrase to decrypt the wallet. @@ -157,11 +157,11 @@ Confirm wallet encryption - 지갑의 암호화를 확정 + 지갑 암호화 승인 Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! - 경고: 만약 암호화된 지갑의 비밀번호를 잃어버릴 경우, 모든 비트코인들을 잃어버릴 수 있습니다! + 경고: 만약 암호화 된 지갑의 비밀번호를 잃어버릴 경우, <b>모든 비트코인들을 잃어버릴 수 있습니다</b>! Are you sure you wish to encrypt your wallet? @@ -169,16 +169,20 @@ IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - 중요: 본인 지갑파일에서 만든 예전 백업들은 새로 생성한 암화화된 지갑 파일로 교체됩니다. 보안상 이유로 이전에 암호화 하지 않은 지갑 파일 백업은 사용할 수 없게 되니 빠른 시일 내로 새로 암화화된 지갑을 사용하시기 바랍니다. + 중요: 본인 지갑파일에서 만든 예전 백업들은 새로 생성한 암호화 된 지갑 파일로 교체됩니다. 보안상 이유로 이전에 암호화 하지 않은 지갑 파일 백업은 사용할 수 없게 되니 빠른 시일 내로 새로 암호화 된 지갑을 사용하시기 바랍니다. Warning: The Caps Lock key is on! - 경고: 캡스록 키가 켜져있습니다! + 경고: Caps Lock키가 켜져있습니다! Wallet encrypted 지갑 암호화 완료 + + Enter the old passphrase and new passphrase to the wallet. + 지갑의 기존 암호와 새로운 암호를 입력해주세요. + Wallet encryption failed 지갑 암호화 실패 @@ -806,7 +810,7 @@ command-line options 명령줄 옵션 - + Intro @@ -963,6 +967,18 @@ Port of the proxy (e.g. 9050) 프록시의 포트번호입니다(예: 9050) + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + &Window 창(&W) @@ -1070,6 +1086,10 @@ Mined balance that has not yet matured 아직 사용 가능하지 않은 채굴된 잔액 + + Balances + 잔액 + Total: 총액: @@ -1082,6 +1102,10 @@ Your current balance in watch-only addresses 모니터링 지갑의 현재 잔액 + + Recent transactions + 최근 거래 + PaymentServer @@ -1151,11 +1175,27 @@ Enter a Bitcoin address (e.g. %1) 비트코인 주소를 입력하기 (예. %1) + + %1 h + %1 시간 + + + %1 m + %1 분 + + + %1 s + %1 초 + N/A 없음 - + + %1 ms + %1 ms + + QRImageWidget @@ -1203,7 +1243,11 @@ Using OpenSSL version - 오픈SSL 버전을 사용합니다 + 사용중인 OpenSSL 버전 + + + Using BerkeleyDB version + 사용중인 BerkeleyDB 버전 Startup time @@ -1229,6 +1273,22 @@ Current number of blocks 현재 블럭 수 + + Received + 받음 + + + Sent + 보냄 + + + &Peers + &피어 + + + Version + 버전 + Last block time 최종 블럭 시각 @@ -1281,6 +1341,22 @@ Type <b>help</b> for an overview of available commands. 사용할 수 있는 명령을 둘러보려면 <b>help</b>를 입력하십시오. + + %1 B + %1 바이트 + + + %1 KB + %1 킬로바이트 + + + %1 MB + %1 메가바이트 + + + %1 GB + %1 기가바이트 + ReceiveCoinsDialog @@ -1290,7 +1366,7 @@ &Label: - 표: + 라벨: &Message: @@ -1432,7 +1508,7 @@ (no label) - (표 없음) + (라벨 없음) (no message) @@ -1497,6 +1573,14 @@ Custom change address 주소변경 + + Transaction Fee: + 거래 수수료: + + + Recommended: + 권장: + Send to multiple recipients at once 다수의 수령인들에게 한번에 보내기 @@ -2140,6 +2224,10 @@ Export Transaction History 거래 기록 내보내기 + + Watch-only + 모니터링 지갑 + Exporting Failed 내보내기 실패 @@ -2299,10 +2387,6 @@ 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. 경고 : wallet.dat가 손상되어 데이터가 복구되었습니다. 원래의 wallet.dat 파일은 %s 후에 wallet.{timestamp}.bak 이름으로 저장됩니다. 잔액과 거래 내역이 정확하지 않다면 백업 파일로 부터 복원해야 합니다. - - (default: 1) - (기본값: 1) - Block creation options: 블록 생성 옵션: @@ -2335,6 +2419,10 @@ Error initializing block database 블록 데이터베이스를 초기화하는데 오류 + + Error initializing wallet database environment %s! + 지갑 데이터베이스 환경 초기화하는데 오류 %s + Error loading block database 블록 데이터베이스를 불러오는데 오류 @@ -2412,13 +2500,17 @@ 최대 크기를 최우선으로 설정 / 바이트당 최소 수수료로 거래(기본값: %d) - Choose data directory on startup (default: 0) - 파일목록을 선택하여 시작하시오(기본값: 0) + Cannot resolve -whitebind address: '%s' + -whitebind 주소를 확인할 수 없습니다: '%s' Information 정보 + + Invalid amount for -maxtxfee=<amount>: '%s' + -maxtxfee=<amount>에 대한 양이 잘못되었습니다: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' 노드로 전달하기 위한 최저 거래 수수료가 부족합니다. - minrelaytxfee=<amount>: '%s' - @@ -2435,22 +2527,10 @@ Send trace/debug info to console instead of debug.log file 추적오류 정보를 degug.log 자료로 보내는 대신 콘솔로 보내기 - - Set SSL root certificates for payment request (default: -system-) - 지불 요청을 위해 SSL 최상위 인증을 설정합니다. (기본값: -system-) - - - Set language, for example "de_DE" (default: system locale) - "de_DE"와 같이 언어를 설정하십시오 (기본값: 시스템 로캘) - Show all debugging options (usage: --help -help-debug) 모든 디버그 설정 보기(설정: --help -help-debug) - - Show splash screen on startup (default: 1) - 시작시 시작 화면 표시 (기본값: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) 클라이언트 시작시 debug.log 파일 비우기(기본값: 디버그 안할때 1) @@ -2459,10 +2539,6 @@ Signing transaction failed 거래를 서명하는것을 실패하였습니다. - - Start minimized - 최소화 상태에서 시작 - Transaction amount too small 거래량이 너무 적습니다 diff --git a/src/qt/locale/bitcoin_ky.ts b/src/qt/locale/bitcoin_ky.ts index 495f11b1f..51efd519c 100644 --- a/src/qt/locale/bitcoin_ky.ts +++ b/src/qt/locale/bitcoin_ky.ts @@ -125,6 +125,10 @@ &Network &Тармак + + W&allet + Капчык + &Port: &Порт: @@ -175,6 +179,10 @@ General Жалпы + + Network + &Тармак + Name Аты @@ -194,6 +202,10 @@ ReceiveCoinsDialog + + &Message: + Билдирүү: + ReceiveRequestDialog diff --git a/src/qt/locale/bitcoin_la.ts b/src/qt/locale/bitcoin_la.ts index b297a35d4..e3dcd505f 100644 --- a/src/qt/locale/bitcoin_la.ts +++ b/src/qt/locale/bitcoin_la.ts @@ -305,6 +305,10 @@ Bitcoin Core Bitcoin Nucleus + + &Command-line options + Optiones mandati initiantis + No block source available... Nulla fons frustorum absens... @@ -476,7 +480,7 @@ command-line options Optiones mandati intiantis - + Intro @@ -513,6 +517,10 @@ &Network &Rete + + W&allet + Cassidile + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. Aperi per se portam clientis Bitcoin in itineratore. Hoc tantum effectivum est si itineratrum tuum supportat UPnP et id activum est. @@ -655,6 +663,10 @@ &Information &Informatio + + Debug window + Fenestra Debug + Using OpenSSL version Utens OpenSSL versione @@ -714,10 +726,18 @@ ReceiveCoinsDialog + + &Amount: + Quantitas: + &Label: &Titulus: + + &Message: + Nuntius: + Copy label Copia titulum @@ -729,6 +749,10 @@ ReceiveRequestDialog + + Copy &Address + &Copia Inscriptionem + Address Inscriptio @@ -783,10 +807,18 @@ Send Coins Mitte Nummos + + Insufficient funds! + Inopia nummorum + Amount: Quantitas: + + Transaction Fee: + Transactionis merces: + Send to multiple recipients at once Mitte pluribus accipientibus simul @@ -870,6 +902,10 @@ Message: Nuntius: + + Pay To: + Pensa Ad: + ShutdownWindow @@ -1461,10 +1497,18 @@ Verifying wallet... Verificante cassidilem... + + Cannot resolve -whitebind address: '%s' + Non posse resolvere -whitebind inscriptionem: '%s' + Information Informatio + + Invalid amount for -maxtxfee=<amount>: '%s' + Quantitas non valida pro -maxtxfee=<amount>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Quantitas non valida pro -minrelaytxfee=<amount>: '%s' @@ -1477,14 +1521,6 @@ Send trace/debug info to console instead of debug.log file Mitte informationem vestigii/debug ad terminale potius quam plicam debug.log - - Set language, for example "de_DE" (default: system locale) - Constitue linguam, exempli gratia "de_DE" (praedefinitum: lingua systematis) - - - Show splash screen on startup (default: 1) - Monstra principem imaginem ad initium (praedefinitum: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Diminue plicam debug.log ad initium clientis (praedefinitum: 1 nisi -debug) @@ -1493,10 +1529,6 @@ Signing transaction failed Signandum transactionis abortum est - - Start minimized - Incipe minifactum ut icon - Transaction amount too small Magnitudo transactionis nimis parva diff --git a/src/qt/locale/bitcoin_lt.ts b/src/qt/locale/bitcoin_lt.ts index 782097737..b98976dfe 100644 --- a/src/qt/locale/bitcoin_lt.ts +++ b/src/qt/locale/bitcoin_lt.ts @@ -190,7 +190,11 @@ BanTableModel - + + Banned Until + Užblokuotas iki + + BitcoinGUI @@ -357,6 +361,10 @@ &About Bitcoin Core &Apie Bitcoin Core + + &Command-line options + Komandinės eilutės parametrai + Error Klaida @@ -551,7 +559,11 @@ (no label) (nėra žymės) - + + (change) + (Graža) + + EditAddressDialog @@ -632,7 +644,7 @@ command-line options komandinės eilutės parametrai - + Intro @@ -665,10 +677,26 @@ &Main &Pagrindinės + + MB + MB + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + Proxy IP adresas (Pvz. IPv4: 127.0.0.1 / IPv6: ::1) + + + &Reset Options + &Atstatyti Parinktis + &Network &Tinklas + + W&allet + Piniginė + Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. Automatiškai atidaryti Bitcoin kliento prievadą maršrutizatoriuje. Tai veikia tik tada, kai jūsų maršrutizatorius palaiko UPnP ir ji įjungta. @@ -689,6 +717,18 @@ Port of the proxy (e.g. 9050) Tarpinio serverio preivadas (pvz, 9050) + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + &Window &Langas @@ -741,6 +781,14 @@ Confirm options reset Patvirtinti nustatymų atstatymą + + Client restart required to activate changes. + Kliento perkrovimas reikalingas nustatymų aktyvavimui + + + This change would require a client restart. + Šis pakeitimas reikalautų kliento perkrovimo + The supplied proxy address is invalid. Nurodytas tarpinio serverio adresas negalioja. @@ -756,6 +804,10 @@ Available: Galimi: + + Your current spendable balance + Jūsų dabartinis išleidžiamas balansas + Pending: Laukiantys: @@ -779,10 +831,18 @@ URI handling URI apdorojimas + + Invalid payment address %1 + Neteisingas mokėjimo adresas %1 + Payment request rejected Mokėjimo siuntimas atmestas + + Payment request expired. + Mokėjimo siuntimas pasibaigė + Network request error Tinklo užklausos klaida @@ -812,11 +872,19 @@ QRImageWidget + + &Copy Image + Kopijuoti nuotrauką + Save QR Code Įrašyti QR kodą - + + PNG Image (*.png) + PNG paveikslėlis (*.png) + + RPCConsole @@ -835,6 +903,10 @@ &Information &Informacija + + Debug window + Derinimo langas + Using OpenSSL version Naudojama OpenSSL versija @@ -847,6 +919,10 @@ Network Tinklas + + Name + Pavadinimas + Number of connections Prisijungimų kiekis @@ -883,6 +959,10 @@ &Console &Konsolė + + &Clear + Išvalyti + Totals Viso: @@ -919,13 +999,29 @@ never Niekada + + Yes + Taip + + + No + Ne + ReceiveCoinsDialog + + &Amount: + Suma: + &Label: Ž&ymė: + + &Message: + Žinutė: + Clear Išvalyti @@ -945,6 +1041,10 @@ QR Code QR kodas + + Copy &Address + &Kopijuoti adresą + Payment information Mokėjimo informacija @@ -999,6 +1099,10 @@ Send Coins Siųsti monetas + + Insufficient funds! + Nepakanka lėšų + Quantity: Kiekis: @@ -1027,6 +1131,10 @@ Change: Graža: + + Transaction Fee: + Sandorio mokestis: + Send to multiple recipients at once Siųsti keliems gavėjams vienu metu @@ -1091,6 +1199,10 @@ The total exceeds your balance when the %1 transaction fee is included. Jei pridedame sandorio mokestį %1 bendra suma viršija jūsų balansą. + + Payment request expired. + Mokėjimo siuntimas pasibaigė + (no label) (nėra žymės) @@ -1130,6 +1242,10 @@ Message: Žinutė: + + Pay To: + Mokėti gavėjui: + ShutdownWindow @@ -1176,6 +1292,10 @@ Verify the message to ensure it was signed with the specified Bitcoin address Patikrinkite žinutę, jog įsitikintumėte, kad ją pasirašė nurodytas Bitcoin adresas + + Verify &Message + &Patikrinti žinutę + Click "Sign Message" to generate signature Spragtelėkite "Registruotis žinutę" tam, kad gauti parašą @@ -1629,18 +1749,22 @@ Information Informacija + + Invalid amount for -maxtxfee=<amount>: '%s' + Neteisinga suma -maxtxfee=<amount>: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + Neteisinga suma -minrelaytxfee=<amount>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + Neteisinga suma -mintxfee=<amount>: '%s' + Send trace/debug info to console instead of debug.log file Siųsti atsekimo/derinimo info į konsolę vietoj debug.log failo - - Set language, for example "de_DE" (default: system locale) - Nustatyti kalbą, pavyzdžiui "lt_LT" (numatyta: sistemos kalba) - - - Start minimized - Paleisti sumažintą - Username for JSON-RPC connections Vartotojo vardas JSON-RPC jungimuisi diff --git a/src/qt/locale/bitcoin_lv_LV.ts b/src/qt/locale/bitcoin_lv_LV.ts index fa7abdf2a..e01d4c812 100644 --- a/src/qt/locale/bitcoin_lv_LV.ts +++ b/src/qt/locale/bitcoin_lv_LV.ts @@ -720,6 +720,10 @@ About Bitcoin Core Par Bitcoin Core + + Command-line options + Komandrindas iespējas + Usage: Lietojums: @@ -728,7 +732,7 @@ command-line options komandrindas izvēles - + Intro @@ -1375,6 +1379,10 @@ Custom change address Pielāgota atlikuma adrese + + Transaction Fee: + Transakcijas maksa: + Send to multiple recipients at once Sūtīt vairākiem saņēmējiem uzreiz @@ -2113,10 +2121,6 @@ Run in the background as a daemon and accept commands Darbināt fonā kā servisu un pieņemt komandas - - (default: 1) - (noklusējums: 1) - <category> can be: <category> var būt: @@ -2161,10 +2165,26 @@ Wallet options: Maciņa iespējas: + + Cannot resolve -whitebind address: '%s' + Nevar atrisināt -whitebind adresi: '%s' + Information Informācija + + Invalid amount for -maxtxfee=<amount>: '%s' + Nederīgs daudzums priekš -maxtxfee=<amount>: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + Nederīgs daudzums priekš -minrelaytxfee=<amount>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + Nederīgs daudzums priekš -mintxfee=<amount>: '%s' + RPC server options: RPC servera iestatījumi: @@ -2173,22 +2193,10 @@ Send trace/debug info to console instead of debug.log file Debug/trace informāciju izvadīt konsolē, nevis debug.log failā - - Set language, for example "de_DE" (default: system locale) - Uzstādiet valodu, piemēram "de_DE" (pēc noklusēšanas: sistēmas lokāle) - - - Show splash screen on startup (default: 1) - Uzsākot, parādīt programmas informācijas logu (pēc noklusēšanas: 1) - Signing transaction failed Transakcijas parakstīšana neizdevās - - Start minimized - Sākt minimizētu - Transaction amount too small Transakcijas summa ir pārāk maza diff --git a/src/qt/locale/bitcoin_mk_MK.ts b/src/qt/locale/bitcoin_mk_MK.ts new file mode 100644 index 000000000..b7797063b --- /dev/null +++ b/src/qt/locale/bitcoin_mk_MK.ts @@ -0,0 +1,1039 @@ + + + AddressBookPage + + Right-click to edit address or label + Десен клик за уредување на адреса или етикета + + + Create a new address + Креирај нова адреса + + + &New + &Нова + + + Copy the currently selected address to the system clipboard + Копирај ја избраната адреса на системскиот клипборд + + + &Copy + &Копирај + + + C&lose + З&атвори + + + &Copy Address + &Копирај Адреса + + + Delete the currently selected address from the list + Избриши ја избраната адреса од листата + + + Export the data in the current tab to a file + Експортирај ги податоците од активното јазиче во датотека + + + &Export + &Експорт + + + &Delete + &Избриши + + + Choose the address to send coins to + Изберете адресата за да пратите биткоини + + + Choose the address to receive coins with + Изберете адресата за да примите биткоини + + + C&hoose + И&збери + + + Sending addresses + Адреси за праќање + + + Receiving addresses + Адреси за примање + + + Copy &Label + Копирај &Етикета + + + &Edit + &Уреди + + + Export Address List + Експортирај Листа со Адреси + + + Exporting Failed + Експортирањето не Успеа + + + + AddressTableModel + + Label + Етикета + + + Address + Адреса + + + (no label) + (без етикета) + + + + AskPassphraseDialog + + Enter passphrase + Внеси тајна фраза + + + New passphrase + Нова тајна фраза + + + Repeat new passphrase + Повторете ја новата тајна фраза + + + Encrypt wallet + Криптирање на паричник + + + Unlock wallet + Отклучи паричник + + + Decrypt wallet + Декриптирање на паричник + + + Change passphrase + Измени тајна фраза + + + Confirm wallet encryption + Потврдете го криптирањето на паричникот + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! + Предупредување: Ако го шифрирате вашиот паричник и ја изгубите вашата тајна фраза, ќе <b>ГИ ИЗГУБИТЕ СИТЕ ВАШИ БИТКОИНИ</b>! + + + Are you sure you wish to encrypt your wallet? + Дали сте сигурни дека сакате да криптирате вашиот паричник? + + + Warning: The Caps Lock key is on! + Предупредување: Caps Lock копчето е активно! + + + Wallet encrypted + Паричникот е криптиран + + + Wallet encryption failed + Криптирањето на паричникот е неуспешно + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. + Криптирањето на паричникот не успеа поради интерна грешка. Вашиот паричник не е криптиран. + + + The supplied passphrases do not match. + Приложените тајни фрази не се поклопуваат + + + Wallet unlock failed + Отклучувањето на паричникот е неуспешно + + + The passphrase entered for the wallet decryption was incorrect. + Тајната фраза која што ја внесовте за декриптирање на паричникот е неточна. + + + Wallet decryption failed + Декриптирањето на паричникот е неуспешно + + + Wallet passphrase was successfully changed. + Тајната фраза е успешно променета. + + + + BanTableModel + + + BitcoinGUI + + Sign &message... + Потпиши &порака... + + + Synchronizing with network... + Синхронизација со мрежата... + + + &Overview + &Преглед + + + Node + Јазол + + + &Transactions + &Трансакции + + + Browse transaction history + Преглед на историјата на трансакции + + + E&xit + И&злез + + + Quit application + Напушти ја апликацијата + + + About &Qt + За &Qt + + + Show information about Qt + Прикажи информации за Qt + + + &Options... + &Опции... + + + &Encrypt Wallet... + &Криптирање на Паричник... + + + &Backup Wallet... + &Бекап на Паричник... + + + &Change Passphrase... + &Измени Тајна Фраза... + + + &Sending addresses... + &Адреси за Испраќање... + + + &Receiving addresses... + &Адреси за Примање... + + + Open &URI... + Отвори &URI... + + + Bitcoin Core client + Биткоин Core софтверот + + + Importing blocks from disk... + Внесување на блокови од дискот... + + + Reindexing blocks on disk... + Повторно индексирање на блокови од дискот... + + + Send coins to a Bitcoin address + Испрати биткоини на Биткоин адреса + + + &Verify message... + &Потврди порака... + + + Bitcoin + Биткоин + + + Wallet + Паричник + + + &Send + &Испрати + + + &Receive + &Прими + + + Show information about Bitcoin Core + Прикажи информации за Биткоин Core + + + &Show / Hide + &Прикажи / Сокриј + + + Encrypt the private keys that belong to your wallet + Криптирај ги приватните клучеви кои припаѓаат на твојот паричник + + + &Settings + &Подесувања + + + &Help + &Помош + + + Bitcoin Core + Биткоин Core + + + &About Bitcoin Core + &За Биткоин Core + + + Processed %n block(s) of transaction history. + Обработен %n блок од историјата на трансакции.Обработени %n блокови од историјата на трансакции. + + + %n hour(s) + %n час%n часови + + + %n day(s) + %n ден%n денови + + + %n week(s) + %n недела%n недели + + + %1 and %2 + %1 и %2 + + + %n year(s) + %n година%n години + + + %1 behind + %1 позади + + + Error + Грешка + + + Warning + Предупредување + + + Up to date + Во тек + + + Date: %1 + + Дата: %1 + + + + Amount: %1 + + Сума: %1 + + + + Type: %1 + + Тип: %1 + + + + Label: %1 + + Етикета: %1 + + + + Address: %1 + + Адреса: %1 + + + + + ClientModel + + + CoinControlDialog + + Bytes: + Бајти: + + + Amount: + Сума: + + + Priority: + Приоритет: + + + Fee: + Провизија: + + + Dust: + Прашина: + + + After Fee: + После Провизија: + + + Change: + Кусур: + + + Amount + Сума + + + Date + Дата + + + Priority + Приоритет + + + Copy address + Копирај адреса + + + Copy label + Копирај етикета + + + Copy amount + Копирај сума + + + Lock unspent + Заклучи непотрошени + + + Unlock unspent + Отклучи непотрошени + + + Copy quantity + Копирај количина + + + Copy fee + Копирај провизија + + + Copy after fee + Копирај после провизија + + + Copy bytes + Копирај бајти + + + Copy priority + Копирај приоритет + + + Copy dust + Копирај прашина + + + Copy change + Копирај кусур + + + highest + највисок + + + higher + повисок + + + high + висок + + + medium-high + средно-висок + + + medium + среден + + + low-medium + ниско-среден + + + low + низок + + + lower + понизок + + + lowest + најнизок + + + none + нема + + + This label turns red if the transaction size is greater than 1000 bytes. + Оваа етикета станува црвена ако големината на трансакцијата е поголема од 1000 бајти. + + + This label turns red if the priority is smaller than "medium". + Оваа етикета станува црвена ако приоритетот е помал од "среден". + + + This label turns red if any recipient receives an amount smaller than %1. + Оваа етикета станува црвена ако примачот прими сума помала од %1. + + + yes + да + + + no + не + + + Transactions with higher priority are more likely to get included into a block. + Трансакциите со повисок приоритет имаат поголеми шанси да бидат вклучени во блок. + + + (no label) + (без етикета) + + + (change) + (кусур) + + + + EditAddressDialog + + Edit Address + Измени Адреса + + + &Label + &Етикета + + + &Address + &Адреса + + + + FreespaceChecker + + name + име + + + + HelpMessageDialog + + Bitcoin Core + Биткоин Core + + + version + верзија + + + (%1-bit) + (%1-бит) + + + About Bitcoin Core + За Биткоин Core + + + + Intro + + Bitcoin Core + Биткоин Core + + + Error + Грешка + + + + OpenURIDialog + + Open URI + Отвори URI + + + URI: + URI: + + + + OptionsDialog + + Options + Опции + + + MB + МБ + + + &Network + &Мрежа + + + W&allet + П&аричник + + + &Window + &Прозорец + + + &OK + &ОК + + + &Cancel + &Откажи + + + none + нема + + + + OverviewPage + + Total: + Вкупно: + + + + PaymentServer + + + PeerTableModel + + + QObject + + Amount + Сума + + + %1 d + %1 д + + + %1 h + %1 ч + + + %1 m + %1 м + + + %1 s + %1 с + + + %1 ms + %1 мс + + + + QRImageWidget + + &Save Image... + &Сними Слика... + + + Save QR Code + Сними QR Код + + + PNG Image (*.png) + PNG Слика (*.png) + + + + RPCConsole + + Network + Мрежа + + + Name + Име + + + Number of connections + Број на конекции + + + Block chain + Block chain + + + Sent + Испратени + + + Version + Верзија + + + &Console + &Конзола + + + %1 B + %1 Б + + + %1 KB + %1 КБ + + + %1 MB + %1 МБ + + + %1 GB + %1 ГБ + + + + ReceiveCoinsDialog + + &Amount: + &Сума: + + + &Label: + &Етикета: + + + &Message: + &Порака: + + + Show + Прикажи + + + Copy label + Копирај етикета + + + Copy message + Копирај порака + + + Copy amount + Копирај сума + + + + ReceiveRequestDialog + + QR Code + QR Код + + + Copy &URI + Копирај &URI + + + Copy &Address + Копирај &Адреса + + + &Save Image... + &Сними Слика... + + + URI + URI + + + Address + Адреса + + + Amount + Сума + + + Label + Етикета + + + Message + Порака + + + + RecentRequestsTableModel + + Date + Дата + + + Label + Етикета + + + Message + Порака + + + Amount + Сума + + + (no label) + (без етикета) + + + + SendCoinsDialog + + Bytes: + Бајти: + + + Amount: + Сума: + + + Priority: + Приоритет: + + + Fee: + Провизија: + + + After Fee: + После Провизија: + + + Change: + Кусур: + + + Dust: + Прашина: + + + Copy quantity + Копирај количина + + + Copy amount + Копирај сума + + + Copy fee + Копирај провизија + + + Copy after fee + Копирај после провизија + + + Copy bytes + Копирај бајти + + + Copy priority + Копирај приоритет + + + Copy change + Копирај кусур + + + (no label) + (без етикета) + + + Copy dust + Копирај прашина + + + + SendCoinsEntry + + A&mount: + Сума: + + + &Label: + &Етикета: + + + Message: + Порака: + + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + Bitcoin Core + Биткоин Core + + + + TrafficGraphWidget + + + TransactionDesc + + Date + Дата + + + Message + Порака + + + Amount + Сума + + + + TransactionDescDialog + + + TransactionTableModel + + Date + Дата + + + Label + Етикета + + + + TransactionView + + Copy address + Копирај Адреса + + + Copy label + Копирај етикета + + + Copy amount + Копирај сума + + + Exporting Failed + Експортирањето не Успеа + + + Date + Дата + + + Label + Етикета + + + Address + Адреса + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + &Export + &Експорт + + + Export the data in the current tab to a file + Експортирај ги податоците од активното јазиче во датотека + + + + bitcoin-core + + Options: + Опции: + + + Warning + Предупредување + + + Error + Грешка + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_mn.ts b/src/qt/locale/bitcoin_mn.ts index d1a597622..b79001006 100644 --- a/src/qt/locale/bitcoin_mn.ts +++ b/src/qt/locale/bitcoin_mn.ts @@ -233,6 +233,10 @@ &Change Passphrase... &Нууц Үгийг Солих... + + &Receiving addresses... + Хүлээн авах хаяг + Change the passphrase used for wallet encryption Түрүйвчийг цоожлох нууц үгийг солих @@ -269,6 +273,10 @@ Error Алдаа + + Information + Мэдээллэл + Up to date Шинэчлэгдсэн @@ -421,6 +429,14 @@ IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) проксигийн IP хаяг (жишээ нь: IPv4: 127.0.0.1 / IPv6: ::1) + + &Network + Сүлжээ + + + W&allet + Түрүйвч + Client restart required to activate changes. Ѳѳрчлѳлтүүдийг идэвхижүүлхийн тулд клиентийг ахин эхлүүлэх шаардлагтай @@ -522,10 +538,18 @@ ReceiveCoinsDialog + + &Amount: + Хэмжээ: + &Label: &Шошго: + + &Message: + Зурвас: + Show Харуул @@ -553,6 +577,10 @@ ReceiveRequestDialog + + Copy &Address + Хаягийг &Хуулбарлах + Address Хаяг @@ -714,6 +742,10 @@ Message: Зурвас: + + Pay To: + Тѳлѳх хаяг: + ShutdownWindow @@ -1033,6 +1065,10 @@ Wallet options: Түрүйвчийн сонголтууд: + + Information + Мэдээллэл + Loading addresses... Хаягуудыг ачааллаж байна... diff --git a/src/qt/locale/bitcoin_ms_MY.ts b/src/qt/locale/bitcoin_ms_MY.ts index 8f6676e48..df98dd839 100644 --- a/src/qt/locale/bitcoin_ms_MY.ts +++ b/src/qt/locale/bitcoin_ms_MY.ts @@ -121,6 +121,10 @@ ReceiveRequestDialog + + Copy &Address + &Salin Alamat + Address Alamat diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 6cded5e13..9236ac86f 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -882,6 +882,34 @@ command-line options kommandolinjevalg + + UI Options: + Grensesnittvalg: + + + Choose data directory on startup (default: %u) + Velg datakatalog for oppstart (default: %u) + + + Set language, for example "de_DE" (default: system locale) + Sett språk, for eksempel "nb_NO" (default: system-«locale») + + + Start minimized + Begynn minimert + + + Set SSL root certificates for payment request (default: -system-) + Sett SSL-rootsertifikat for betalingshenvendelser (default: -system-) + + + Show splash screen on startup (default: %u) + Vis velkomstbilde ved oppstart (default: %u) + + + Reset all settings changes made over the GUI + Nullstill alle oppsettendringer gjort via det grafiske grensesnittet + Intro @@ -1477,6 +1505,18 @@ Current number of blocks Nåværende antall blokker + + Memory Pool + Minnepool + + + Current number of transactions + Nåværende antall transaksjoner + + + Memory usage + Minnebruk + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Åpne Bitcoin Core sin loggfil for feilsøk fra gjeldende datamappe. Dette kan ta noen sekunder for store loggfiler. @@ -2736,6 +2776,10 @@ Copy transaction ID Kopier transaksjons-ID + + Copy raw transaction + Kopier råtransaksjon + Edit label Rediger merkelapp @@ -2915,6 +2959,10 @@ Error: A fatal internal error occurred, see debug.log for details Feil: En fatal intern feil oppstod, se debug.log for detaljer + + Fee (in %s/kB) to add to transactions you send (default: %s) + Gebyr (i %s/kB) for å legge til i transaksjoner du sender (standardverdi: %s) + Pruning blockstore... Beskjærer blokklageret... @@ -2991,10 +3039,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Hvitelist noder som kobler til fra den oppgitte nettmasken eller IP-adressen. Kan oppgis flere ganger. - - (default: 1) - (standardverdi: 1) - -maxmempool must be at least %d MB -maxmempool må være minst %d MB @@ -3041,11 +3085,11 @@ Enable publish raw block in <address> - Slå på publish raw block i <address> + Slå på publisering av råblokk i <address> Enable publish raw transaction in <address> - Slå på publish raw transaction i <address> + Slå på publisering av råtransaksjon i <address> Error initializing block database @@ -3251,17 +3295,21 @@ Activating best chain... Aktiverer beste kjede... + + Always relay transactions received from whitelisted peers (default: %d) + Alltid videresend transaksjoner mottatt fra hvitlistede noder (standardverdi: %d) + Attempt to recover private keys from a corrupt wallet.dat on startup Forsøk å berge private nøkler fra en korrupt wallet.dat ved oppstart - Cannot resolve -whitebind address: '%s' - Kan ikke løse -whitebind-adresse: '%s' + Automatically create Tor hidden service (default: %d) + Automatisk opprette Tor skjult tjeneste (standardverdi: %d) - Choose data directory on startup (default: 0) - Velg datamappe ved oppstart (standard: 0) + Cannot resolve -whitebind address: '%s' + Kan ikke løse -whitebind-adresse: '%s' Connect through SOCKS5 proxy @@ -3351,22 +3399,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Send transaksjoner uten transaksjonsgebyr hvis mulig (standardverdi: %u) - - Set SSL root certificates for payment request (default: -system-) - Sett SSL-rotsertifikat for betalingsetterspørring (standard: -system-) - - - Set language, for example "de_DE" (default: system locale) - Sett språk, for eksempel "nb_NO" (standardverdi: fra operativsystem) - Show all debugging options (usage: --help -help-debug) Vis alle feilsøkingsvalg (bruk: --help -help-debug) - - Show splash screen on startup (default: 1) - Vis splashskjerm ved oppstart (standardverdi: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Krymp filen debug.log når klienten starter (standardverdi: 1 hvis uten -debug) @@ -3375,10 +3411,6 @@ Signing transaction failed Signering av transaksjon feilet - - Start minimized - Start minimert - The transaction amount is too small to pay the fee Transaksjonsbeløpet er for lite til å betale gebyr @@ -3387,6 +3419,14 @@ This is experimental software. Dette er eksperimentell programvare. + + Tor control port password (default: empty) + Passord for Tor-kontrollport (standardverdi: tom) + + + Tor control port to use if onion listening enabled (default: %s) + Tor-kontrollport å bruke hvis onion-lytting er aktivert (standardverdi: %s) + Transaction amount too small Transaksjonen er for liten @@ -3403,10 +3443,6 @@ Transaction too large Transaksjonen er for stor - - UI Options: - Innstillinger for Brukergrensesnitt: - Unable to bind to %s on this computer (bind returned error %s) Kan ikke binde til %s på denne datamaskinen (binding returnerte feilen %s) @@ -3427,6 +3463,10 @@ Warning Advarsel + + Whether to operate in a blocks only mode (default: %u) + Hvorvidt å operere i modus med kun blokker (standardverdi: %u) + Zapping all transactions from wallet... Zapper alle transaksjoner fra lommeboken... @@ -3483,6 +3523,10 @@ Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Feil ved lesing av wallet.dat! Alle nøkler lest riktig, men transaksjonsdataene eller oppføringer i adresseboken mangler kanskje eller er feil. + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Gebyrer (i %s/Kb) mindre enn dette anses som null gebyr for laging av transaksjoner (standardverdi: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Hvor grundig blokkverifiseringen til -checkblocks er (0-4, standardverdi: %u) @@ -3499,6 +3543,10 @@ Output debugging information (default: %u, supplying <category> is optional) Ta ut feilsøkingsinformasjon (standardverdi: %u, bruk av <category> er valgfritt) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Støtte filtrering av blokker og transaksjoner med bloomfiltre (standardverdi: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. Total lengde av nettverks-versionstreng (%i) er over maks lengde (%i). Reduser tallet eller størrelsen av uacomments. @@ -3515,6 +3563,10 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Bruk separate SOCKS5 proxyer for å nå noder via Tor skjulte tjenester (standardverdi: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Brukernavn og hashet passord for JSON-RPC tilkoblinger. Feltet <userpw> kommer i formatet: <USERNAME>:<SALT>$<HASH>. Et Python-skript er inkludert i share/rpcuser. Dette alternativet kan angis flere ganger + (default: %s) (standardverdi: %s) diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index c307f0ab6..8457a9ab5 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -59,7 +59,7 @@ Sending addresses - Verstuur adressen + Verstuuradressen Receiving addresses @@ -67,11 +67,11 @@ These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. - Dit zijn uw Bitcoinadressen om betalingen mee te verzenden. Controleer altijd het bedrag en het ontvang adres voordat u uw bitcoins verzendt. + Dit zijn uw Bitcoinadressen om betalingen mee te doen. Controleer altijd het bedrag en het ontvang adres voordat u uw bitcoins verstuurt. These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. - Dit zijn uw Bitcoin-adressen waarmee u kunt betalen. We raden u aan om een nieuw ontvangstadres voor elke transactie te gebruiken. + Dit zijn uw Bitcoinadressen waarmee u kunt betalen. We raden u aan om een nieuw ontvangstadres voor elke transactie te gebruiken. Copy &Label @@ -157,7 +157,7 @@ Confirm wallet encryption - Bevestig versleuteling van de portemonnee + Bevestig versleuteling van uw portemonnee Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>! @@ -177,7 +177,7 @@ Warning: The Caps Lock key is on! - Waarschuwing: De Caps-Lock-toets staat aan! + Waarschuwing: De Caps Locktoets staat aan! Wallet encrypted @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP/Netmasker + + + Banned Until + Geband tot + + BitcoinGUI @@ -251,11 +259,11 @@ Browse transaction history - Blader door transactieverleden + Blader door transactiegescheidenis E&xit - &Afsluiten + A&fsluiten Quit application @@ -271,7 +279,7 @@ &Options... - O&pties... + &Opties... &Encrypt Wallet... @@ -287,11 +295,11 @@ &Sending addresses... - V&erstuur adressen... + &Verstuuradressen... &Receiving addresses... - O&ntvang adressen... + &Ontvang adressen... Open &URI... @@ -299,7 +307,7 @@ Bitcoin Core client - Bitcoin Kern applicatie + Bitcoin Coreapplicatie Importing blocks from disk... @@ -343,7 +351,7 @@ &Send - &Versturen + &Verstuur &Receive @@ -351,7 +359,7 @@ Show information about Bitcoin Core - Toon informatie over bitcoin kern + Toon informatie over Bitcoin Core &Show / Hide @@ -391,11 +399,11 @@ Bitcoin Core - Bitcoin Kern + Bitcoin Core Request payments (generates QR codes and bitcoin: URIs) - Vraag betaling aan (genereert QR codes en bitcoin: URIs) + Vraag betaling aan (genereert QR-codes en bitcoin: URI's) &About Bitcoin Core @@ -407,7 +415,7 @@ Show the list of used sending addresses and labels - Toon de lijst met gebruikt verzend adressen en labels + Toon de lijst met gebruikte verstuuradressen en -labels Show the list of used receiving addresses and labels @@ -419,15 +427,15 @@ &Command-line options - &Commandoregel-opties + &Opdrachytregelopties Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options - Toon het Bitcoin Core hulpbericht om een lijst te krijgen met mogelijke Bitcoin commandoregelopties + Toon het Bitcoin Core hulpbericht om een lijst te krijgen met mogelijke Bitcoinopdrachtregelopties %n active connection(s) to Bitcoin network - %n actieve connectie naar Bitcoin netwerk%n actieve connecties naar Bitcoin netwerk + %n actieve verbinding met Bitcoinnetwerk%n actieve verbindingen met Bitcoinnetwerk No block source available... @@ -435,11 +443,11 @@ Processed %n block(s) of transaction history. - %n blok aan transactie geschiedenis verwerkt.%n blokken aan transactie geschiedenis verwerkt. + %n blok aan transactiegeschiedenis verwerkt.%n blokken aan transactiegeschiedenis verwerkt. %n hour(s) - %n uur%n uur + %n uur%n uren %n day(s) @@ -455,7 +463,7 @@ %n year(s) - %n jaar%n jaar + %n jaar%n jaren %1 behind @@ -521,7 +529,7 @@ Sent transaction - Verzonden transactie + Verstuurde transactie Incoming transaction @@ -567,7 +575,7 @@ Fee: - Vergoeding: + Transactiekosten: Dust: @@ -575,7 +583,7 @@ After Fee: - Na vergoeding: + Naheffing: Change: @@ -651,11 +659,11 @@ Copy fee - Kopieer vergoeding + Kopieerkosten Copy after fee - Kopieer na vergoeding + Kopieernaheffing Copy bytes @@ -743,15 +751,15 @@ This means a fee of at least %1 per kB is required. - Dit betekent dat een vergoeding van minimaal %1 per kB nodig is. + Dit betekent dat kosten van minimaal %1 per kB aan verbonden zijn. Can vary +/- 1 byte per input. - Kan +/- byte per invoer variëren. + Kan +/- 1 byte per invoer variëren. Transactions with higher priority are more likely to get included into a block. - Transacties met een hogere prioriteit zullen eerder in een block gezet worden. + Transacties met een hogere prioriteit zullen eerder in een blok gezet worden. (no label) @@ -782,7 +790,7 @@ The address associated with this address list entry. This can only be modified for sending addresses. - Het adres dat bij dit adres item hoort. Dit kan alleen bewerkt worden voor verstuur adressen. + Het adres dat bij dit adresitem hoort. Dit kan alleen bewerkt worden voor verstuuradressen. &Address @@ -794,7 +802,7 @@ New sending address - Nieuw adres om naar te verzenden + Nieuw adres om naar te versturen Edit receiving address @@ -802,7 +810,7 @@ Edit sending address - Bewerk adres om naar te verzenden + Bewerk adres om naar te versturen The entered address "%1" is already in the address book. @@ -837,7 +845,7 @@ Path already exists, and is not a directory. - Communicatiepad bestaat al, en is geen folder. + Communicatiepad bestaat al, en is geen map. Cannot create data directory here. @@ -848,7 +856,7 @@ HelpMessageDialog Bitcoin Core - Bitcoin Kern + Bitcoin Core version @@ -864,7 +872,7 @@ Command-line options - Commandoregel-opties + Opdrachtregelopties Usage: @@ -872,7 +880,35 @@ command-line options - commandoregel-opties + opdrachtregelopties + + + UI Options: + UI-opties: + + + Choose data directory on startup (default: %u) + Kies gegevensmap bij opstarten (standaard: %u) + + + Set language, for example "de_DE" (default: system locale) + Stel taal in, bijvoorbeeld "nl_NL" (standaard: systeemlocale) + + + Start minimized + Geminimaliseerd starten + + + Set SSL root certificates for payment request (default: -system-) + Zet SSL-rootcertificaat voor betalingsverzoeken (standaard: -systeem-) + + + Show splash screen on startup (default: %u) + Toon opstartscherm bij opstarten (standaard: %u) + + + Reset all settings changes made over the GUI + Reset alle wijzigingen aan instellingen gedaan met de GUI @@ -891,7 +927,7 @@ Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. - Bitcoin Core zal een kopie van de Bitcoin blokketen downloaden en opslaan. Tenminste %1 GB aan data wordt opgeslagen in deze map en het zal groeien in de tijd. De portemonnee wordt ook in deze map opgeslagen. + Bitcoin Core zal een kopie van de Bitcoinblokketen downloaden en opslaan. Tenminste %1 GB aan data wordt opgeslagen in deze map en het zal groeien in de tijd. De portemonnee wordt ook in deze map opgeslagen. Use the default data directory @@ -903,7 +939,7 @@ Bitcoin Core - Bitcoin Kern + Bitcoin Core Error: Specified data directory "%1" cannot be created. @@ -915,7 +951,7 @@ %n GB of free space available - %n GB aan vrije oplsagruimte beschikbaar%n GB aan vrije oplsagruimte beschikbaar + %n GB aan vrije opslagruimte beschikbaar%n GB aan vrije opslagruimte beschikbaar (of %n GB needed) @@ -957,7 +993,7 @@ Size of &database cache - Grootte van de &database cache + Grootte van de &databasecache MB @@ -989,7 +1025,7 @@ Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. - Derde partijen URL's (bijvoorbeeld block explorer) dat in de transacties tab verschijnen als contextmenu elementen. %s in de URL is vervangen door transactie hash. Verscheidene URL's zijn gescheiden door een verticale streep |. + URL's van derden (bijvoorbeeld block explorer) die in de transacties tab verschijnen als contextmenuelementen. %s in de URL is vervangen door transactiehash. Verscheidene URL's zijn gescheiden door een verticale streep |. Third party transaction URLs @@ -997,7 +1033,7 @@ Active command-line options that override above options: - Actieve commandoregelopties die bovenstaande opties overschrijven: + Actieve opdrachtregelopties die bovenstaande opties overschrijven: Reset all client options to default. @@ -1013,11 +1049,11 @@ Automatically start Bitcoin Core after logging in to the system. - Bitcoin Kern automatisch starten bij inloggen. + Bitcoin Core automatisch starten bij inloggen. &Start Bitcoin Core on system login - &Start Bitcoin Kern tijdens login. + &Start Bitcoin Core tijdens login. (0 = auto, <0 = leave that many cores free) @@ -1045,7 +1081,7 @@ Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. - Open de Bitcoin-poort automatisch op de router. Dit werkt alleen als de router UPnP ondersteunt en het aanstaat. + Open de Bitcoinpoort automatisch op de router. Dit werkt alleen als de router UPnP ondersteunt en het aanstaat. Map port using &UPnP @@ -1053,7 +1089,7 @@ Connect to the Bitcoin network through a SOCKS5 proxy. - Verbind met het Bitcoin netwerk via een SOCKS5 proxy. + Verbind met het Bitcoinnetwerk via een SOCKS5 proxy. &Connect through SOCKS5 proxy (default proxy): @@ -1071,13 +1107,41 @@ Port of the proxy (e.g. 9050) Poort van de proxy (bijv. 9050) + + Used for reaching peers via: + Gebruikt om peers te bereiken via: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Vertoningen, als de opgegeven standaard SOCKS5-proxy is gebruikt om peers te benaderen via dit type netwerk. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Maak verbinding met Bitcoinnetwerk door een aparte SOCKS5-proxy voor verborgen diensten van Tor. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Gebruikt aparte SOCKS5-proxy om peers te bereiken via verborgen diensten van Tor: + &Window &Scherm Show only a tray icon after minimizing the window. - Laat alleen een systeemvak-icoon zien wanneer het venster geminimaliseerd is + Laat alleen een systeemvakicoon zien wanneer het venster geminimaliseerd is &Minimize to the tray instead of the taskbar @@ -1085,7 +1149,7 @@ M&inimize on close - Minimaliseer bij sluiten van het &venster + M&inimaliseer bij sluiten van het venster &Display @@ -1101,7 +1165,7 @@ Choose the default subdivision unit to show in the interface and when sending coins. - Kies de standaard onderverdelingseenheid om weer te geven in uw programma, en voor het versturen van munten + Kies de standaardonderverdelingseenheid om weer te geven in uw programma, en voor het versturen van munten Whether to show coin control features or not. @@ -1113,7 +1177,7 @@ &Cancel - Ann&uleren + &Annuleren default @@ -1259,7 +1323,7 @@ URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - URI kan niet verwerkt worden! Dit kan het gevolg zijn van een ongeldig Bitcoin adres of misvormde URI parameters. + URI kan niet verwerkt worden! Dit kan het gevolg zijn van een ongeldig Bitcoinadres of misvormde URI-parameters. Payment request file handling @@ -1267,7 +1331,7 @@ Payment request file cannot be read! This can be caused by an invalid payment request file. - Betalingsverzoek-bestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoek-bestand. + Betalingsverzoekbestand kan niet gelezen of verwerkt worden! Dit kan veroorzaakt worden door een ongeldig betalingsverzoek-bestand. Payment request expired. @@ -1316,6 +1380,10 @@ User Agent User Agent + + Node/Service + Node/Dienst + Ping Time Ping tijd @@ -1329,11 +1397,11 @@ Enter a Bitcoin address (e.g. %1) - Voer een Bitcoin-adres in (bijv. %1) + Voer een Bitcoinadres in (bijv. %1) %1 d - %1d + %1 d %1 h @@ -1345,7 +1413,7 @@ %1 s - %1s + %1 s None @@ -1437,9 +1505,21 @@ Current number of blocks Huidig aantal blokken + + Memory Pool + Geheugenpoel + + + Current number of transactions + Huidig aantal transacties + + + Memory usage + Geheugengebruik + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. - Open het Bitcoin Core debug logbestand van de huidige gegevens directory. Dit kan enkele seconden duren voor grote logbestanden. + Open het Bitcoin Core debuglogbestand van de huidige gegevensmap. Dit kan enkele seconden duren voor grote logbestanden. Received @@ -1453,10 +1533,18 @@ &Peers &Peers + + Banned peers + Gebande peers + Select a peer to view detailed information. Selecteer een peer om gedetailleerde informatie te bekijken. + + Whitelisted + Toegestaan + Direction Directie @@ -1465,13 +1553,25 @@ Version Versie + + Starting Block + Start Blok + + + Synced Headers + Gesynchroniseerde headers + + + Synced Blocks + Gesynchroniseerde blokken + User Agent User Agent Services - Services + Diensten Ban Score @@ -1493,6 +1593,18 @@ Ping Time Ping Tijd + + The duration of a currently outstanding ping. + De tijdsduur van een op het moment openstaande ping. + + + Ping Wait + Pingwachttijd + + + Time Offset + Tijdcompensatie + Last block time Tijd laatste blok @@ -1531,12 +1643,40 @@ Debug log file - Debug-logbestand + Debuglogbestand Clear console Maak console leeg + + &Disconnect Node + &Verbreek Verbinding Node + + + Ban Node for + Ban Node voor + + + 1 &hour + 1 &uur + + + 1 &day + 1 &dag + + + 1 &week + 1 &week + + + 1 &year + 1 &jaar + + + &Unban Node + &Maak Ban Ongedaan voor Node + Welcome to the Bitcoin Core RPC console. Welkom op de Bitcoin Core RPC console. @@ -1547,7 +1687,7 @@ Type <b>help</b> for an overview of available commands. - Typ <b>help</b> voor een overzicht van de beschikbare commando's. + Typ <b>help</b> voor een overzicht van de beschikbare opdrachten. %1 B @@ -1565,6 +1705,10 @@ %1 GB %1 Gb + + (node id: %1) + (node id: %1) + via %1 via %1 @@ -1618,7 +1762,7 @@ An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network. - Een optioneel bericht om bij te voegen aan het betalingsverzoek, dewelke zal getoond worden wanneer het verzoek is geopend. Opermerking: Het bericht zal niet worden verzonden met de betaling over het Bitcoin netwerk. + Een optioneel bericht om bij te voegen aan het betalingsverzoek, welke zal getoond worden wanneer het verzoek is geopend. Opmerking: Het bericht zal niet worden verzonden met de betaling over het Bitcoinnetwerk. An optional label to associate with the new receiving address. @@ -1767,7 +1911,7 @@ SendCoinsDialog Send Coins - Verstuur munten + Verstuurde munten Coin Control Features @@ -1803,11 +1947,11 @@ Fee: - Vergoeding: + Kosten: After Fee: - Na vergoeding: + Naheffing: Change: @@ -1815,7 +1959,7 @@ If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. - Als dit is geactiveerd, maar het wisselgeldadres is leeg of ongeldig, dan wordt het wisselgeld verzonden naar een nieuw gegenereerd adres. + Als dit is geactiveerd, maar het wisselgeldadres is leeg of ongeldig, dan wordt het wisselgeld verstuurd naar een nieuw gegenereerd adres. Custom change address @@ -1831,7 +1975,7 @@ collapse fee-settings - Transactiekosteninstellingen verbergen + verberg kosteninstellingen per kilobyte @@ -1867,7 +2011,7 @@ (Smart fee not initialized yet. This usually takes a few blocks...) - (Slimme vergoeding is nog niet geïnitialiseerd. Dit duurt meestal een paar blokken...) + (Slimme transactiekosten is nog niet geïnitialiseerd. Dit duurt meestal een paar blokken...) Confirmation time: @@ -1883,7 +2027,7 @@ Send as zero-fee transaction if possible - Verstuur als transactie zonder verzendkosten indien mogelijk + Indien mogelijk, verstuur zonder transactiekosten (confirmation may take longer) @@ -1891,7 +2035,7 @@ Send to multiple recipients at once - Verstuur aan verschillende ontvangers ineens + Verstuur in een keer aan verschillende ontvangers Add &Recipient @@ -1919,7 +2063,7 @@ S&end - &Verstuur + V&erstuur Confirm send coins @@ -1939,11 +2083,11 @@ Copy fee - Kopieer vergoeding + Kopieerkosten Copy after fee - Kopieer na vergoeding + Kopieernaheffing Copy bytes @@ -1957,6 +2101,10 @@ Copy change Kopieer wijziging + + Total Amount %1 + Totaalbedrag %1 + or of @@ -1981,10 +2129,22 @@ The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. De transactie was afgewezen. Dit kan gebeuren als u eerder uitgegeven munten opnieuw wilt versturen, zoals wanneer u een kopie van uw wallet.dat heeft gebruikt en in de kopie deze munten zijn gemarkeerd als uitgegeven, maar in de huidige nog niet. + + A fee higher than %1 is considered an absurdly high fee. + Transactiekosten van meer dan %1 wordt beschouwd als een absurd hoge transactiekosten. + Payment request expired. Betalingsverzoek verlopen. + + Pay only the required fee of %1 + Betaal alleen de verplichte transactiekosten van %1 + + + Estimated to begin confirmation within %n block(s). + Schatting is dat bevestiging begint over %n blok.Schatting is dat bevestiging begint over %n blokken. + The recipient address is not valid. Please recheck. Het adres van de ontvanger is niet geldig. Gelieve opnieuw te controleren.. @@ -1995,7 +2155,7 @@ Warning: Invalid Bitcoin address - Waarschuwing: Ongeldig Bitcoin adres + Waarschuwing: Ongeldig Bitcoinadres (no label) @@ -2011,7 +2171,7 @@ Are you sure you want to send? - Weet u zeker dat u wilt verzenden? + Weet u zeker dat u wilt versturen? added as transaction fee @@ -2022,7 +2182,7 @@ SendCoinsEntry A&mount: - Bedra&g: + B&edrag: Pay &To: @@ -2046,7 +2206,7 @@ The Bitcoin address to send the payment to - Het Bitcoin adres om betaling aan te voldoen + Het Bitcoinadres om betaling aan te versturen Alt+A @@ -2066,11 +2226,11 @@ 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. - De vergoeding zal worden afgetrokken van het bedrag dat verzonden wordt. De ontvangers zullen minder bitcoins ontvangen dan ingevoerd is in het hoeveelheids veld. Als er meerdere ontvangers geselecteerd zijn, dan wordt de vergoeding gelijk verdeeld. + De transactiekosten zal worden afgetrokken van het bedrag dat verstuurd wordt. De ontvangers zullen minder bitcoins ontvangen dan ingevoerd is in het hoeveelheidsveld. Als er meerdere ontvangers geselecteerd zijn, dan worden de transactiekosten gelijk verdeeld. S&ubtract fee from amount - Trek de vergoeding af van het bedrag. + Trek de transactiekosten a&f van het bedrag. Message: @@ -2090,7 +2250,7 @@ A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network. - Een bericht dat werd toegevoegd aan de bitcoin: URI dewelke wordt opgeslagen met de transactie ter referentie. Opmerking: Dit bericht zal niet worden verzonden over het Bitcoin netwerk. + Een bericht dat werd toegevoegd aan de bitcoin: URI welke wordt opgeslagen met de transactie ter referentie. Opmerking: Dit bericht zal niet worden verzonden over het Bitcoinnetwerk. Pay To: @@ -2116,19 +2276,19 @@ SignVerifyMessageDialog Signatures - Sign / Verify a Message - Handtekeningen - Onderteken een bericht / Verifiëer een handtekening + Handtekeningen – Onderteken een bericht / Verifiëer een handtekening &Sign Message - O&nderteken Bericht + &Onderteken Bericht You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. - U kunt berichten/overeenkomsten ondertekenen met uw adres om te bewijzen dat u Bitcoins kunt versturen. Wees voorzichtig met het ondertekenen van iets vaags of willekeurigs, omdat phishing-aanvallen u kunnen proberen te misleiden tot het ondertekenen van overeenkomsten om uw identiteit aan hen toe te vertrouwen. Onderteken alleen volledig gedetailleerde verklaringen voordat u akkoord gaat. + U kunt berichten/overeenkomsten ondertekenen met uw adres om te bewijzen dat u Bitcoins kunt versturen. Wees voorzichtig met het ondertekenen van iets vaags of willekeurigs, omdat phishingaanvallen u kunnen proberen te misleiden tot het ondertekenen van overeenkomsten om uw identiteit aan hen toe te vertrouwen. Onderteken alleen volledig gedetailleerde verklaringen voordat u akkoord gaat. The Bitcoin address to sign the message with - Het Bitcoin adres om bericht mee te ondertekenen + Het Bitcoinadres om bericht mee te ondertekenen Choose previously used address @@ -2184,7 +2344,7 @@ The Bitcoin address the message was signed with - Het Bitcoin adres waarmee het bericht ondertekend is + Het Bitcoinadres waarmee het bericht ondertekend is Verify the message to ensure it was signed with the specified Bitcoin address @@ -2255,11 +2415,11 @@ SplashScreen Bitcoin Core - Bitcoin Kern + Bitcoin Core The Bitcoin Core developers - De Bitcoin Core ontwikkelaars + De Bitcoin Core-ontwikkelaars [testnet] @@ -2389,7 +2549,7 @@ Debug information - Debug-informatie + Debuginformatie Transaction @@ -2447,7 +2607,7 @@ Immature (%1 confirmations, will be available after %2) - immatuur (%1 bevestigingen, zal beschikbaar zijn na %2) + Premature (%1 bevestigingen, zal beschikbaar zijn na %2) Open for %n more block(s) @@ -2499,7 +2659,7 @@ Sent to - Verzonden aan + Verstuurd aan Payment to yourself @@ -2533,6 +2693,10 @@ Whether or not a watch-only address is involved in this transaction. Of er een alleen-bekijken adres is betrokken bij deze transactie. + + User-defined intent/purpose of the transaction. + Door gebruiker gedefinieerde intentie/doel van de transactie + Amount removed from or added to balance. Bedrag verwijderd van of toegevoegd aan saldo @@ -2574,7 +2738,7 @@ Sent to - Verzonden aan + Verstuurd aan To yourself @@ -2612,6 +2776,10 @@ Copy transaction ID Kopieer transactie-ID + + Copy raw transaction + Kopieer ruwe transactie + Edit label Bewerk label @@ -2622,7 +2790,7 @@ Export Transaction History - Exporteer Transactieverleden + Exporteer Transactiegeschiedenis Watch-only @@ -2634,7 +2802,7 @@ There was an error trying to save the transaction history to %1. - Er is een fout opgetreden bij het opslaan van het transactieverleden naar %1. + Er is een fout opgetreden bij het opslaan van het transactiegeschiedenis naar %1. Exporting Successful @@ -2642,7 +2810,7 @@ The transaction history was successfully saved to %1. - Het transactieverleden was succesvol bewaard in %1. + Het transactiegeschiedenis was succesvol bewaard in %1. Comma separated file (*.csv) @@ -2699,7 +2867,7 @@ WalletModel Send Coins - Verstuur munten + Verstuur Munten @@ -2718,7 +2886,7 @@ Wallet Data (*.dat) - Portemonnee-data (*.dat) + Portemonneedata (*.dat) Backup Failed @@ -2726,7 +2894,7 @@ There was an error trying to save the wallet data to %1. - Er is een fout opgetreden bij het wegschrijven van de portemonnee-data naar %1. + Er is een fout opgetreden bij het wegschrijven van de portemonneedata naar %1. The wallet data was successfully saved to %1. @@ -2757,15 +2925,55 @@ Accept command line and JSON-RPC commands - Aanvaard commandoregel- en JSON-RPC-commando's + Aanvaard opdrachtregel- en JSON-RPC-opdrachten + + + If <category> is not supplied or if <category> = 1, output all debugging information. + Als er geen <categorie> is opgegeven of als de <categorie> 1 is, laat dan alle debugginginformatie zien. + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Maximum totale transactiekosten (in %s) om te gebruiken voor een enkele portemonneetransactie; als dit te laag is ingesteld kan het grote transacties verhinderen (default: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Check a.u.b. of de datum en tijd van uw computer correct zijn! Als uw klok verkeerd staat zal Bitcoin Core niet correct werken. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Snoeien is geconfigureerd on het minimum van %d MiB. Gebruik a.u.b. een hoger aantal. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Snoei: laatste portemoneesynchronisatie gaat verder dan de gesnoeide data. U moet -reindex gebruiken (download opnieuw de gehele blokketen voor een weggesnoeide node) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Beperk benodigde opslag door snoeien (verwijderen) van oude blokken. Deze modus is niet-compatibele met -txindex en -rescan. Waarschuwing: Terugzetten van deze instellingen vereist opnieuw downloaden van gehele de blokketen. (standaard:0 = uitzetten snoeimodus, >%u = doelgrootte in MiB voor blokbestanden) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Herscannen is niet mogelijk in de snoeimodus. U moet -reindex gebruiken dat de hele blokketen opnieuw zal downloaden. Error: A fatal internal error occurred, see debug.log for details Fout: er is een fout opgetreden, zie debug.log voor details + + Fee (in %s/kB) to add to transactions you send (default: %s) + Transactiekosten (in %s/kB) toevoegen aan transacties die u doet (standaard: %s) + + + Pruning blockstore... + Snoei blokopslag... + Run in the background as a daemon and accept commands - Draai in de achtergrond als daemon en aanvaard commando's + Draai in de achtergrond als daemon en aanvaard opdrachten + + + Unable to start HTTP server. See debug log for details. + Niet mogelijk ok HTTP-server te starten. Zie debuglogboek voor details. Accept connections from outside (default: 1 if no -proxy or -connect) @@ -2777,11 +2985,11 @@ Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup - Verwijder alle transacties van de portemonnee en herstel alleen de delen van de blockchain door -rescan tijdens het opstarten + Verwijder alle transacties van de portemonnee en herstel alleen de delen van de blokketen door -rescan tijdens het opstarten Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. - Uitgegeven onder de MIT software licentie, zie het bijgevoegde bestand COPYING of <http://www.opensource.org/licenses/mit-license.php>. + Uitgegeven onder de MIT-softwarelicentie, zie het bijgevoegde bestand COPYING of <http://www.opensource.org/licenses/mit-license.php>. Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) @@ -2789,16 +2997,28 @@ Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) - Kies het aantal script verificatie processen (%u tot %d, 0 = auto, <0 = laat dit aantal kernen vrij, standaard: %d) + Kies het aantal scriptverificatie processen (%u tot %d, 0 = auto, <0 = laat dit aantal kernen vrij, standaard: %d) + + + The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct + De blokdatabase bevat een blok dat lijkt uit de toekomst te komen. Dit kan gebeuren omdat de datum en tijd van uw computer niet goed staat. Herbouw de blokdatabase pas nadat u de datum en tijd van uw computer correct heeft ingesteld. This is a pre-release test build - use at your own risk - do not use for mining or merchant applications - Dit is een pre-release testversie - gebruik op eigen risico! Gebruik deze niet voor het delven van munten of handelsdoeleinden + Dit is een prerelease testversie – gebruik op eigen risico! Gebruik deze niet voor het delven van munten of handelsdoeleinden Unable to bind to %s on this computer. Bitcoin Core is probably already running. Niet in staat om %s te verbinden op deze computer. Bitcoin Core draait waarschijnlijk al. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Gebruik UPnP om de luisterende poort te mappen (standaard: 1 als er geluisterd worden en geen -proxy is meegegeven) + + + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) + WAARSCHUWING: abnormaal hoog aantal blokken is gegenereerd, %d blokken ontvangen in de laatste %d uren (%d verwacht) + WARNING: check your network connection, %d blocks received in the last %d hours (%d expected) WAARSCHUWING: controleer uw netwerkverbinding, %d blokken ontvangen in de laatste %d uren (%d verwacht) @@ -2820,12 +3040,12 @@ Goedgekeurde peers die verbinden van het ingegeven netmask of IP adres. Kan meerdere keren gespecificeerd worden. - (default: 1) - (standaard: 1) + -maxmempool must be at least %d MB + -maxmempool moet tenminste %d MB zijn <category> can be: - <category> kan zijn: + <categorie> kan zijn: Block creation options: @@ -2855,6 +3075,22 @@ Do you want to rebuild the block database now? Wilt u de blokkendatabase nu herbouwen? + + Enable publish hash block in <address> + Sta toe om hashblok te publiceren in <adres> + + + Enable publish hash transaction in <address> + Stat toe om hashtransactie te publiceren in <adres> + + + Enable publish raw block in <address> + Sta toe rauw blok te publiceren in <adres> + + + Enable publish raw transaction in <address> + Sta toe ruwe transacties te publiceren in <adres> + Error initializing block database Fout bij intialisatie blokkendatabase @@ -2885,12 +3121,16 @@ Incorrect or no genesis block found. Wrong datadir for network? - Incorrect of geen genesis-blok gevonden. Verkeerde datamap voor het netwerk? + Incorrect of geen genesisblok gevonden. Verkeerde datamap voor het netwerk? Invalid -onion address: '%s' Ongeldig -onion adres '%s' + + Keep the transaction memory pool below <n> megabytes (default: %u) + De transactiegeheugenpool moet onder de <n> megabytes blijven (standaard: %u) + Not enough file descriptors available. Niet genoeg file descriptors beschikbaar. @@ -2899,6 +3139,14 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) Verbind alleen met nodes in netwerk <net> (ipv4, ipv6 of onion) + + Prune cannot be configured with a negative value. + Snoeien kan niet worden geconfigureerd met een negatieve waarde. + + + Prune mode is incompatible with -txindex. + Snoeimodus is niet-compatibel met -txindex + Set database cache size in megabytes (%d to %d, default: %d) Zet database cache grootte in megabytes (%d tot %d, standaard: %d) @@ -2911,10 +3159,26 @@ Specify wallet file (within data directory) Specificeer het portemonnee bestand (vanuit de gegevensmap) + + Unsupported argument -benchmark ignored, use -debug=bench. + Niet-ondersteund argument -benchmark genegeerd, gebruik -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Niet-ondersteund argument -debugnet genegeerd, gebruik -debug=net + + + Unsupported argument -tor found, use -onion. + Niet-ondersteund argument -tor gevonden, gebruik -onion. + Use UPnP to map the listening port (default: %u) Gebruik UPnP om de luisterende poort te mappen (standaard: %u) + + User Agent comment (%s) contains unsafe characters. + User Agentcommentaar (%s) bevat onveilige karakters. + Verifying blocks... Blokken aan het controleren... @@ -2937,7 +3201,7 @@ You need to rebuild the database using -reindex to change -txindex - Om -txindex te kunnen veranderen dient u de database opnieuw te bouwen met gebruik van -reindex. + Om -txindex te kunnen veranderen dient u de database herbouwen met gebruik van -reindex. 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 @@ -2959,30 +3223,41 @@ Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) Creër nieuwe bestanden met standaard systeem bestandsrechten in plaats van umask 077 (alleen effectief met uitgeschakelde portemonnee functionaliteit) + + Discover own IP addresses (default: 1 when listening and no -externalip or -proxy) + Ontdek eigen IP-adressen (standaard: 1 voor luisteren en geen -externalip of -proxy) + Error: Listening for incoming connections failed (listen returned error %s) Fout: luisteren naar binnenkomende verbindingen mislukt (luisteren gaf foutmelding %s) Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) - Voer commando uit zodra een waarschuwing is ontvangen of wanneer we een erg lange fork detecteren (%s in commando wordt vervangen door bericht) + Voer opdracht uit zodra een waarschuwing is ontvangen of wanneer we een erg lange fork detecteren (%s in opdracht wordt vervangen door bericht) + + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Transactiekosten (in %s/kB) kleiner dan dit worden beschouw dat geen transactiekosten in rekening worden gebracht voor doorgeven, mijnen en transactiecreatie (standaard: %s) If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) - Als paytxfee niet is ingesteld, het pakket voldoende vergoeding zodat transacties beginnen bevestiging gemiddeld binnen in blokken (default: %u) + Als paytxfee niet is ingesteld, voeg voldoende transactiekosten toe zodat transacties starten met bevestigingen binnen in n blokken (standaard: %u) Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) - ongeldig bedrag voor -maxtxfee=<amount>: '%s' (moet ten minste de minrelay vergoeding van %s het voorkomen geplakt transacties voorkomen) + ongeldig bedrag voor -maxtxfee=<bedrag>: '%s' (moet ten minste de minimale doorgeeftransactiekosten van %s het voorkomen geplakt transacties voorkomen) Maximum size of data in data carrier transactions we relay and mine (default: %u) - Maximale grootte va n de gegevens in gegevensdrager transacties we relais en de mijnen -(default: %u) + Maximale grootte va n de gegevens in gegevensdragertransacties die we doorgeven en mijnen (standaard: %u) Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect) - Query voor peer- adressen via DNS- lookup , als laag op adressen (default: 1 unless -connect) + Query voor peeradressen via DNS- lookup , als laag op adressen (standaard: 1 unless -connect) + + + Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) + Gebruik willekeurige inloggegevens voor elke proxyverbinding. Dit maakt streamislatie voor Tor mogelijk (standaard: %u) Set maximum size of high-priority/low-fee transactions in bytes (default: %d) @@ -2994,7 +3269,7 @@ The transaction amount is too small to send after the fee has been deducted - Het transactiebedrag is te klein om te versturen nadat de vergoeding in mindering is gebracht + Het transactiebedrag is te klein om te versturen nadat de transactiekosten in mindering zijn gebracht This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. @@ -3002,7 +3277,11 @@ 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 - Goedgekeurde peers kunnen niet ge-DoS-banned worden en hun transacties worden altijd doorgestuurd, zelfs als ze reeds in de mempool aanwezig zijn, nuttig voor bijv. een gateway + Goedgekeurde peers kunnen niet ge-DoS-banned worden en hun transacties worden altijd doorgegeven, zelfs als ze reeds in de mempool aanwezig zijn, nuttig voor bijv. een gateway + + + You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain + U moet de database herbouwen met -reindex om terug te gaan naar de ongesnoeide modus. Dit zal de gehele blokkketen opnieuw downloaden. (default: %u) @@ -3010,19 +3289,27 @@ Accept public REST requests (default: %u) - Accepteer publieke REST-requests (standaard: %u) + Accepteer publieke REST-verzoeken (standaard: %u) Activating best chain... Beste reeks activeren... - Cannot resolve -whitebind address: '%s' - Kan -whitebind adres niet herleiden: '%s' + Always relay transactions received from whitelisted peers (default: %d) + Geef transacties altijd door aan goedgekeurde peers (standaard: %d) - Choose data directory on startup (default: 0) - Kies de gegevensmap tijdens het opstarten (standaard: 0) + Attempt to recover private keys from a corrupt wallet.dat on startup + Probeer privésleutels te herstellen van een corrupte wallet.dat bij opstarten + + + Automatically create Tor hidden service (default: %d) + Creëer automatisch verborgen dienst van Tor (standaard:%d) + + + Cannot resolve -whitebind address: '%s' + Kan -whitebind adres niet herleiden: '%s' Connect through SOCKS5 proxy @@ -3040,6 +3327,10 @@ Error reading from database, shutting down. Fout bij het lezen van de database, afsluiten. + + Imports blocks from external blk000??.dat file on startup + Importeer blokken van externe blk000??.dat-bestand bij opstarten + Information Informatie @@ -3050,7 +3341,7 @@ Invalid amount for -maxtxfee=<amount>: '%s' - Ongeldig bedrag voor -maxtxfee=<amount>: '%s' + Ongeldig bedrag voor -maxtxfee=<bedrag>: '%s' Invalid amount for -minrelaytxfee=<amount>: '%s' @@ -3078,36 +3369,40 @@ Node relay options: - Node relay opties: + Nodedoorgeefopties: RPC server options: RPC server opties: + + Rebuild block chain index from current blk000??.dat files on startup + Herbouwen blokketenindex vanuit huidige blk000??.dat-bestanden bij opstarten? + + + Receive and display P2P network alerts (default: %u) + Ontvang en toon P2P-netwerkwaarschuwingen (standaard: %u) + + + Reducing -maxconnections from %d to %d, because of system limitations. + Verminder -maxconnections van %d naar %d, vanwege systeembeperkingen. + + + Rescan the block chain for missing wallet transactions on startup + Herscan de blokketen voor missende portemonneetransacties bij opstarten + Send trace/debug info to console instead of debug.log file - Stuur trace/debug-info naar de console in plaats van het debug.log bestand + Verzend trace/debug-info naar de console in plaats van het debug.log-bestand Send transactions as zero-fee transactions if possible (default: %u) - Verstuur transacties zonder verzendkosten indien mogelijk (standaard: %u) - - - Set SSL root certificates for payment request (default: -system-) - Zet SSL root certificaten voor betalingsverzoek (standaard: -sytem-) - - - Set language, for example "de_DE" (default: system locale) - Stel taal in, bijvoorbeeld ''de_DE" (standaard: systeeminstellingen) + Indien mogelijk, verstuur zonder transactiekosten (standaard: %u) Show all debugging options (usage: --help -help-debug) Toon alle foutopsporingsopties (gebruik: --help -help-debug) - - Show splash screen on startup (default: 1) - Laat laadscherm zien bij het opstarten. (standaard: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Verklein debug.log-bestand bij het opstarten van de client (standaard: 1 als geen -debug) @@ -3116,18 +3411,22 @@ Signing transaction failed Ondertekenen van transactie mislukt - - Start minimized - Geminimaliseerd starten - The transaction amount is too small to pay the fee - Het transactiebedrag is te klein om de vergoeding te betalen + Het transactiebedrag is te klein om transactiekosten in rekening te brengen This is experimental software. Dit is experimentele software. + + Tor control port password (default: empty) + Tor bepaalt poortwachtwoord (standaard: empty) + + + Tor control port to use if onion listening enabled (default: %s) + Tor bepaalt welke poort te gebruiken als luisteren naar onion wordt gebruikt (standaard: %s) + Transaction amount too small Transactiebedrag te klein @@ -3138,20 +3437,20 @@ Transaction too large for fee policy - De transactie is te groot voor het toeslagenbeleid + De transactie is te groot voor het transactiekostenbeleid Transaction too large Transactie te groot - - UI Options: - UI Opties: - Unable to bind to %s on this computer (bind returned error %s) Niet in staat om aan %s te binden op deze computer (bind gaf error %s) + + Upgrade wallet to latest format on startup + Upgrade portemonee naar laatste formaat bij opstarten + Username for JSON-RPC connections Gebruikersnaam voor JSON-RPC-verbindingen @@ -3164,10 +3463,18 @@ Warning Waarschuwing + + Whether to operate in a blocks only mode (default: %u) + Om in alleen een blokmodus te opereren (standaard: %u) + Zapping all transactions from wallet... Bezig met het zappen van alle transacties van de portemonnee... + + ZeroMQ notification options: + ZeroMQ notificatieopties: + wallet.dat corrupt, salvage failed wallet.dat corrupt, veiligstellen mislukt @@ -3178,7 +3485,7 @@ Execute command when the best block changes (%s in cmd is replaced by block hash) - Voer commando uit zodra het beste blok verandert (%s in cmd wordt vervangen door blockhash) + Voer opdracht uit zodra het beste blok verandert (%s in cmd wordt vervangen door blokhash) This help message @@ -3200,6 +3507,26 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = behoudt tx meta data bijv. account eigenaar en betalingsverzoek informatie, 2. sla tx meta data niet op) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee staat zeer hoog! Transactiekosten van de grootte kunnen worden gebruikt in een enkele transactie. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee staat zeer hoog! Dit is de transactiekosten die u betaalt als u een transactie doet. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Bewaar transactie niet langer dan <n> uren in de geheugenpool (standaard: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Fout tijdens lezen van wallet.dat! Alle sleutels zijn correct te lezen, maar de transactiondatabase of adresboekingangen zijn mogelijk verdwenen of incorrect. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Transactiekosten (in %s/kB) kleiner dan dit worden beschouwd dat geen transactiekosten in rekening worden gebracht voor transactiecreatie (standaard: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Hoe grondig de blokverificatie van -checkblocks is (0-4, standaard: %u) @@ -3214,11 +3541,35 @@ Output debugging information (default: %u, supplying <category> is optional) - Output extra debugginginformatie (standaard: %u, het leveren van <category> is optioneel) + Output extra debugginginformatie (standaard: %u, het leveren van <categorie> is optioneel) + + + Support filtering of blocks and transaction with bloom filters (default: %u) + Ondersteun filtering van blokken en transacties met bloomfilters (standaard: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + Totale lengte van netwerkversiestring (%i) overschrijdt maximale lengte (%i). Verminder het aantal of grootte van uacomments. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Pogingen om uitgaand verkeer onder een bepaald doel te houden (in MiB per 24u), 0 = geen limiet (standaard: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Niet-ondersteund argument -socks gevonden. Instellen van SOCKS-versie is niet meer mogelijk, alleen SOCKS5-proxies worden ondersteund. Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) - Gebruik een aparte SOCKS5 proxy om 'Tor hidden services' te bereiken (standaard: %s) + Gebruik een aparte SOCKS5 proxy om verborgen diensten van Tor te bereiken (standaard: %s) + + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Gebruikersnaam en gehasht wachtwoord voor JSON-RPC-verbindingen. De velden <userpw> is in het formaat: <GEBRUIKERSNAAM>:<SALT>$<HASH>. Een kanoniek Pythonscript is inbegrepen in de share/rpcuser. Deze optie kan meerdere keren worden meegegeven + + + (default: %s) + (standaard: %s) Always query for peer addresses via DNS lookup (default: %u) @@ -3246,7 +3597,7 @@ Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) - Luister naar JSON-RPC-verbindingen op poort <port> (standaard: %u of testnet: %u) + Luister naar JSON-RPC-verbindingen op <poort> (standaard: %u of testnet: %u) Listen for connections on <port> (default: %u or testnet: %u) @@ -3266,7 +3617,7 @@ Maximum per-connection send buffer, <n>*1000 bytes (default: %u) - Maximum per-connectie zendbuffer, <n>*1000 bytes (standaard: %u) + Maximum per-connectie verstuurbuffer, <n>*1000 bytes (standaard: %u) Prepend debug output with timestamp (default: %u) @@ -3274,15 +3625,15 @@ Relay and mine data carrier transactions (default: %u) - Gegevensdrager transacties relay en de mijnen (default: %u) + Geef gegevensdragertransacties door en mijn ze ook (standaard: %u) Relay non-P2SH multisig (default: %u) - Relay non-P2SH multisig (default: %u) + Geef non-P2SH multisig door (standaard: %u) Set key pool size to <n> (default: %u) - Stel sleutelpoelgrootte in op <&> (standaard: %u) + Stel sleutelpoelgrootte in op <n> (standaard: %u) Set minimum block size in bytes (default: %u) @@ -3294,7 +3645,7 @@ Specify configuration file (default: %s) - Specificeer configuratie bestand (standaard: %s) + Specificeer configuratiebestand (standaard: %s) Specify connection timeout in milliseconds (minimum: 1, default: %d) @@ -3306,7 +3657,7 @@ Spend unconfirmed change when sending transactions (default: %u) - Besteed onbevestigd wisselgeld bij het versturen van transacties (standaard: %u) + Besteed onbevestigd wisselgeld bij het doen van transacties (standaard: %u) Threshold for disconnecting misbehaving peers (default: %u) @@ -3354,7 +3705,7 @@ Rescanning... - Blokketen aan het doorzoeken... + Blokketen aan het herscannen... Done loading diff --git a/src/qt/locale/bitcoin_pam.ts b/src/qt/locale/bitcoin_pam.ts index 893ae43c5..233918ff2 100644 --- a/src/qt/locale/bitcoin_pam.ts +++ b/src/qt/locale/bitcoin_pam.ts @@ -249,6 +249,10 @@ &Change Passphrase... &Alilan ing Passphrase... + + &Receiving addresses... + Address king pamag-Tanggap + Send coins to a Bitcoin address Magpadalang barya king Bitcoin address @@ -309,6 +313,10 @@ Bitcoin Core Kapilubluban ning Bitcoin + + &Command-line options + Pipamilian command-line + Last received block was generated %1 ago. Ing tatauling block a metanggap, me-generate ya %1 ing milabas @@ -363,6 +371,10 @@ CoinControlDialog + + Amount: + Alaga: + Amount Alaga @@ -464,7 +476,7 @@ command-line options pipamilian command-line - + Intro @@ -639,6 +651,10 @@ &Information &Impormasion + + Debug window + I-Debug ing awang + Using OpenSSL version Gagamit bersion na ning OpenSSL @@ -717,6 +733,10 @@ ReceiveRequestDialog + + Copy &Address + &Kopyan ing address + Address Address @@ -763,6 +783,18 @@ Send Coins Magpadalang Barya + + Insufficient funds! + Kulang a pondo + + + Amount: + Alaga: + + + Transaction Fee: + Bayad king Transaksion: + Send to multiple recipients at once Misanang magpadala kareng alialiuang tumanggap @@ -842,6 +874,14 @@ Alt+P Alt+P + + Message: + Mensayi: + + + Pay To: + Ibayad kang: + ShutdownWindow @@ -1365,26 +1405,30 @@ Failed to listen on any port. Use -listen=0 if you want this. Memali ya ing pamakiramdam kareng gang nanung port. Gamita me ini -listen=0 nung buri me ini. + + Cannot resolve -whitebind address: '%s' + Eya me-resolve ing -whitebind address: '%s' + Information &Impormasion + + Invalid amount for -maxtxfee=<amount>: '%s' + Eya maliari ing alaga keng -maxtxfee=<amount>: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + Eya maliari ing alaga keng -minrelaytxfee=<amount>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + Eya maliari ing alaga keng -mintxfee=<amount>: '%s' + Send trace/debug info to console instead of debug.log file Magpadalang trace/debug info okeng console kesa keng debug.log file - - Set language, for example "de_DE" (default: system locale) - Mamiling Amanu, alimbawa "de_DE"(default: system locale) - - - Show splash screen on startup (default: 1) - Ipalto ing splash screen keng umpisa (default: 1) - - - Start minimized - Umpisan ing pamaglati - Transaction too large Maragul yang masiadu ing transaksion diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index 228e02a5e..8a8c37748 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP/Maska Sieci + + + Banned Until + Blokada do + + BitcoinGUI @@ -870,6 +878,34 @@ command-line options opcje konsoli + + UI Options: + Opcje interfejsu + + + Choose data directory on startup (default: %u) + Katalog danych używany podczas uruchamiania programu (domyślny: %u) + + + Set language, for example "de_DE" (default: system locale) + Wybierz język, na przykład "de_DE" (domyślnie: język systemowy) + + + Start minimized + Uruchom zminimalizowany + + + Set SSL root certificates for payment request (default: -system-) + Ustaw certyfikaty główne SSL dla żądań płatności (domyślnie: -system-) + + + Show splash screen on startup (default: %u) + Wyświetl okno powitalne podczas uruchamiania (domyślnie: %u) + + + Reset all settings changes made over the GUI + Ustaw jako domyślne wszystkie ustawienia interfejsu + Intro @@ -1067,6 +1103,26 @@ Port of the proxy (e.g. 9050) Port proxy (np. 9050) + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Pokazuje, czy wspierane domyślnie proxy SOCKS5 jest używane do łączenia się z peerami w tej sieci + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Użyj oddzielnego prozy SOCKS5 aby osiągnąć węzły w ukrytych usługach Tor: + &Window &Okno @@ -1437,6 +1493,14 @@ Current number of blocks Aktualna liczba bloków + + Current number of transactions + Obecna liczba transakcji + + + Memory usage + Zużycie pamięci + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Otwórz plik logowania debugowania Bitcoin Core z obecnego katalogu z danymi. Może to potrwać kilka sekund przy większych plikach. @@ -1453,10 +1517,18 @@ &Peers &Węzły + + Banned peers + Blokowane węzły + Select a peer to view detailed information. Wybierz węzeł żeby zobaczyć szczegóły. + + Whitelisted + Biała lista + Direction Kierunek @@ -1465,6 +1537,18 @@ Version Wersja + + Starting Block + Blok startowy + + + Synced Headers + Zsynchronizowane nagłówki + + + Synced Blocks + Zsynchronizowane bloki + User Agent Aplikacja kliencka @@ -1493,6 +1577,10 @@ Ping Time Czas odpowiedzi + + Ping Wait + Czas odpowiedzi + Time Offset Przesunięcie czasu @@ -1541,6 +1629,14 @@ Clear console Wyczyść konsolę + + Ban Node for + Blokuj węzeł na okres + + + &Unban Node + Odblokuj węzeł + Welcome to the Bitcoin Core RPC console. Witaj w konsoli Bitcoin Core RPC. @@ -1569,6 +1665,10 @@ %1 GB %1 GB + + (node id: %1) + (id węzła: %1) + via %1 przez %1 @@ -1585,6 +1685,14 @@ Outbound Wyjściowy + + Yes + Tak + + + No + Nie + Unknown Nieznany @@ -1608,6 +1716,10 @@ Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before. Użyj jednego z poprzednio użytych adresów odbiorczych. Podczas ponownego używania adresów występują problemy z bezpieczeństwem i prywatnością. Nie korzystaj z tej opcji, chyba że odtwarzasz żądanie płatności wykonane już wcześniej. + + R&euse an existing receiving address (not recommended) + U&żyj ponownie istniejącego adresu odbiorczego (niepolecane) + An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network. Opcjonalna wiadomość do dołączenia do żądania płatności, która będzie wyświetlana, gdy żądanie zostanie otwarte. Uwaga: wiadomość ta nie zostanie wysłana wraz z płatnością w sieci Bitcoin. @@ -1949,6 +2061,10 @@ Copy change Skopiuj resztę + + Total Amount %1 + Łączna kwota %1 + or lub @@ -1981,6 +2097,10 @@ Payment request expired. Żądanie płatności upłynęło. + + Pay only the required fee of %1 + Zapłać tylko wymaganą opłatę %1 + Estimated to begin confirmation within %n block(s). Przybliżony czas zatwierdzenia: %n bloków.Przybliżony czas zatwierdzenia: %n bloków.Przybliżony czas zatwierdzenia: %n bloków. @@ -2612,6 +2732,10 @@ Copy transaction ID Skopiuj ID transakcji + + Copy raw transaction + Skopiuj surowe dane transakcji + Edit label Zmień etykietę @@ -2763,6 +2887,10 @@ Error: A fatal internal error occurred, see debug.log for details Błąd: Wystąpił fatalny błąd wewnętrzny, sprawdź szczegóły w debug.log + + Fee (in %s/kB) to add to transactions you send (default: %s) + Prowizja (w %s/kB) dodawana do wysyłanych transakcji (domyślnie: %s) + Pruning blockstore... Przycinanie zapisu bloków... @@ -2771,6 +2899,10 @@ Run in the background as a daemon and accept commands Uruchom w tle jako daemon i przyjmuj polecenia + + Unable to start HTTP server. See debug log for details. + Uruchomienie serwera HTTP nie powiodło się. Zobacz dziennik debugowania, aby uzyskać więcej szczegółów. + Accept connections from outside (default: 1 if no -proxy or -connect) Akceptuj połączenia z zewnątrz (domyślnie: 1 jeśli nie ustawiono -proxy lub -connect) @@ -2827,10 +2959,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Dodawaj do białej listy węzły łączące się z podanej maski sieciowej lub adresu IP. Może być określona kilka razy. - - (default: 1) - (domyślnie: 1) - <category> can be: <category> mogą być: @@ -2927,6 +3055,14 @@ Specify wallet file (within data directory) Określ plik portfela (w obrębie folderu danych) + + Unsupported argument -benchmark ignored, use -debug=bench. + Niewspierany argument -benchmark zignorowany, użyj -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Niewspierany argument -debugnet zignorowany, użyj -debug=net. + Use UPnP to map the listening port (default: %u) Użyj UPnP do przekazania portu nasłuchu (domyślnie : %u) @@ -3036,12 +3172,20 @@ Aktywuje najlepszy łańcuch - Cannot resolve -whitebind address: '%s' - Nie można rozwiązać adresu -whitebind: '%s' + Always relay transactions received from whitelisted peers (default: %d) + Zawsze przekazuj informacje o transakcjach otrzymanych od osób z białej listy (domyślnie: %d) - Choose data directory on startup (default: 0) - Wybierz folder danych przy starcie (domyślnie: 0) + Attempt to recover private keys from a corrupt wallet.dat on startup + Próbuj podczas uruchamiania programu odzyskać klucze prywatne z uszkodzonego pliku wallet.dat + + + Automatically create Tor hidden service (default: %d) + Stwórz automatycznie ukrytą usługę Tora (domyślnie: %d) + + + Cannot resolve -whitebind address: '%s' + Nie można rozwiązać adresu -whitebind: '%s' Connect through SOCKS5 proxy @@ -3059,6 +3203,10 @@ Error reading from database, shutting down. Błąd odczytu z bazy danych, wyłączam się. + + Imports blocks from external blk000??.dat file on startup + Importuj bloki z zewnętrznego pliku blk000??.dat podczas uruchamiania programu + Information Informacja @@ -3091,6 +3239,10 @@ Keep at most <n> unconnectable transactions in memory (default: %u) Przechowuj w pamięci maksymalnie <n> transakcji nie możliwych do połączenia (domyślnie: %u) + + Need to specify a port with -whitebind: '%s' + Musisz określić port z -whitebind: '%s' + Node relay options: Opcje przekaźnikowe węzła: @@ -3107,6 +3259,10 @@ Receive and display P2P network alerts (default: %u) Odbieranie i wyświetlanie alertów sieci P2P (domyślnie: %u) + + Rescan the block chain for missing wallet transactions on startup + Przeskanuj podczas ładowania programu łańcuch bloków w poszukiwaniu zaginionych transakcji portfela + Send trace/debug info to console instead of debug.log file Wyślij informację/raport do konsoli zamiast do pliku debug.log. @@ -3115,22 +3271,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Wyślij bez opłaty jeżeli to możliwe (domyślnie: %u) - - Set SSL root certificates for payment request (default: -system-) - Ustaw certyfikaty główne SSL dla żądań płatności (domyślnie: -system-) - - - Set language, for example "de_DE" (default: system locale) - Ustaw Język, na przykład "pl_PL" (domyślnie: systemowy) - Show all debugging options (usage: --help -help-debug) Pokaż wszystkie opcje odpluskwiania (użycie: --help -help-debug) - - Show splash screen on startup (default: 1) - Pokazuj okno powitalne przy starcie (domyślnie: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Zmniejsz plik debug.log przy starcie programu (domyślnie: 1 jeśli nie użyto -debug) @@ -3139,10 +3283,6 @@ Signing transaction failed Podpisywanie transakcji nie powiodło się - - Start minimized - Uruchom zminimalizowany - The transaction amount is too small to pay the fee Zbyt niska kwota transakcji by zapłacić opłatę @@ -3151,6 +3291,10 @@ This is experimental software. To oprogramowanie eksperymentalne. + + Tor control port password (default: empty) + Hasło zabezpieczające portu kontrolnego Tora (domyślnie: puste) + Transaction amount too small Zbyt niska kwota transakcji @@ -3167,14 +3311,14 @@ Transaction too large Transakcja zbyt duża - - UI Options: - Opcje UI - Unable to bind to %s on this computer (bind returned error %s) Nie można przywiązać do %s na tym komputerze (bind zwrócił błąd %s) + + Upgrade wallet to latest format on startup + Zaktualizuj portfel do najnowszego formatu podczas ładowania programu + Username for JSON-RPC connections Nazwa użytkownika dla połączeń JSON-RPC @@ -3223,6 +3367,14 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = zachowaj wysłane metadane np. właściciel konta i informacje o żądaniach płatności, 2 = porzuć wysłane metadane) + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Nie trzymaj w pamięci transakcji starszych niż <n> godzin (domyślnie: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Ostrzeżenie: błąd odczytu wallet.dat! Wszystkie klucze zostały odczytane, ale może brakować pewnych danych transakcji lub wpisów w książce adresowej lub mogą one być nieprawidłowe. + How thorough the block verification of -checkblocks is (0-4, default: %u) Jak dokładna jest weryfikacja bloków przy -checkblocks (0-4, domyślnie: %u) @@ -3239,6 +3391,10 @@ Output debugging information (default: %u, supplying <category> is optional) Wypuść informacje debugowania (domyślnie: %u, podanie <category> jest opcjonalne) + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Znaleziono niewspierany argument -socks. Wybieranie wersji SOCKS nie jest już możliwe, wsparcie programu obejmuje tylko proxy SOCKS5 + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Użyj oddzielnego prozy SOCKS5 aby osiągnąć węzły w ukrytych usługach Tor (domyślnie: %s) diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index 4863591ac..5cea349fb 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -441,6 +441,10 @@ No block source available... Nenhum servidor disponível... + + Processed %n block(s) of transaction history. + %n bloco processado do histórico de transações.%n blocos processados do histórico de transações. + %n hour(s) %n hora%n horas @@ -878,6 +882,34 @@ command-line options opções da linha de comando + + UI Options: + Opções de Interface: + + + Choose data directory on startup (default: %u) + Escolher diretório de dados na inicialização (padrão: %u) + + + Set language, for example "de_DE" (default: system locale) + Definir idioma, por exemplo "de_DE" (padrão: idioma do sistema) + + + Start minimized + Iniciar minimizado + + + Set SSL root certificates for payment request (default: -system-) + Definir certificados de root SSL para requisições de pagamento (padrão: -sistema-) + + + Show splash screen on startup (default: %u) + Exibir tela de abertura na inicialização (padrão: %u) + + + Reset all settings changes made over the GUI + Desfazer todas as mudanças de configuração feitas na interface + Intro @@ -1079,6 +1111,10 @@ Used for reaching peers via: Usado para alcançar participantes via: + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Exibe, caso o proxy padrão SOCKS5 fornecido seja usado para se conectar a peers através deste tipo de rede. + IPv4 IPv4 @@ -1469,6 +1505,18 @@ Current number of blocks Quantidade atual de blocos + + Memory Pool + Pool de Memória + + + Current number of transactions + Número atual de transações + + + Memory usage + Uso de memória + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Abrir o arquivo de log de depuração do Bitcoin na pasta de dados atual. Isso pode demorar para arquivos grandes. @@ -1549,6 +1597,14 @@ The duration of a currently outstanding ping. A duração de um ping excepcional no momento. + + Ping Wait + Espera de ping + + + Time Offset + Offset de tempo + Last block time Horário do último bloco @@ -2637,6 +2693,10 @@ Whether or not a watch-only address is involved in this transaction. Mostrar ou não endereços Bitcoin na lista de transações. + + User-defined intent/purpose of the transaction. + Intenção/Propósito definido pelo usuário para a transação + Amount removed from or added to balance. Quantidade debitada ou creditada ao saldo. @@ -2716,6 +2776,10 @@ Copy transaction ID Copiar ID da transação + + Copy raw transaction + Copia os dados brutos da transação + Edit label Editar rótulo @@ -2867,6 +2931,30 @@ If <category> is not supplied or if <category> = 1, output all debugging information. Se <category> não for suprida ou se <category> = 1, mostrar toda informação de depuração. + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Total máximo de comissão (em %s) que será usado em uma única transação; um valor muito baixo pode cancelar uma transação grande (padrão: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Por favor verifique se a data e horário estão corretos no seu computador! Se o seu relógio estiver incorreto, a Carteira Bitcoin não irá funcionar corretamente. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Corte configurado abaixo do nível mínimo de %d de MiB. Por favor use um número mais alto. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Corte: a ultima sincronização da carteira foi além do dado comprimido. Você precisa reindexar ( -reindex , faça o download de toda a blockchain novamente) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Reduza os requerimentos de armazenamento de dados (cortando) deletando blocos mais antigos. Esse modo é incompatível com -txindex e -rescan. Cuidado: Reverter essa configuração requer um novo download de toda a blockchain. (Padrão: 0 = desabilita o corte de blocos, >%u = tamanho alvo em MiB para o uso de blocos cortados) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Rescans não são possíveis no modo de corte. Você precisa usar -reindex, que irá fazer o download de toda a blockchain novamente. + Error: A fatal internal error occurred, see debug.log for details Erro: Um erro interno fatal ocorreu, veja debug.log para detalhes @@ -2951,10 +3039,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Lista Branca pares de ligação da máscara de rede dado ou o endereço IP . Pode ser especificado várias vezes. - - (default: 1) - (padrão: 1) - -maxmempool must be at least %d MB -maxmempool deve ser pelo menos %d MB @@ -2991,6 +3075,22 @@ Do you want to rebuild the block database now? Você quer reconstruir o banco de dados de blocos agora? + + Enable publish hash block in <address> + Abilitar a publicação da hash do block em <endereço> + + + Enable publish hash transaction in <address> + Abilitar a publicação da hash da transação em <endereço> + + + Enable publish raw block in <address> + Abilitar a publicação dos dados brutos do block em <endereço> + + + Enable publish raw transaction in <address> + Abilitar a publicação dos dados brutos da transação em <endereço> + Error initializing block database Erro ao inicializar banco de dados de blocos @@ -3111,6 +3211,10 @@ Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 Vincular ao endereço fornecido e sempre escutar nele. Use a notação [host]:port para IPv6 + + 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) + Conecte ao endereço dado para receber conecções JSON-RPC. Use a notação [destino]:porta para IPv6. Essa opção pode ser especificada várias vezes (padrão: conecte a todas as interfaces) + Cannot obtain a lock on data directory %s. Bitcoin Core is probably already running. Não foi possível obter acesso exclusivo ao diretório de dados %s. Provavelmente Bitcoin já está sendo executado. @@ -3131,18 +3235,50 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Executa um comando quando um alerta relevante é recebido ou vemos uma longa segregação (%s em cmd é substituído pela mensagem) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Comissões (em %s/kB) menores serão consideradas como zero para relaying, mineração e criação de transação (padrão %s) + + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + Se paytxfee não estiver definida, incluir comissão suficiente para que as transações comecem a ter confirmações em média dentro de N blocos (padrão %u) + + + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + Valor inválido para -maxtxfee = <valor>: '%s'( precisa ser pelo menos a comissão mínima de %s para prevenir travamento de transações) + + + Maximum size of data in data carrier transactions we relay and mine (default: %u) + Tamanho máximo de dados em transações de dados de operadora (padrão %u) + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect) Buscar por endereços de peers via busca DNS, se estiver baixo em endereços (padrão: 1 a não ser que -connect) + + Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) + Gerar credenciais aleatórias para cada conexão por proxy. Isto habilita o isolamento de stream do Tor (padrão: %u) + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Define o tamanho máximo de alta-prioridade por taxa baixa nas transações em bytes (padrão: %d) + + Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) + Determina o número de núcleos para a geração de moedas se ativado (-1 = todos os núcleos, padrão: %d) + The transaction amount is too small to send after the fee has been deducted A quantia da transação é muito pequena para mandar + + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + Esse produto inclui software desenvolvido pelo Open SSL Project para uso na OpenSSL Toolkit<https://www.openssl.org/> e software criptográfico escrito por Eric Young e software UPnP escrito por Thomas Bernard. + + + 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 + Peers permitidos não podem ser banidos do DoS e suas transações sempre são transmitidas, até mesmo se eles já estão no pool de memória, útil, por exemplo, para um gateway + You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain Você precisa reconstruir o banco de dados usando -reindex para sair do modo prune. Isso irá rebaixar todo o blockchain. @@ -3151,17 +3287,29 @@ (default: %u) (padrão: %u) + + Accept public REST requests (default: %u) + Aceitar pedidos restantes públicas (padrão: %u) + Activating best chain... Ativando a melhor sequência... - Cannot resolve -whitebind address: '%s' - Impossível resolver endereço -whitebind: '%s' + Always relay transactions received from whitelisted peers (default: %d) + Sempre transmitir transações recebidas de peers confiáveis (padrão: %d) - Choose data directory on startup (default: 0) - Escolha o diretório de dados na inicialização (padrão: 0) + Attempt to recover private keys from a corrupt wallet.dat on startup + Tentar recuperar na inicialização chaves privadas de um arquivo wallet.dat corrompido + + + Automatically create Tor hidden service (default: %d) + Criar automaticamente serviços ocultos do Tor (padrão: %d) + + + Cannot resolve -whitebind address: '%s' + Impossível resolver endereço -whitebind: '%s' Connect through SOCKS5 proxy @@ -3179,10 +3327,18 @@ Error reading from database, shutting down. Erro ao ler o banco de dados. Finalizando. + + Imports blocks from external blk000??.dat file on startup + Importar blocos a partir de arquivo externo blk000??.dat durante a inicialização + Information Informação + + Initialization sanity check failed. Bitcoin Core is shutting down. + O teste de integridade da inicialização falhou. O Core do Bitcoin está sendo desligado. + Invalid amount for -maxtxfee=<amount>: '%s' Quantidade inválida para -maxtxfee=<quantidade>: '%s' @@ -3203,6 +3359,10 @@ Invalid netmask specified in -whitelist: '%s' Máscara de rede especificada em -whitelist: '%s' é inválida + + Keep at most <n> unconnectable transactions in memory (default: %u) + Manter ao máximo <n> transações inconectáveis na memória (padrão: %u) + Need to specify a port with -whitebind: '%s' Necessário informar uma porta com -whitebind: '%s' @@ -3215,9 +3375,13 @@ RPC server options: Opções do servidor RPC: + + Rebuild block chain index from current blk000??.dat files on startup + Reconstruir índice de cadeia de bloco a partir dos arquivos blk000??.dat atuais durante a inicialização + Receive and display P2P network alerts (default: %u) - Receba e mostre P2P alerta de rede (default: %u) + Receba e mostre P2P alerta de rede (padrão: %u) Send trace/debug info to console instead of debug.log file @@ -3227,22 +3391,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Enviar transação sem taxa, se possível (padrão: %u) - - Set SSL root certificates for payment request (default: -system-) - Define certificados SSL root para requisição de pagamento (padrão: -system-) - - - Set language, for example "de_DE" (default: system locale) - Escolher língua, por exemplo "de_DE" (padrão: localização do sistema) - Show all debugging options (usage: --help -help-debug) Exibir todas opções de depuração (uso: --help -help-debug) - - Show splash screen on startup (default: 1) - Mostrar tela inicial ao ligar (padrão: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Encolher arquivo debug.log ao iniciar o cliente (padrão 1 se opção -debug não estiver presente) @@ -3251,10 +3403,6 @@ Signing transaction failed Assinatura de transação falhou - - Start minimized - Inicializar minimizado - The transaction amount is too small to pay the fee A quantidade da transação é pequena demais para pagar a taxa @@ -3279,10 +3427,6 @@ Transaction too large Transação muito larga - - UI Options: - Opções da interface: - Unable to bind to %s on this computer (bind returned error %s) Impossível se ligar a %s neste computador (bind retornou erro %s) @@ -3331,6 +3475,14 @@ Error loading wallet.dat: Wallet corrupted Erro ao carregar wallet.dat: Carteira corrompida + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Comissões (em %s/kB) menores serão consideradas como zero para criação de transação (padrão %s) + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + Use um proxy SOCKS5 separado para alcançar participantes da rede via serviços ocultos Tor (padrão: %s) + (default: %s) (padrão: %s) @@ -3375,13 +3527,21 @@ Make the wallet broadcast transactions Fazer a carteira transmitir transações + + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) + Buffer máximo de recebimento por conexão, <n>*1000 bytes (padrão: %u) + Prepend debug output with timestamp (default: %u) - Adiciona timestamp como prefixo no debug (default: %u) + Adiciona timestamp como prefixo no debug (padrão: %u) Relay non-P2SH multisig (default: %u) - Retransmitir P2SH não multisig (default: %u) + Retransmitir P2SH não multisig (padrão: %u) + + + Set key pool size to <n> (default: %u) + Defina o tamanho da chave para piscina<n> (padrão: %u) Set minimum block size in bytes (default: %u) @@ -3401,7 +3561,7 @@ Specify pid file (default: %s) - Especificar aqrquivo pid (default: %s) + Especificar aqrquivo pid (padrão: %s) Spend unconfirmed change when sending transactions (default: %u) diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index 454906636..ffed44a61 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -874,7 +874,7 @@ command-line options opções da linha de comandos - + Intro @@ -2772,10 +2772,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Ligações na lista branca conectam desde a seguinte netmask ou endereço IP. Posse ser especificado varias vezes. - - (default: 1) - (padrão: 1) - <category> can be: <categoria> pode ser: @@ -2921,8 +2917,8 @@ (por defeito: %u) - Choose data directory on startup (default: 0) - Escolha a pasta de dados ao iniciar (por defeito: 0) + Cannot resolve -whitebind address: '%s' + Não foi possível resolver o endereço -whitebind: '%s' Copyright (C) 2009-%i The Bitcoin Core Developers @@ -2936,6 +2932,10 @@ Information Informação + + Invalid amount for -maxtxfee=<amount>: '%s' + Quantia inválida para -maxtxfee=<quantidade>: '%s' + Invalid amount for -minrelaytxfee=<amount>: '%s' Quantia inválida para -minrelaytxfee=<quantidade>: '%s' @@ -2948,18 +2948,6 @@ Send trace/debug info to console instead of debug.log file Enviar informação de rastreio/depuração para a consola e não para o ficheiro debug.log - - Set SSL root certificates for payment request (default: -system-) - Configurar certificados SSL root para pedido de pagamento (default: -system-) - - - Set language, for example "de_DE" (default: system locale) - Definir linguagem, por exemplo "pt_PT" (por defeito: linguagem do sistema) - - - Show splash screen on startup (default: 1) - Mostrar imagem ao iniciar (por defeito: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Encolher ficheiro debug.log ao iniciar o cliente (por defeito: 1 sem -debug definido) @@ -2968,10 +2956,6 @@ Signing transaction failed Falhou assinatura da transação - - Start minimized - Iniciar minimizado - Transaction amount too small Quantia da transação é muito baixa @@ -3028,6 +3012,10 @@ Error loading wallet.dat: Wallet corrupted Erro ao carregar wallet.dat: Carteira danificada + + (default: %s) + (por defeito: %s) + Error loading wallet.dat Erro ao carregar wallet.dat diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index 72ab2c5bd..8bccf037a 100644 --- a/src/qt/locale/bitcoin_ro_RO.ts +++ b/src/qt/locale/bitcoin_ro_RO.ts @@ -709,6 +709,10 @@ lowest cea mai scăzută + + (%1 locked) + (%1 blocat) + none nimic @@ -737,6 +741,10 @@ no nu + + This means a fee of at least %1 per kB is required. + Aceasta înseamnă o taxă de cel puţin %1 pe kB necesar. + Can vary +/- 1 byte per input. Poate varia +/- 1 octet pentru fiecare intrare. @@ -866,7 +874,7 @@ command-line options Opţiuni linie de comandă - + Intro @@ -881,6 +889,10 @@ As this is the first time the program is launched, you can choose where Bitcoin Core will store its data. Dacă aceasta este prima dată cînd programul este lansat, puteţi alege unde Nucleul Bitcoin va stoca datele. + + Bitcoin Core will download and store a copy of the Bitcoin block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + Nucleul Bitcoin se va descărca şi va stoca o copie a lanţului blocului Bitcoin. Cel puţin %1GB de date vor fi stocate în acest dosar şi se va mări în timp. Portofelul va fi, de asemenea, stocat în acest dosar. + Use the default data directory Foloseşte dosarul de date implicit @@ -2335,6 +2347,10 @@ , has not been successfully broadcast yet , nu s-a propagat încă + + Open for %n more block(s) + Deschis pentru încă %n blocDeschis pentru încă %n blocuriDeschis pentru încă %n de blocuri + unknown necunoscut @@ -2365,6 +2381,10 @@ Immature (%1 confirmations, will be available after %2) Imatur (%1 confirmări, va fi disponibil după %2) + + Open for %n more block(s) + Deschis pentru încă %n blocDeschis pentru încă %n blocuriDeschis pentru încă %n de blocuri + Open until %1 Deschis până la %1 @@ -2715,10 +2735,6 @@ 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. Atenţie: fişierul wallet.dat este corupt, date salvate! Fişierul original wallet.dat a fost salvat ca wallet.{timestamp}.bak in %s; dacă balansul sau tranzactiile sînt incorecte ar trebui să restauraţi dintr-o copie de siguranţă. - - (default: 1) - (iniţial: 1) - <category> can be: <category> poate fi: @@ -2851,13 +2867,17 @@ This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. Acest produs include programe dezvoltate de către Proiectul OpenSSL pentru a fi folosite în OpenSSL Toolkit <https://www.openssl.org/> şi programe criptografice scrise de către Eric Young şi programe UPnP scrise de către Thomas Bernard. + + (default: %u) + (implicit: %u) + Accept public REST requests (default: %u) Acceptă cererile publice REST (implicit: %u) - Choose data directory on startup (default: 0) - Alege dosarul de date la pornire (implicit: 0) + Cannot resolve -whitebind address: '%s' + Nu se poate rezolva adresa -whitebind: '%s' Connect through SOCKS5 proxy @@ -2915,22 +2935,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Trimitere tranzacţii ca tranzacţii taxă-zero dacă este posibil (implicit: %u) - - Set SSL root certificates for payment request (default: -system-) - Setare rădăcină certificat SSL pentru cerere de plată (implicit: -sistem- ) - - - Set language, for example "de_DE" (default: system locale) - Setează limba, de exemplu: "de_DE" (implicit: sistem local) - Show all debugging options (usage: --help -help-debug) Arată toate opţiunile de depanare (uz: --help -help-debug) - - Show splash screen on startup (default: 1) - Afişează pe ecran splash la pornire (implicit: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Micşorează fişierul debug.log la pornirea clientului (implicit: 1 cînd nu se foloseşte -debug) @@ -2939,10 +2947,6 @@ Signing transaction failed Nu s-a reuşit semnarea tranzacţiei - - Start minimized - Începe minimizat - This is experimental software. Acesta este un program experimental. diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index b69a3bda5..00dfd833a 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -93,7 +93,11 @@ Exporting Failed Экспорт не удался - + + There was an error trying to save the address list to %1. Please try again. + Произошла ошибка при попытке сохранить список адресов, %1. Пожалуйста, попробуйте еще раз. + + AddressTableModel @@ -218,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP/префикс + + + Banned Until + Заблокировано до + + BitcoinGUI @@ -421,6 +433,10 @@ Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options Показать помощь по Bitcoin Core и получить список доступных параметров командной строки. + + %n active connection(s) to Bitcoin network + %n активных соединений с сетью Bitcoin%n активных соединений с сетью Bitcoin%n активных соединений с сетью Bitcoin%n активных соединений с сетью Bitcoin + No block source available... Источник блоков недоступен... @@ -433,10 +449,22 @@ %n hour(s) %n час%n часа%n часов%n часов + + %n day(s) + %n день%n дня%n дней%n дней + + + %n week(s) + %n неделю%n недели%n недель%n недель + %1 and %2 %1 и %2 + + %n year(s) + %n год%n лет%n лет%n года + %1 behind %1 позади @@ -854,6 +882,34 @@ command-line options параметры командной строки + + UI Options: + Настройки интерфейса: + + + Choose data directory on startup (default: %u) + Выбрать каталог данных при запуске (по умолчанию: %u) + + + Set language, for example "de_DE" (default: system locale) + Выберите язык, например "de_DE" (по умолчанию: как в системе) + + + Start minimized + Запускать свёрнутым + + + Set SSL root certificates for payment request (default: -system-) + Указать корневые SSL-сертификаты для запроса платежа (по умолчанию: -system-) + + + Show splash screen on startup (default: %u) + Показывать экран-заставку при запуске (по умолчанию: %u) + + + Reset all settings changes made over the GUI + Сбросить все настройки сделанные через графический интерфейс + Intro @@ -893,7 +949,15 @@ Error Ошибка - + + %n GB of free space available + %n ГБ свободного места доступно%n ГБ свободного места доступно%n ГБ свободного места доступно%n ГБ свободного места доступно + + + (of %n GB needed) + (из необходимых %n ГБ)(из необходимых %n ГБ)(из необходимых %n ГБ)(из необходимых %n ГБ) + + OpenURIDialog @@ -1043,10 +1107,34 @@ Port of the proxy (e.g. 9050) Порт прокси-сервера (например, 9050) + + Used for reaching peers via: + Используется для достижения участников через: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Показывается, если включено прокси SOCKS5 по умолчанию, используемое для соединения с участниками по этому типу сети. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + Tor Tor + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Подключаться к сети Bitcoin через прокси SOCKS5 для скрытых сервисов Tor. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Использовать отдельный прокси SOCKS5 для соединения с участниками через скрытые сервисы Tor: + &Window &Окно @@ -1417,6 +1505,18 @@ Current number of blocks Текущее число блоков + + Memory Pool + Пул памяти + + + Current number of transactions + Текущее число транзакций + + + Memory usage + Использование памяти + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Открыть отладочный лог-файл Bitcoin Core из текущего каталога данных. Это может занять несколько секунд для больших лог-файлов. @@ -1433,10 +1533,18 @@ &Peers &Участники + + Banned peers + Заблокированные участники + Select a peer to view detailed information. Выберите участника для просмотра подробностей. + + Whitelisted + Доверенный + Direction Направление @@ -1445,6 +1553,18 @@ Version Версия + + Starting Block + Начальный блок + + + Synced Headers + Синхронизировано заголовков + + + Synced Blocks + Синхронизировано блоков + User Agent Юзер-агент @@ -1473,6 +1593,14 @@ Ping Time Время задержки + + The duration of a currently outstanding ping. + Длительность текущего пинга. + + + Ping Wait + Время задержки + Time Offset Смещение времени @@ -1521,6 +1649,34 @@ Clear console Очистить консоль + + &Disconnect Node + &Отключить узел + + + Ban Node for + Заблокировать узел на + + + 1 &hour + 1 &час + + + 1 &day + 1 &день + + + 1 &week + 1 &неделю + + + 1 &year + 1 &год + + + &Unban Node + &Разблокировать узел + Welcome to the Bitcoin Core RPC console. Добро пожаловать в RPC-консоль Bitcoin Core. @@ -1549,6 +1705,10 @@ %1 GB %1 ГБ + + (node id: %1) + (номер узла: %1) + via %1 через %1 @@ -1941,6 +2101,10 @@ Copy change Копировать размен + + Total Amount %1 + Общая сумма %1 + or или @@ -1973,6 +2137,14 @@ Payment request expired. Запрос платежа просрочен. + + Pay only the required fee of %1 + Заплатить только обязательную комиссию %1 + + + Estimated to begin confirmation within %n block(s). + Подтверждение ожидается через %n блок.Подтверждение ожидается через %n блока.Подтверждение ожидается через %n блоков.Подтверждение ожидается через %n блоков. + The recipient address is not valid. Please recheck. Адрес получателя неверный. Пожалуйста, перепроверьте. @@ -2287,6 +2459,10 @@ Status Статус + + , broadcast through %n node(s) + , разослано через %n узел, разослано через %n узла, разослано через %n узлов, разослано через %n узлов + Date Дата @@ -2323,6 +2499,10 @@ Credit Кредит + + matures in %n more block(s) + будет доступно через %n блокбудет доступно через %n блокабудет доступно через %n блоковбудет доступно через %n блоков + not accepted не принято @@ -2395,6 +2575,10 @@ , has not been successfully broadcast yet , ещё не было успешно разослано + + Open for %n more block(s) + Открыто для ещё %n блокаОткрыто для ещё %n блоковОткрыто для ещё %n блоковОткрыто для ещё %n блоков + unknown неизвестно @@ -2425,6 +2609,10 @@ Immature (%1 confirmations, will be available after %2) Незрелый (%1 подтверждений, будет доступен после %2) + + Open for %n more block(s) + Открыто для ещё %n блокаОткрыто для ещё %n блоковОткрыто для ещё %n блоковОткрыто для ещё %n блоков + Open until %1 Открыто до %1 @@ -2453,6 +2641,10 @@ Unconfirmed Неподтверждено + + Confirming (%1 of %2 recommended confirmations) + Подтверждено(%1 подтверждений, рекомендуется %2 подтверждений) + Conflicted В противоречии @@ -2584,6 +2776,10 @@ Copy transaction ID Скопировать ID транзакции + + Copy raw transaction + Скопировать исходную транзакции + Edit label Изменить метку @@ -2731,10 +2927,42 @@ Accept command line and JSON-RPC commands Принимать командную строку и команды JSON-RPC + + If <category> is not supplied or if <category> = 1, output all debugging information. + Если <category> не предоставлена или равна 1, выводить всю отладочную информацию. + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Максимальная сумма комиссий (%s) для одной транзакции в бумажнике; слишком низкое значение может вызвать прерывание больших транзакций (по умолчанию: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Внимание: убедитесь, что дата и время на Вашем компьютере выставлены верно! Если Ваши часы идут неправильно, Bitcoin Core будет работать некорректно. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Удаление блоков выставлено ниже, чем минимум в %d Мб. Пожалуйста, используйте большее значение. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Удаление: последняя синхронизация кошелька вышла за рамки удаленных данных. Вам нужен -reindex (скачать всю цепь блоков в случае удаленного узла) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Уменьшить размер хранилища за счёт удаления (обрезания) старых блоков. Этот режим несовместим с -txindex и -rescan. Внимание: переключение этой опции обратно потребует полной загрузки цепи блоков. (по умолчанию: 0 = отключить удаление блоков, >%u = целевой размер в Мб для файлов блоков) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Повторное сканирование не возможно в режиме удаления. Вам надо будет использовать -reindex, который загрузит заново всю цепь блоков. + Error: A fatal internal error occurred, see debug.log for details Ошибка: произошла неустранимая ошибка, подробности в debug.log + + Fee (in %s/kB) to add to transactions you send (default: %s) + Комиссия (в %s/Кб) для добавления к вашим транзакциям (по умолчанию: %s) + Pruning blockstore... Очистка хранилища блоков... @@ -2743,6 +2971,10 @@ Run in the background as a daemon and accept commands Запускаться в фоне как демон и принимать команды + + Unable to start HTTP server. See debug log for details. + Невозможно запустить HTTP сервер. Смотри debug лог для подробностей. + Accept connections from outside (default: 1 if no -proxy or -connect) Принимать подключения извне (по умолчанию: 1, если не используется -proxy или -connect) @@ -2767,6 +2999,10 @@ Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Задать число потоков проверки скрипта (от %u до %d, 0=авто, <0 = оставить столько ядер свободными, по умолчанию: %d) + + The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct + База данных блоков содержит блок, который появляется из будущего. Это может из-за некорректно установленных даты и времени на вашем компьютере. Остается только перестроивать базу блоков, если вы уверены, что дата и время корректны. + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Это пре-релизная тестовая сборка - используйте на свой страх и риск - не используйте для добычи или торговых приложений @@ -2775,6 +3011,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Не удалось забиндиться на %s на этом компьютере. Возможно, Bitcoin Core уже запущен. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Использовать UPnP для проброса порта (по умолчанию: 1, если используется прослушивание и нет -proxy) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) ВНИМАНИЕ: сгенерировано ненормально большое число блоков, %d блоков получено за последние %d часов (ожидалось %d) @@ -2800,8 +3040,8 @@ Вносить в белый список участников, подключающихся с указанной маски сети или IP. Можно использовать многократно. - (default: 1) - (по умолчанию: 1) + -maxmempool must be at least %d MB + -maxmempool должен быть как минимум %d MB <category> can be: @@ -2835,6 +3075,22 @@ Do you want to rebuild the block database now? Пересобрать БД блоков прямо сейчас? + + Enable publish hash block in <address> + Включить публичный хеш блока в <address> + + + Enable publish hash transaction in <address> + Включить публичный хеш транзакции в <address> + + + Enable publish raw block in <address> + Включить публичный сырой блок в <address> + + + Enable publish raw transaction in <address> + Включить публичную сырую транзакцию в <address> + Error initializing block database Ошибка инициализации БД блоков @@ -2871,6 +3127,10 @@ Invalid -onion address: '%s' Неверный -onion адрес: '%s' + + Keep the transaction memory pool below <n> megabytes (default: %u) + Сбрасывать транзакции из памяти на диск каждые <n> мегабайт (по умолчанию: %u) + Not enough file descriptors available. Недостаточно файловых дескрипторов. @@ -2899,10 +3159,26 @@ Specify wallet file (within data directory) Укажите файл бумажника (внутри каталога данных) + + Unsupported argument -benchmark ignored, use -debug=bench. + Неподдерживаемый аргумент -benchmark проигнорирован, используйте -debug=bench. + + + Unsupported argument -debugnet ignored, use -debug=net. + Неподдерживаемый аргумент -debugnet проигнорирован, используйте -debug=net. + + + Unsupported argument -tor found, use -onion. + Обнаружен не поддерживаемый параметр -tor, используйте -onion. + Use UPnP to map the listening port (default: %u) Использовать UPnP для проброса порта (по умолчанию: %u) + + User Agent comment (%s) contains unsafe characters. + Комментарий пользователя (%s) содержит небезопасные символы. + Verifying blocks... Проверка блоков... @@ -2959,6 +3235,10 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Выполнить команду, когда приходит соответствующее сообщение о тревоге или наблюдается очень длинное расщепление цепи (%s в команде заменяется на сообщение) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Комиссии (в %s/Кб) меньшие этого значения считаются нулевыми для создания, ретрансляции, получения транзакции (по умолчанию: %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Если paytxfee не задан, включить достаточную комиссию для подтверждения транзакции в среднем за n блоков (по умолчанию: %u) @@ -3016,12 +3296,20 @@ Активируется лучшая цепь... - Cannot resolve -whitebind address: '%s' - Не удаётся разрешить адрес в параметре -whitebind: '%s' + Always relay transactions received from whitelisted peers (default: %d) + Всегда транслировать транзакции, полученные из белого списка участников (по умолчанию: %d) - Choose data directory on startup (default: 0) - Выбрать каталог данных при запуске (по умолчанию: 0) + Attempt to recover private keys from a corrupt wallet.dat on startup + Попытаться восстановить приватные ключи из повреждённого wallet.dat при запуске + + + Automatically create Tor hidden service (default: %d) + Автоматически создавать скрытый Tor сервис (по умолчанию: %d) + + + Cannot resolve -whitebind address: '%s' + Не удаётся разрешить адрес в параметре -whitebind: '%s' Connect through SOCKS5 proxy @@ -3039,6 +3327,10 @@ Error reading from database, shutting down. Ошибка чтения базы данных, работа завершается. + + Imports blocks from external blk000??.dat file on startup + Импортировать блоки из внешнего файла blk000?.dat при запуске + Information Информация @@ -3091,6 +3383,14 @@ Receive and display P2P network alerts (default: %u) Получать и отображать P2P сетевые тревоги (по умолчанию: %u) + + Reducing -maxconnections from %d to %d, because of system limitations. + Уменьшите -maxconnections с %d до %d, из-за ограничений системы. + + + Rescan the block chain for missing wallet transactions on startup + Перепроверить цепь блоков на предмет отсутствующих в бумажнике транзакций при запуске + Send trace/debug info to console instead of debug.log file Выводить информацию трассировки/отладки на консоль вместо файла debug.log @@ -3099,22 +3399,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Осуществить транзакцию бесплатно, если возможно (по умолчанию: %u) - - Set SSL root certificates for payment request (default: -system-) - Указать корневые SSL-сертификаты для запроса платежа (по умолчанию: -system-) - - - Set language, for example "de_DE" (default: system locale) - Выберите язык, например "de_DE" (по умолчанию: как в системе) - Show all debugging options (usage: --help -help-debug) Показать все отладочные параметры (использование: --help -help-debug) - - Show splash screen on startup (default: 1) - Показывать сплэш при запуске (по умолчанию: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Сжимать файл debug.log при запуске клиента (по умолчанию: 1, если нет -debug) @@ -3123,10 +3411,6 @@ Signing transaction failed Не удалось подписать транзакцию - - Start minimized - Запускать свёрнутым - The transaction amount is too small to pay the fee Сумма транзакции слишком мала для уплаты комиссии @@ -3135,6 +3419,14 @@ This is experimental software. Это экспериментальное ПО. + + Tor control port password (default: empty) + Пароль контроля порта Tor (по умолчанию: пустой) + + + Tor control port to use if onion listening enabled (default: %s) + Порт контроля Tor используется, если включено прослушивание onion (по умолчанию: %s) + Transaction amount too small Сумма транзакции слишком мала @@ -3151,14 +3443,14 @@ Transaction too large Транзакция слишком большая - - UI Options: - Настройки интерфейса: - Unable to bind to %s on this computer (bind returned error %s) Невозможно привязаться к %s на этом компьютере (bind вернул ошибку %s) + + Upgrade wallet to latest format on startup + Обновить бумажник до последнего формата при запуске + Username for JSON-RPC connections Имя для подключений JSON-RPC @@ -3171,10 +3463,18 @@ Warning Внимание + + Whether to operate in a blocks only mode (default: %u) + Будет работать в режиме только блоков (по умолчанию: %u) + Zapping all transactions from wallet... Стираем все транзакции из кошелька... + + ZeroMQ notification options: + ZeroMQ параметры оповещения: + wallet.dat corrupt, salvage failed wallet.dat повреждён, спасение данных не удалось @@ -3207,6 +3507,26 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = сохранять метаданные транзакции: например, владельца аккаунта и информацию запроса платежа; 2 = отбросить метаданные) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + Установлено очень большое значение -maxtxfee. Такие большие комиссии могут быть уплачены в отдельной транзакции. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + Установлено очень большое значение -paytxfee. Такие большие комиссии могут быть уплачены в отдельной транзакции. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Не хранить транзакции в памяти дольше, чем <n> часов (по умолчанию %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Ошибка чтения wallet.dat! Все ключи прочитаны верно, но данные транзакций или записи адресной книги могут отсутствовать или быть неправильными. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Комиссии (в %s/Кб) меньшие этого значения считаются нулевыми при создании транзакций (по умолчанию: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Насколько тщательна проверка контрольных блоков -checkblocks (0-4, по умолчанию: %u) @@ -3223,10 +3543,30 @@ Output debugging information (default: %u, supplying <category> is optional) Выводить отладочную информацию (по умолчанию: %u, указание <category> необязательно) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Поддерживать фильтрацию блоков и транзакций с помощью фильтра Блума (по умолчанию: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + Текущая длина строки версии сети (%i) превышает максимальную длину (%i). Увеливается количество или размер uacomments. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Пытается ограничить исходящий трафик до (в МБ за 24ч), 0 = не ограничивать (по умолчанию: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Обнаружен не поддерживаемый аргумент -socks. Выбор версии SOCKS более невозможен, поддерживаются только прокси SOCKS5. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Использовать отдельный прокси SOCKS5 для соединения с участниками через скрытые сервисы Tor (по умолчанию: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Имя пользователя и хэш пароля для JSON-RPC соединений. Поле <userpw> использует формат: <USERNAME>:<SALT>$<HASH>. Каноничный пример скрипта на питоне включен в "share/rpcuser". Эта опция может быть указана несколько раз + (default: %s) (по умолчанию: %s) @@ -3295,6 +3635,10 @@ Set key pool size to <n> (default: %u) Установить размер пула ключей в <n> (по умолчанию: %u) + + Set minimum block size in bytes (default: %u) + Задать минимальный размер блока в байтах (по умолчанию: %u) + Set the number of threads to service RPC calls (default: %d) Задать число потоков выполнения запросов RPC (по умолчанию: %d) diff --git a/src/qt/locale/bitcoin_ru_RU.ts b/src/qt/locale/bitcoin_ru_RU.ts new file mode 100644 index 000000000..53a1c1d8a --- /dev/null +++ b/src/qt/locale/bitcoin_ru_RU.ts @@ -0,0 +1,245 @@ + + + AddressBookPage + + + AddressTableModel + + + AskPassphraseDialog + + + BanTableModel + + + BitcoinGUI + + Bitcoin Core + Bitcoin Core + + + &About Bitcoin Core + О Bitcoin Core + + + &Command-line options + Опции командной строки + + + Error + Ошибка + + + Warning + Предупреждение + + + Information + Информация + + + + ClientModel + + + CoinControlDialog + + Date + Дата + + + Confirmations + Подтверждения + + + Confirmed + Подтвержденные + + + Copy address + Копировать адрес + + + yes + Да + + + no + Нет + + + + EditAddressDialog + + Edit Address + Изменить адрес + + + + FreespaceChecker + + + HelpMessageDialog + + Bitcoin Core + Bitcoin Core + + + version + версия + + + About Bitcoin Core + О Bitcoin Core + + + Command-line options + Опции командной строки + + + command-line options + Опции командной строки + + + + Intro + + Bitcoin Core + Bitcoin Core + + + Error + Ошибка + + + + OpenURIDialog + + Open URI + Открыть URI + + + URI: + URI: + + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + &Information + Информация + + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + + RecentRequestsTableModel + + Date + Дата + + + + SendCoinsDialog + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + Bitcoin Core + Bitcoin Core + + + + TrafficGraphWidget + + + TransactionDesc + + Date + Дата + + + + TransactionDescDialog + + + TransactionTableModel + + Date + Дата + + + + TransactionView + + Copy address + Копировать адрес + + + Confirmed + Подтвержденные + + + Date + Дата + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + + bitcoin-core + + Information + Информация + + + Warning + Предупреждение + + + Error + Ошибка + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_sah.ts b/src/qt/locale/bitcoin_sah.ts deleted file mode 100644 index 8af88a87d..000000000 --- a/src/qt/locale/bitcoin_sah.ts +++ /dev/null @@ -1,113 +0,0 @@ - - - AddressBookPage - - - AddressTableModel - - - AskPassphraseDialog - - - BanTableModel - - - BitcoinGUI - - - ClientModel - - - CoinControlDialog - - - EditAddressDialog - - - FreespaceChecker - - - HelpMessageDialog - - - Intro - - - OpenURIDialog - - - OptionsDialog - - - OverviewPage - - - PaymentServer - - - PeerTableModel - - - QObject - - - QRImageWidget - - - RPCConsole - - - ReceiveCoinsDialog - - - ReceiveRequestDialog - - - RecentRequestsTableModel - - - SendCoinsDialog - - - SendCoinsEntry - - - ShutdownWindow - - - SignVerifyMessageDialog - - - SplashScreen - - - TrafficGraphWidget - - - TransactionDesc - - - TransactionDescDialog - - - TransactionTableModel - - - TransactionView - - - UnitDisplayStatusBarControl - - - WalletFrame - - - WalletModel - - - WalletView - - - bitcoin-core - - \ No newline at end of file diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index 83f5f2c8e..8c779cbe9 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -874,7 +874,7 @@ command-line options voľby príkazového riadku - + Intro @@ -1071,6 +1071,10 @@ Port of the proxy (e.g. 9050) Port proxy (napr. 9050) + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Použiť samostatný SOCKS5 proxy server na dosiahnutie počítačov cez skryté služby Tor: + &Window Okno @@ -2797,10 +2801,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Uzle na zoznam povolených, ktoré sa pripájajú z danej netmask alebo IP adresy. Môže byť zadané viac krát. - - (default: 1) - (predvolené: 1) - <category> can be: <category> môže byť: @@ -2985,10 +2985,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Cannot resolve -whitebind address: '%s' Nedá sa vyriešiť -whitebind adresa: '%s' - - Choose data directory on startup (default: 0) - Zvoľte dátový priečinok pri štarte (prednastavené: 0) - Connect through SOCKS5 proxy Pripojiť cez proxy server SOCKS5 @@ -3057,22 +3053,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Send transactions as zero-fee transactions if possible (default: %u) Poslať ako transakcie bez poplatku, ak je to možné (predvolené: %u) - - Set SSL root certificates for payment request (default: -system-) - Nastaviť koreňový certifikát pre výzvy na platbu (prednastavené: -system-) - - - Set language, for example "de_DE" (default: system locale) - Nastaviť jazyk, napríklad "sk_SK" (predvolené: systémový) - Show all debugging options (usage: --help -help-debug) Zobraziť všetky možnosti ladenia (použitie: --help --help-debug) - - Show splash screen on startup (default: 1) - Zobraziť splash screen pri spustení (predvolené: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Zmenšiť debug.log pri spustení klienta (predvolené: 1 ak bez -debug) @@ -3081,10 +3065,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Signing transaction failed Podpísanie správy zlyhalo - - Start minimized - Spustiť minimalizované - This is experimental software. Toto je experimentálny softvér. @@ -3105,10 +3085,6 @@ The network does not appear to fully agree! Some miners appear to be experiencin Transaction too large Transakcia príliš veľká - - UI Options: - Možnosti používateľského rozhrania: - Unable to bind to %s on this computer (bind returned error %s) Na tomto počítači sa nedá vytvoriť väzba %s (vytvorenie väzby vrátilo chybu %s) @@ -3189,6 +3165,10 @@ The network does not appear to fully agree! Some miners appear to be experiencin Error loading wallet.dat Chyba načítania wallet.dat + + Generate coins (default: %u) + Generovať mince (predvolené: %u) + How many blocks to check at startup (default: %u, 0 = all) Koľko blokov overiť pri spustení (predvolené: %u, 0 = všetky) diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index ca6581039..c62c8cf27 100644 --- a/src/qt/locale/bitcoin_sl_SI.ts +++ b/src/qt/locale/bitcoin_sl_SI.ts @@ -874,7 +874,7 @@ command-line options možnosti ukazne vrstice - + Intro @@ -917,7 +917,11 @@ %n GB of free space available %n GiB prostega prostora na voljo%n GiB prostega prostora na voljo%n GiB prostega prostora na voljo%n GiB prostega prostora na voljo - + + (of %n GB needed) + (od potrebnih %n GiB)(od potrebnih %n GiB)(od potrebnih %n GiB)(od potrebnih %n GiB) + + OpenURIDialog @@ -1067,6 +1071,10 @@ Port of the proxy (e.g. 9050) Vrata posredniškega strežnika (npr. 9050) + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Za dostop do soležnikov preko skritih storitev Tor uporabi drug posredniški strežnik SOCKS5: + &Window O&kno @@ -2831,10 +2839,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Sprejemaj povezave samo od soležnikov, ki so na naslovih, ki ustrezajo navedeni omrežni maski ali naslovu. Opcijo lahko navedete večkrat. - - (default: 1) - (privzeto: 1) - <category> can be: <category> je lahko: @@ -3011,10 +3015,6 @@ Cannot resolve -whitebind address: '%s' Naslova %s, podanega pri opciji -whitebind ni mogoče razrešiti. - - Choose data directory on startup (default: 0) - Ob zagonu pozovi uporabnika, naj izbere podatkovno mapo (privzeto: 0) - Connect through SOCKS5 proxy Poveži se preko posredniškega strežnika SOCKS5 @@ -3027,6 +3027,18 @@ Information Informacije + + Invalid amount for -maxtxfee=<amount>: '%s' + Neveljavna količina za -maxtxfee=<amount>: '%s' + + + Invalid amount for -minrelaytxfee=<amount>: '%s' + Neveljavna količina za -minrelaytxfee=<amount>: '%s' + + + Invalid amount for -mintxfee=<amount>: '%s' + Neveljavna količina za -mintxfee=<amount>: '%s' + Need to specify a port with -whitebind: '%s' Pri opciji -whitebind morate navesti vrata: %s @@ -3035,18 +3047,6 @@ Send trace/debug info to console instead of debug.log file Pošilja sledilne/razhroščevalne informacije na konzolo namesto v datoteko debug.log - - Set SSL root certificates for payment request (default: -system-) - Nastavi korenske certifikate SSL za preverjanje zahtevkov za plačilo (privzeto: -system-) - - - Set language, for example "de_DE" (default: system locale) - Nastavi jezik, npr. "sl_SI" (privzeto: jezik sistema) - - - Show splash screen on startup (default: 1) - Ob zagonu prikaži uvodni zaslon (privzeto: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Ob zagonu skrajšaj datoteko debug.log (privzeto: 1, če ni vklopljena opcija -debug) @@ -3055,10 +3055,6 @@ Signing transaction failed Transakcije ni bilo mogoče podpisati. - - Start minimized - Zaženi v minimiranem oknu - This is experimental software. Program je eksperimentalne narave. @@ -3075,10 +3071,6 @@ Transaction too large Transkacija je prevelika - - UI Options: - Možnosti uporabniškega vmesnika: - Unable to bind to %s on this computer (bind returned error %s) Na tem računalniku ni bilo mogoče vezati naslova %s (vrnjena napaka: %s) diff --git a/src/qt/locale/bitcoin_sq.ts b/src/qt/locale/bitcoin_sq.ts index 769b45b56..994b06599 100644 --- a/src/qt/locale/bitcoin_sq.ts +++ b/src/qt/locale/bitcoin_sq.ts @@ -201,6 +201,10 @@ &Options... &Opsione + + &Receiving addresses... + Duke marr adresen + Change the passphrase used for wallet encryption Ndrysho frazkalimin e përdorur per enkriptimin e portofolit @@ -421,6 +425,10 @@ Options Opsionet + + W&allet + Portofol + OverviewPage @@ -447,6 +455,10 @@ RPCConsole + + &Information + Informacion + &Open &Hap @@ -466,13 +478,25 @@ ReceiveCoinsDialog + + &Amount: + Shuma: + &Label: &Etiketë: + + Clear + Pastro + ReceiveRequestDialog + + Copy &Address + &Kopjo adresen + Address Adresë @@ -511,6 +535,10 @@ Send Coins Dërgo Monedha + + Insufficient funds! + Fonde te pamjaftueshme + Amount: Shuma: @@ -570,6 +598,10 @@ Alt+P Alt+P + + Pay To: + Paguaj drejt: + ShutdownWindow @@ -621,6 +653,10 @@ Date Data + + Transaction + transaksionit + Amount Sasia @@ -757,6 +793,10 @@ bitcoin-core + + Options: + Opsionet: + Information Informacion diff --git a/src/qt/locale/bitcoin_sr.ts b/src/qt/locale/bitcoin_sr.ts index 425c077b2..b6ba896b3 100644 --- a/src/qt/locale/bitcoin_sr.ts +++ b/src/qt/locale/bitcoin_sr.ts @@ -221,6 +221,10 @@ Tabs toolbar Трака са картицама + + &About Bitcoin Core + O Bitcoin Coru + Up to date Ажурно @@ -337,6 +341,10 @@ Options Поставке + + W&allet + новчаник + &Unit to show amounts in: &Јединица за приказивање износа: @@ -374,10 +382,18 @@ ReceiveCoinsDialog + + &Amount: + Iznos: + &Label: &Етикета + + &Message: + Poruka: + Copy label kopiraj naziv @@ -389,6 +405,10 @@ ReceiveRequestDialog + + Copy &Address + Kopirajte adresu + Address Адреса @@ -401,6 +421,10 @@ Label Етикета + + Message + Poruka + RecentRequestsTableModel @@ -412,6 +436,10 @@ Label Етикета + + Message + Poruka + Amount iznos @@ -450,6 +478,10 @@ SendCoinsEntry + + A&mount: + Iznos: + &Label: &Етикета @@ -513,6 +545,14 @@ label етикета + + Message + Poruka + + + Transaction + transakcije + Amount iznos diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index 69c175645..756114351 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -738,6 +738,10 @@ Var vänlig och försök igen. This label turns red if any recipient receives an amount smaller than %1. Denna etikett blir röd om någon mottagare får ett belopp mindre än %1. + + Can vary +/- %1 satoshi(s) per input. + Kan variera +/- %1 satoshi per inmatning. + yes ja @@ -879,6 +883,34 @@ Var vänlig och försök igen. command-line options kommandoradsalternativ + + UI Options: + UI-inställningar: + + + Choose data directory on startup (default: %u) + Välj datakatalog vid uppstart (standard: %u) + + + Set language, for example "de_DE" (default: system locale) + Ange språk, till exempel "de_DE" (standard: systemspråk) + + + Start minimized + Starta minimerad + + + Set SSL root certificates for payment request (default: -system-) + Ange SSL rotcertifikat för betalningsansökan (standard: -system-) + + + Show splash screen on startup (default: %u) + Visa startbild vid uppstart (standard: %u) + + + Reset all settings changes made over the GUI + Återställ alla inställningar som gjorts över GUI + Intro @@ -1474,6 +1506,18 @@ Var vänlig och försök igen. Current number of blocks Aktuellt antal block + + Memory Pool + Minnespool + + + Current number of transactions + Nuvarande antal transaktioner + + + Memory usage + Minnesåtgång + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Öppna felsökningsloggfilen för Bitcoin Core från den nuvarande datakatalogen. Detta kan ta några sekunder om loggfilen är stor. @@ -1697,6 +1741,10 @@ Var vänlig och försök igen. ReceiveCoinsDialog + + &Amount: + &Belopp: + &Label: &Etikett: @@ -2054,6 +2102,10 @@ Var vänlig och försök igen. Copy change Kopiera växel + + Total Amount %1 + Total summa %1 + or eller @@ -2086,6 +2138,10 @@ Var vänlig och försök igen. Payment request expired. Betalningsbegäran löpte ut. + + Pay only the required fee of %1 + Betala endast den nödvändiga avgiften på %1 + Estimated to begin confirmation within %n block(s). Uppskattas till att påbörja bekräftelse inom %n block.Uppskattas till att påbörja bekräftelse inom %n block. @@ -2173,6 +2229,10 @@ Var vänlig och försök igen. 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. Avgiften dras från beloppet som skickas. Mottagaren kommer att få mindre bitcoins än du angivit i belopp-fältet. Om flera mottagare valts kommer avgiften delas jämt. + + S&ubtract fee from amount + S&ubtrahera avgiften från beloppet + Message: Meddelande: @@ -2717,6 +2777,10 @@ Var vänlig och försök igen. Copy transaction ID Kopiera transaktions ID + + Copy raw transaction + Kopiera rå transaktion + Edit label Ändra etikett @@ -2976,10 +3040,6 @@ Var vänlig och försök igen. Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Vitlista klienter som ansluter från angivna nätmasker eller IP-adresser. Kan specificeras flera gånger. - - (default: 1) - (förvalt: 1) - -maxmempool must be at least %d MB -maxmempool måste vara minst %d MB @@ -3176,6 +3236,10 @@ Var vänlig och försök igen. Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Exekvera kommando när ett relevant meddelande är mottagen eller när vi ser en väldigt lång förgrening (%s i cmd är utbytt med ett meddelande) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Avgifter (i %s/kB) mindre än detta betraktas som nollavgift för vidarebefordran, mining och transaktionsskapande (förvalt: %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Om paytxfee inte är satt, inkludera tillräcklig avgift så att transaktionen börjar att konfirmeras inom n blocks (förvalt: %u) @@ -3200,6 +3264,10 @@ Var vänlig och försök igen. Set maximum size of high-priority/low-fee transactions in bytes (default: %d) Sätt den maximala storleken av hög-prioriterade/låg-avgifts transaktioner i byte (förvalt: %d) + + Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) + Ange antalet trådar för myntgenerering om påslagen (-1= alla kärnor, förval: %d) + The transaction amount is too small to send after the fee has been deducted Transaktionen är för liten att skicka efter det att avgiften har dragits @@ -3229,12 +3297,20 @@ Var vänlig och försök igen. Aktiverar bästa kedjan... - Cannot resolve -whitebind address: '%s' - Kan inte matcha -whitebind adress: '%s' + Always relay transactions received from whitelisted peers (default: %d) + Vidarebefordra alltid transaktioner från vitlistade noder (förval: %d) - Choose data directory on startup (default: 0) - Välj datakatalog vid uppstart (förvalt: 0) + Attempt to recover private keys from a corrupt wallet.dat on startup + Försök att rädda privata nycklar från en korrupt wallet.dat vid uppstart + + + Automatically create Tor hidden service (default: %d) + Skapa automatiskt dold tjänst i Tor (förval: %d) + + + Cannot resolve -whitebind address: '%s' + Kan inte matcha -whitebind adress: '%s' Connect through SOCKS5 proxy @@ -3252,6 +3328,10 @@ Var vänlig och försök igen. Error reading from database, shutting down. Fel vid läsning från databas, avslutar. + + Imports blocks from external blk000??.dat file on startup + Importera block från extern blk000??.dat-fil vid uppstart + Information Information @@ -3308,6 +3388,10 @@ Var vänlig och försök igen. Reducing -maxconnections from %d to %d, because of system limitations. Minskar -maxconnections från %d till %d, på grund av systembegränsningar. + + Rescan the block chain for missing wallet transactions on startup + Sök i blockkedjan efter saknade plånbokstransaktioner vid uppstart + Send trace/debug info to console instead of debug.log file Skicka trace-/debuginformation till terminalen istället för till debug.log @@ -3316,22 +3400,10 @@ Var vänlig och försök igen. Send transactions as zero-fee transactions if possible (default: %u) Sänd transaktioner som nollavgiftstransaktioner om möjligt (förvalt: %u) - - Set SSL root certificates for payment request (default: -system-) - Sätt SSL root-certifikat för betalningsbegäran (förvalt: -system-) - - - Set language, for example "de_DE" (default: system locale) - Ändra språk, till exempel "de_DE" (förvalt: systemets språk) - Show all debugging options (usage: --help -help-debug) Visa alla avlusningsalternativ (använd: --help -help-debug) - - Show splash screen on startup (default: 1) - Visa startbilden vid uppstart (förvalt: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Krymp debug.log filen vid klient start (förvalt: 1 vid ingen -debug) @@ -3340,10 +3412,6 @@ Var vänlig och försök igen. Signing transaction failed Signering av transaktion misslyckades - - Start minimized - Starta som minimerad - The transaction amount is too small to pay the fee Transaktionen är för liten för att betala avgiften @@ -3352,6 +3420,14 @@ Var vänlig och försök igen. This is experimental software. Detta är experimentmjukvara. + + Tor control port password (default: empty) + Lösenord för Tor-kontrollport (förval: inget) + + + Tor control port to use if onion listening enabled (default: %s) + Tor-kontrollport att använda om onion är aktiverat (förval: %s) + Transaction amount too small Transaktions belopp för liten @@ -3368,14 +3444,14 @@ Var vänlig och försök igen. Transaction too large Transaktionen är för stor - - UI Options: - UI Alternativ: - Unable to bind to %s on this computer (bind returned error %s) Det går inte att binda till %s på den här datorn (bind returnerade felmeddelande %s) + + Upgrade wallet to latest format on startup + Uppgradera plånbok till senaste formatet vid uppstart + Username for JSON-RPC connections Användarnamn för JSON-RPC-anslutningar @@ -3388,6 +3464,10 @@ Var vänlig och försök igen. Warning Varning + + Whether to operate in a blocks only mode (default: %u) + Ska allt göras i endast block-läge (förval: %u) + Zapping all transactions from wallet... Töm plånboken på alla transaktioner... @@ -3444,6 +3524,10 @@ Var vänlig och försök igen. Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Fel vid läsning av wallet.dat! Alla nycklar lästes korrekt, men transaktionsdata eller adressbokens poster kanske saknas eller är felaktiga. + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Avgifter (i %s/kB) mindre än detta anses vara nollavgifter vid skapande av transaktion (standard: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Hur grundlig blockverifikationen vid -checkblocks är (0-4, förvalt: %u) @@ -3460,6 +3544,10 @@ Var vänlig och försök igen. Output debugging information (default: %u, supplying <category> is optional) Skriv ut avlusningsinformation (förvalt: %u, att ange <category> är frivilligt) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Stöd filtrering av block och transaktioner med bloomfilter (standard: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. Total längd på strängen för nätverksversion (%i) överskrider maxlängden (%i). Minska numret eller storleken på uacomments. @@ -3476,6 +3564,10 @@ Var vänlig och försök igen. Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Använd separat SOCKS5 proxy för att nå kollegor via dolda tjänster i Tor (förvalt: -%s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Användarnamn och hashat lösenord för JSON-RPC-anslutningar. Fältet <userpw> kommer i formatet: <USERNAME>:<SALT>$<HASH>. Ett kanoniskt pythonskript finns inkluderat i share/rpcuser. Detta alternativ kan anges flera gånger + (default: %s) (förvalt: %s) diff --git a/src/qt/locale/bitcoin_th_TH.ts b/src/qt/locale/bitcoin_th_TH.ts index 75fdfc5bd..79a55cdd5 100644 --- a/src/qt/locale/bitcoin_th_TH.ts +++ b/src/qt/locale/bitcoin_th_TH.ts @@ -282,6 +282,10 @@ ReceiveCoinsDialog + + &Label: + &ชื่อ: + ReceiveRequestDialog @@ -318,6 +322,10 @@ SendCoinsEntry + + &Label: + &ชื่อ: + ShutdownWindow @@ -385,5 +393,9 @@ bitcoin-core + + Options: + ตัวเลือก: + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index fa8392b3d..96fca8bb2 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -222,7 +222,15 @@ BanTableModel - + + IP/Netmask + IP/Ağ maskesi + + + Banned Until + Şu vakte kadar yasaklı: + + BitcoinGUI @@ -874,6 +882,34 @@ command-line options komut satırı seçenekleri + + UI Options: + Arayüz Seçenekleri: + + + Choose data directory on startup (default: %u) + Başlangıçta veri klasörü seç (varsayılan: %u) + + + Set language, for example "de_DE" (default: system locale) + Lisan belirt, mesela "de_De" (varsayılan: sistem dili) + + + Start minimized + Küçültülmüş olarak başlat + + + Set SSL root certificates for payment request (default: -system-) + Ödeme talebi için SSL kök sertifikalarını belirle (varsayılan: -system-) + + + Show splash screen on startup (default: %u) + Başlatıldığında başlangıç ekranını göster (varsayılan: %u) + + + Reset all settings changes made over the GUI + Arayüzde yapılan tüm seçenek değişikliklerini sıfırla + Intro @@ -1071,6 +1107,34 @@ Port of the proxy (e.g. 9050) Vekil sunucunun portu (mesela 9050) + + Used for reaching peers via: + Eşlere ulaşmak için kullanılır, şu yoluyla: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Bu şebeke türü yoluyla eşlere bağlanmak için belirtilen varsayılan SOCKS5 vekil sunucusunun kullanılıp kullanılmadığını gösterir. + + + IPv4 + IPv4 + + + IPv6 + IPv6 + + + Tor + Tor + + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Bitcoin şebekesine gizli Tor servisleri için ayrı bir SOCKS5 vekil sunucusu vasıtasıyla bağlan. + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + Eşlere gizli Tor servisleri ile ulaşmak için ayrı SOCKS5 vekil sunucusu kullan: + &Window &Pencere @@ -1441,6 +1505,18 @@ Current number of blocks Güncel blok sayısı + + Memory Pool + Bellek Alanı + + + Current number of transactions + Güncel muamele sayısı + + + Memory usage + Bellek kullanımı + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Güncel veri klasöründen Bitcoin Çekirdeği hata ayıklama kütük dosyasını açar. Büyük kütük dosyaları için bu birkaç saniye alabilir. @@ -1457,10 +1533,18 @@ &Peers &Eşler + + Banned peers + Yasaklı eşler + Select a peer to view detailed information. Ayrıntılı bilgi görmek için bir eş seçin. + + Whitelisted + Beyaz listedekiler + Direction Yön @@ -1469,6 +1553,18 @@ Version Sürüm + + Starting Block + Başlangıç Bloku + + + Synced Headers + Eşleşmiş Başlıklar + + + Synced Blocks + Eşleşmiş Bloklar + User Agent Kullanıcı Yazılımı @@ -1497,6 +1593,14 @@ Ping Time Ping Süresi + + The duration of a currently outstanding ping. + Güncel olarak göze çarpan bir ping'in süresi. + + + Ping Wait + Ping Beklemesi + Time Offset Saat Farkı @@ -1545,6 +1649,34 @@ Clear console Konsolu temizle + + &Disconnect Node + Düğümle Bağlantıyı &Kes + + + Ban Node for + Düğümü şu süre için yasakla: + + + 1 &hour + 1 &saat + + + 1 &day + 1 &gün + + + 1 &week + 1 &hafta + + + 1 &year + 1 &yıl + + + &Unban Node + Düğümün Yasağını Kald&ır + Welcome to the Bitcoin Core RPC console. Bitcoin Çekirdeği RPC konsoluna hoş geldiniz. @@ -1573,6 +1705,10 @@ %1 GB %1 GB + + (node id: %1) + (düğüm kimliği: %1) + via %1 %1 vasıtasıyla @@ -1965,6 +2101,10 @@ Copy change Para üstünü kopyala + + Total Amount %1 + Toplam Meblağ %1 + or veya @@ -1997,6 +2137,14 @@ Payment request expired. Ödeme talebinin ömrü doldu. + + Pay only the required fee of %1 + Sadece gerekli ücret olan %1 tutarını öde + + + Estimated to begin confirmation within %n block(s). + Tahmini olarak %n blok içinde teyide başlanacaktır.Tahmini olarak %n blok içinde teyide başlanacaktır. + The recipient address is not valid. Please recheck. Alıcı adresi geçerli değildir. Lütfen denetleyiniz. @@ -2628,6 +2776,10 @@ Copy transaction ID Muamele kimliğini kopyala + + Copy raw transaction + Ham muameleyi kopyala + Edit label Etiketi düzenle @@ -2775,10 +2927,54 @@ Accept command line and JSON-RPC commands Komut satırı ve JSON-RPC komutlarını kabul et + + If <category> is not supplied or if <category> = 1, output all debugging information. + Eğer <kategori> belirtilmemişse ya da <kategori> = 1 ise, tüm hata ayıklama verilerini dök. + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + Tek cüzdan muamelesinde kullanılacak azami toplam ücret (%s olarak); bunu çok düşük olarak ayarlamak büyük muameleleri iptal edebilir (varsayılan: %s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + Lütfen bilgisayarınızın saat ve tarihinin doğru olduğunu kontol ediniz! Saatinizde gecikme varsa Bitcoin Çekirdeği doğru şekilde çalışamaz. + + + Prune configured below the minimum of %d MiB. Please use a higher number. + Prune, asgari değer olan %d MiB'den düşük olarak ayarlanmıştır. Lütfen daha yüksek bir sayı kullanınız. + + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Budama: son cüzdan eşleşmesi budanmış verilerin ötesine gitmektedir. -reindex kullanmanız gerekmektedir (Budanmış düğüm ise tüm blok zincirini tekrar indirmeniz gerekir.) + + + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) + Depolama gerekliliğini eski blokları budayarak (silerek) düşür. Bu kip -txindex ve -rescan ile uyumsuzdur. İkaz: Bu ayarı geri almak tüm blok zincirini yeniden indirmeyi gerektirir. (varsayılan: 0 = blokları silmeyi devre dışı bırak, >%u = MiB olarak blok dosyaları için kullanılacak hedef boyut) + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + Tekrar taramalar budanmış kipte mümkün değildir. Tüm blok zincirini tekrar indirecek olan -reindex seçeneğini kullanmanız gerekecektir. + + + Error: A fatal internal error occurred, see debug.log for details + Hata: Ölümcül dahili bir hata meydana geldi, ayrıntılar için debug.log dosyasına bakınız + + + Fee (in %s/kB) to add to transactions you send (default: %s) + Yolladığınız muamelelere eklenecek ücret (%s/kB olarak) (varsayılan: %s) + + + Pruning blockstore... + Blockstore budanıyor... + Run in the background as a daemon and accept commands Arka planda daemon (servis) olarak çalış ve komutları kabul et + + Unable to start HTTP server. See debug log for details. + HTTP sunucusu başlatılamadı. Ayrıntılar için debug.log dosyasına bakınız. + Accept connections from outside (default: 1 if no -proxy or -connect) Dışarıdan gelen bağlantıları kabul et (varsayılan: -proxy veya -connect yoksa 1) @@ -2803,6 +2999,10 @@ Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) Betik kontrolü iş parçacıklarının sayısını belirler (%u ilâ %d, 0 = otomatik, <0 = bu sayıda çekirdeği kullanma, varsayılan: %d) + + The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct + Blok veritabanı gelecekten gibi görünen bir blok içermektedir. Bu, bilgisayarınızın saat ve tarihinin yanlış ayarlanmış olmasından kaynaklanabilir. Blok veritabanını sadece bilgisayarınızın tarih ve saatinin doğru olduğundan eminseniz yeniden derleyin. + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications Bu yayın öncesi bir deneme sürümüdür - tüm riski siz üstlenmiş olursunuz - bitcoin oluşturmak ya da ticari uygulamalar için kullanmayınız @@ -2811,6 +3011,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. Bu bilgisayarda %s unsuruna bağlanılamadı. Bitcoin Çekirdeği muhtemelen hâlihazırda çalışmaktadır. + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + Dinlenecek portu haritalamak için UPnP kullan (varsayılan: dinlenildiğinde ve -proxy olmadığında 1) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) İKAZ: anormal yüksek sayıda blok oluşturulmuştur, %d blok son %d saat içinde alınmıştır (%d bekleniyordu) @@ -2836,8 +3040,8 @@ Belirtilen ağ maskesi ya da IP adresinden bağlanan eşleri beyaz listeye al. Birden fazla kez belirtilebilir. - (default: 1) - (varsayılan: 1) + -maxmempool must be at least %d MB + -maxmempool asgari %d MB olmalıdır <category> can be: @@ -2871,6 +3075,22 @@ Do you want to rebuild the block database now? Blok veritabanını şimdi yeniden inşa etmek istiyor musunuz? + + Enable publish hash block in <address> + Blok karma değerinin <adres>te yayınlanmasını etkinleştir + + + Enable publish hash transaction in <address> + Karma değer muamelesinin <adres>te yayınlanmasını etkinleştir + + + Enable publish raw block in <address> + Ham blokun <adres>te yayınlanmasını etkinleştir + + + Enable publish raw transaction in <address> + Ham muamelenin <adres>te yayınlanmasını etkinleştir + Error initializing block database Blok veritabanını başlatılırken bir hata meydana geldi @@ -2907,6 +3127,10 @@ Invalid -onion address: '%s' Geçersiz -onion adresi: '%s' + + Keep the transaction memory pool below <n> megabytes (default: %u) + Muamele bellek alanını <n> megabayttan düşük tut (varsayılan: %u) + Not enough file descriptors available. Kafi derecede dosya tanımlayıcıları mevcut değil. @@ -2935,10 +3159,26 @@ Specify wallet file (within data directory) Cüzdan dosyası belirtiniz (veri klasörünün içinde) + + Unsupported argument -benchmark ignored, use -debug=bench. + Desteklenmeyen -benchmark argümanı görmezden gelindi, -debug=bench kullanınız. + + + Unsupported argument -debugnet ignored, use -debug=net. + Desteklenmeyen -debugnet argümanı görmezden gelindi, debug=net kullanınız. + + + Unsupported argument -tor found, use -onion. + Deskteklenmeyen -tor argümanı bulundu, -onion kullanınız. + Use UPnP to map the listening port (default: %u) Dinleme portunu haritalamak için UPnP kullan (varsayılan: %u) + + User Agent comment (%s) contains unsafe characters. + Kullanıcı Aracı açıklaması (%s) güvensiz karakterler içermektedir. + Verifying blocks... Bloklar kontrol ediliyor... @@ -2995,6 +3235,10 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) İlgili bir uyarı alındığında ya da gerçekten uzun bir çatallama gördüğümüzde komutu çalıştır (komuttaki %s mesaj ile değiştirilir) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Bundan düşük ücretler (%s/kB olarak) aktarma, oluşturma ve muamele yaratma için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Eğer paytxfee ayarlanmadıysa kafi derecede ücret ekleyin ki muameleler teyite vasati n blok içinde başlasın (varsayılan: %u) @@ -3052,12 +3296,20 @@ En iyi zincir etkinleştiriliyor... - Cannot resolve -whitebind address: '%s' - -whitebind adresi çözümlenemedi: '%s' + Always relay transactions received from whitelisted peers (default: %d) + Beyaz listedeki eşlerden gelen muameleleri daima aktar (varsayılan: %d) - Choose data directory on startup (default: 0) - Başlangıçta veri klasörü seç (varsayılan: 0) + Attempt to recover private keys from a corrupt wallet.dat on startup + Başlangıçta bozuk bir wallet.dat dosyasından özel anahtarları geri kazanmayı dene + + + Automatically create Tor hidden service (default: %d) + Otomatik olarak gizli Tor servisi oluştur (varsayılan: %d) + + + Cannot resolve -whitebind address: '%s' + -whitebind adresi çözümlenemedi: '%s' Connect through SOCKS5 proxy @@ -3075,6 +3327,10 @@ Error reading from database, shutting down. Veritabanından okumada hata, kapatılıyor. + + Imports blocks from external blk000??.dat file on startup + Başlangıçta harici blk000??.dat dosyasından blokları içe aktarır + Information Bilgi @@ -3127,6 +3383,14 @@ Receive and display P2P network alerts (default: %u) P2P ağından gelen önemli uyarıları alın ve gösterin (önseçili değer: %u) + + Reducing -maxconnections from %d to %d, because of system limitations. + Sistem sınırlamaları sebebiyle -maxconnections %d değerinden %d değerine düşürülmüştür. + + + Rescan the block chain for missing wallet transactions on startup + Başlangıçta blok zincirini eksik cüzdan muameleleri için tekrar tara + Send trace/debug info to console instead of debug.log file Trace/hata ayıklama verilerini debug.log dosyası yerine konsola gönder @@ -3135,22 +3399,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Muameleleri mümkünse ücretsiz olarak gönder (varsayılan: %u) - - Set SSL root certificates for payment request (default: -system-) - Ödeme talebi için SSL kök sertifikalarını belirle (varsayılan: -system-) - - - Set language, for example "de_DE" (default: system locale) - Lisan belirt, mesela "de_De" (varsayılan: sistem dili) - Show all debugging options (usage: --help -help-debug) Tüm hata ayıklama seçeneklerini göster (kullanımı: --help -help-debug) - - Show splash screen on startup (default: 1) - Başlatıldığında başlangıç ekranını göster (varsayılan: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) İstemci başlatıldığında debug.log dosyasını küçült (varsayılan: -debug bulunmadığında 1) @@ -3159,10 +3411,6 @@ Signing transaction failed Muamelenin imzalanması başarısız oldu - - Start minimized - Küçültülmüş olarak başlat - The transaction amount is too small to pay the fee Muamele meblağı ücreti ödemek için çok düşük @@ -3171,6 +3419,14 @@ This is experimental software. Bu, deneysel bir yazılımdır. + + Tor control port password (default: empty) + Tor kontrol portu parolası (varsayılan: boş) + + + Tor control port to use if onion listening enabled (default: %s) + Eğer onion dinlenmesi etkinse kullanılacak Tor kontrol portu (varsayılan: %s) + Transaction amount too small Muamele meblağı çok düşük @@ -3187,14 +3443,14 @@ Transaction too large Muamele çok büyük - - UI Options: - Arayüz Seçenkleri: - Unable to bind to %s on this computer (bind returned error %s) Bu bilgisayarda %s unsuruna bağlanılamadı (bağlanma %s hatasını verdi) + + Upgrade wallet to latest format on startup + Başlangıçta cüzdanı en yeni biçime güncelle + Username for JSON-RPC connections JSON-RPC bağlantıları için kullanıcı ismi @@ -3207,10 +3463,18 @@ Warning Uyarı + + Whether to operate in a blocks only mode (default: %u) + Salt blok kipinde çalışılıp çalışılmayacağı (varsayılan: %u) + Zapping all transactions from wallet... Cüzdandaki tüm muameleler kaldırılıyor... + + ZeroMQ notification options: + ZeroMQ bildirim seçenekleri: + wallet.dat corrupt, salvage failed wallet.dat bozuk, geri kazanım başarısız oldu @@ -3243,6 +3507,26 @@ (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) (1 = tx meta verilerini tut mesela hesap sahibi ve ödeme talebi bilgileri, 2 = tx meta verilerini at) + + -maxtxfee is set very high! Fees this large could be paid on a single transaction. + -maxtxfee çok yüksek bir değere ayarlanmış! Bu denli yüksek ücretler tek bir muamelede ödenebilir. + + + -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + -paytxfee çok yüksek bir değere ayarlanmış! Bu, muamele gönderirseniz ödeyeceğiniz muamele ücretidir. + + + Do not keep transactions in the mempool longer than <n> hours (default: %u) + Muameleleri bellek alanında <n> saatten fazla tutma (varsayılan: %u) + + + Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + wallet.dat dosyasının okunması sırasında bir hata meydana geldi! Tüm anahtarlar doğru bir şekilde okundu, ancak muamele verileri ya da adres defteri unsurları hatalı veya eksik olabilir. + + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Bundan düşük ücretler (%s/kB olarak) muamele oluşturulması için sıfır değerinde ücret olarak kabul edilir (varsayılan: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) -checkblocks'un blok kontrolünün ne kadar kapsamlı olacağı (0 ilâ 4, varsayılan: %u) @@ -3259,10 +3543,30 @@ Output debugging information (default: %u, supplying <category> is optional) Hata ayıklama bilgisi dök (varsayılan: %u, <kategori> sağlanması seçime dayalıdır) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Blokların ve muamelelerin bloom filtreleri ile süzülmesini destekle (varsayılan: %u) + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + Şebeke sürümü zincirinin toplam boyutu (%i) azami boyutu geçmektedir (%i). Kullanıcı aracı açıklamasının sayısı veya boyutunu azaltınız. + + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Giden trafiği belirtilen hedefin altında tutmaya çalışır (24 saat başı MiB olarak), 0 = sınırsız (varsayılan: %d) + + + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Desteklenmeyen -socks argümanı bulundu. SOCKS sürümünün ayarlanması artık mümkün değildir, sadece SOCKS5 vekilleri desteklenmektedir. + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Eşlere gizli Tor servisleri ile ulaşmak için ayrı SOCKS5 vekil sunucusu kullan (varsayılan: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + JSON-RPC bağlantıları için kullanıcı ismi ve karmalanmış parola. <userpw> alanı şu biçimdedir: <USERNAME>:<SALT>$<HASH>. Kanonik bir Python betiği share/rpcuser klasöründe bulunabilir. Bu seçenek birden çok kez belirtilebilir. + (default: %s) (varsayılan: %s) diff --git a/src/qt/locale/bitcoin_tr_TR.ts b/src/qt/locale/bitcoin_tr_TR.ts new file mode 100644 index 000000000..10866b011 --- /dev/null +++ b/src/qt/locale/bitcoin_tr_TR.ts @@ -0,0 +1,281 @@ + + + AddressBookPage + + Right-click to edit address or label + Adresi veya etiketi düzenlemek için sağ tıklayın + + + Create a new address + Yeni adres oluştur + + + &New + &Yeni + + + Copy the currently selected address to the system clipboard + Seçili adresi panoya kopyala + + + &Copy + &Kopyala + + + C&lose + K&apat + + + &Copy Address + &Adresi Kopyala + + + Delete the currently selected address from the list + Seçili adresi listeden sil + + + Export the data in the current tab to a file + Seçili sekmedeki veriyi dosya olarak dışa aktar + + + &Export + &Dışa Aktar + + + &Delete + &Sil + + + Choose the address to send coins to + Para göndereceğiniz adresi seçin + + + Choose the address to receive coins with + Parayı alacağınız adresi seçin + + + C&hoose + S&eç + + + Sending addresses + Gönderim adresleri + + + Receiving addresses + Alış adresleri + + + These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. + Bunlar ödeme gönderebileceğiniz Bitcoin adreslerinizdir. Para göndermeden önce mutlaka alıcı adresini ve tutarı kontrol edin. + + + These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + Bunlar ödeme alabileceğiniz Bitcoin adreslerinizdir. Her işlem için yeni bir adres kullanmanız önerilir. + + + Copy &Label + Kopyala &Etiketle + + + &Edit + &Düzenle + + + Export Address List + Adres Listesini Dışa Aktar + + + Exporting Failed + Dışa Aktarma Başarısız Oldu + + + There was an error trying to save the address list to %1. Please try again. + Adres listesini %1'e kaydederken bir hata oluştu. Lütfen tekrar deneyin. + + + + AddressTableModel + + Label + Etiket + + + Address + Adres + + + (no label) + (etiket yok) + + + + AskPassphraseDialog + + + BanTableModel + + + BitcoinGUI + + &Receiving addresses... + Alış adresleri + + + + ClientModel + + + CoinControlDialog + + (no label) + (etiket yok) + + + + EditAddressDialog + + &Label + Etiket + + + &Address + Adres + + + + FreespaceChecker + + + HelpMessageDialog + + + Intro + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + Copy &Address + &Adresi Kopyala + + + Address + Adres + + + Label + Etiket + + + + RecentRequestsTableModel + + Label + Etiket + + + (no label) + (etiket yok) + + + + SendCoinsDialog + + (no label) + (etiket yok) + + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDesc + + + TransactionDescDialog + + + TransactionTableModel + + Label + Etiket + + + + TransactionView + + Exporting Failed + Dışa Aktarma Başarısız Oldu + + + Label + Etiket + + + Address + Adres + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + &Export + &Dışa Aktar + + + Export the data in the current tab to a file + Seçili sekmedeki veriyi dosya olarak dışa aktar + + + + bitcoin-core + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index e0afa8eff..ea783aa85 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -882,6 +882,34 @@ command-line options параметри командного рядка + + UI Options: + Параметри інтерфейсу: + + + Choose data directory on startup (default: %u) + Обирати каталог даних під час запуску (типово: %u) + + + Set language, for example "de_DE" (default: system locale) + Встановити мову (наприклад: "de_DE") (типово: системна) + + + Start minimized + Запускати згорнутим + + + Set SSL root certificates for payment request (default: -system-) + Вказати кореневі SSL-сертифікати для запиту платежу (типово: -системні-) + + + Show splash screen on startup (default: %u) + Показувати заставку під час запуску (типово: %u) + + + Reset all settings changes made over the GUI + Скинути налаштування, які було змінено через графічний інтерфейс користувача + Intro @@ -1083,6 +1111,10 @@ Used for reaching peers via: Приєднуватися до учасників через: + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + Вказує на використання наявного типового проксі SOCKS5, що використувується задля встановлення зв'язку з пірами через мережу такого типу. + IPv4 IPv4 @@ -1473,6 +1505,18 @@ Current number of blocks Поточне число блоків + + Memory Pool + Пул пам'яті + + + Current number of transactions + Поточне число транзакцій + + + Memory usage + Використання пам'яті + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. Відкрити файл журналу налагодження Bitcoin Core з поточного каталогу даних. Це може зайняти кілька секунд для великих файлів журналів. @@ -2057,6 +2101,10 @@ Copy change Копіювати решту + + Total Amount %1 + Всього %1 + or або @@ -2089,6 +2137,10 @@ Payment request expired. Запит платежу прострочено. + + Pay only the required fee of %1 + Сплатіть лише мінімальну комісію у розмірі %1 + Estimated to begin confirmation within %n block(s). Перше підтвердження очікується протягом %n блоку.Перше підтвердження очікується протягом %n блоків.Перше підтвердження очікується протягом %n блоків. @@ -2724,6 +2776,10 @@ Copy transaction ID Скопіювати ID транзакції + + Copy raw transaction + Скопіювати RAW транзакцію + Edit label Редагувати мітку @@ -2887,6 +2943,10 @@ Prune configured below the minimum of %d MiB. Please use a higher number. Встановлений розмір ланцюжка блоків є замалим (меншим за %d МіБ). Будь ласка, виберіть більше число. + + Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) + Операція відсікання: остання синхронізація вмісту гаманцю не обмежується діями над скороченими данними. Вам необхідно зробити переіндексацію -reindex (заново завантажити веcь ланцюжок блоків в разі появи скороченого ланцюга) + Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. Warning: Reverting this setting requires re-downloading the entire blockchain. (default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files) Зменшити вимоги до наявного простору на носії даних за допомогою скорочення ланцюжка (видалення старих блоків). Цей режим несумісний з параметрами -txindex та -rescan. Увага: при поверненні до типового значення видалені частини ланцюжка буде повторно завантажено. (типово: 0 = вимкнути скорочення ланцюжка, >%u = очікуваний розмір файлів блоків в МіБ) @@ -2979,10 +3039,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. Додати учасників, що під'єднуються з заданої підмережі чи IP-адреси, в білий список. Можна вказувати декілька разів. - - (default: 1) - (типово: 1) - -maxmempool must be at least %d MB -maxmempool має бути не менше %d МБ @@ -3019,6 +3075,22 @@ Do you want to rebuild the block database now? Ви хочете перебудувати базу даних блоків зараз? + + Enable publish hash block in <address> + Дозволено введення хеш блоку в рядок <address> + + + Enable publish hash transaction in <address> + Дозволено введення хеш транзакції в рядок <address> + + + Enable publish raw block in <address> + Дозволено введення RAW блоку в рядок <address> + + + Enable publish raw transaction in <address> + Дозволено введення RAW транзакції в рядок <address> + Error initializing block database Помилка ініціалізації бази даних блоків @@ -3163,6 +3235,10 @@ Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) Виконати команду при надходженні важливого сповіщення або при спостереженні тривалого розгалуження ланцюжка (замість %s буде підставлено повідомлення) + + Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s) + Комісії (в %s/kB), що менші за вказану, вважатимуться нульовими для зміни, аналізу та створення транзакцій (типово: %s) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) Якщо параметр paytxfee не встановлено, включити комісію для отримання перших підтверджень транзакцій протягом n блоків (типово: %u) @@ -3220,12 +3296,20 @@ Активація найкращого ланцюжка... - Cannot resolve -whitebind address: '%s' - Не вдалося розпізнати адресу для -whitebind: «%s» + Always relay transactions received from whitelisted peers (default: %d) + Завжди передавайте транзакції отримані від пірів з білого списку (типово: %d) - Choose data directory on startup (default: 0) - Обрати каталог даних під час запуску (типово: 0) + Attempt to recover private keys from a corrupt wallet.dat on startup + Спочатку спробуйте відновити приватні ключі в пошкодженому wallet.dat + + + Automatically create Tor hidden service (default: %d) + Автоматичне з'єднання з прихованим сервісом Tor (типово: %d) + + + Cannot resolve -whitebind address: '%s' + Не вдалося розпізнати адресу для -whitebind: «%s» Connect through SOCKS5 proxy @@ -3243,6 +3327,10 @@ Error reading from database, shutting down. Помилка читання бази даних, припиняю роботу. + + Imports blocks from external blk000??.dat file on startup + Спочатку імпортує блоки з зовнішнього файлу blk000??.dat + Information Інформація @@ -3299,6 +3387,10 @@ Reducing -maxconnections from %d to %d, because of system limitations. Зменшення значення -maxconnections з %d до %d із-за обмежень системи. + + Rescan the block chain for missing wallet transactions on startup + Спочатку переглянте ланцюжок блоків на наявність втрачених транзакцій гаманця + Send trace/debug info to console instead of debug.log file Відсилати налагоджувальну інформацію на консоль, а не у файл debug.log @@ -3307,22 +3399,10 @@ Send transactions as zero-fee transactions if possible (default: %u) Не сплачувати комісію за надсилання транзакцій, якщо це можливо (типово: %u) - - Set SSL root certificates for payment request (default: -system-) - Вказати кореневі SSL-сертифікати для запиту платежу (типово: -системні-) - - - Set language, for example "de_DE" (default: system locale) - Встановлення мови, наприклад "de_DE" (типово: системна) - Show all debugging options (usage: --help -help-debug) Показати всі налагоджувальні параметри (використання: --help -help-debug) - - Show splash screen on startup (default: 1) - Показувати заставку під час запуску (типово: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) Стискати файл debug.log під час старту клієнта (типово: 1 коли відсутній параметр -debug) @@ -3331,10 +3411,6 @@ Signing transaction failed Підписання транзакції не вдалося - - Start minimized - Запускати згорнутим - The transaction amount is too small to pay the fee Неможливо сплатити комісію із-за малої суми транзакції @@ -3343,6 +3419,14 @@ This is experimental software. Це програмне забезпечення є експериментальним. + + Tor control port password (default: empty) + Пароль управління порт протоколом Tor (типово: empty) + + + Tor control port to use if onion listening enabled (default: %s) + Скористайтесь управлінням порт протоколом Tor, в разі перехоплення обміну цибулевої маршрутизації (типово: %s) + Transaction amount too small Сума транзакції занадто мала @@ -3359,14 +3443,14 @@ Transaction too large Транзакція занадто велика - - UI Options: - Параметри інтерфейсу: - Unable to bind to %s on this computer (bind returned error %s) Неможливо прив'язатися до %s на цьому комп'ютері (bind повернув помилку: %s) + + Upgrade wallet to latest format on startup + Спочатку оновіть гаманець до останньої версії + Username for JSON-RPC connections Ім'я користувача для JSON-RPC-з'єднань @@ -3379,6 +3463,10 @@ Warning Попередження + + Whether to operate in a blocks only mode (default: %u) + Чи слід працювати в режимі тільки блоки (типово: %u) + Zapping all transactions from wallet... Видалення всіх транзакцій з гаманця... @@ -3435,6 +3523,10 @@ Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. Помилка читання wallet.dat! Всі ключі прочитано коректно, але дані транзакцій чи записи адресної книги можуть бути пропущені або пошкоджені. + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + Комісії (в %s/kB), що менші за вказану, вважатимуться нульовими для створення транзакцій (типово: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) Рівень ретельності перевірки блоків (0-4, типово: %u) @@ -3451,10 +3543,18 @@ Output debugging information (default: %u, supplying <category> is optional) Виводити налагоджувальну інформацію (типово: %u, вказання <category> необов'язкове) + + Support filtering of blocks and transaction with bloom filters (default: %u) + Фільтрація блоків та транзакцій з допомогою фільтрів Блума (типово: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. Загальна довжина рядку мережевої версії (%i) перевищує максимально допустиму (%i). Зменшіть число чи розмір коментарів клієнта користувача. + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + Намагається зберегти вихідний трафік відповідно до зданого значення (в MIB за 24 години), 0 = без обмежень (типово: %d) + Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. Параметр -socks не підтримується. Можливість вказувати версію SOCKS було видалено, так як підтримується лише SOCKS5. @@ -3463,6 +3563,10 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Використовувати окремий SOCKS5-проксі для з'єднання з учасниками через приховані сервіси Tor (типово: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + Логін та хешований пароль для зв'язків JSON-RPC. Поле <userpw> має формат: <USERNAME>:<SALT>$<HASH>. Класичний Python script додано до share/rpcuser. Цей параметр може бути застосований декілька разів. + (default: %s) (типово: %s) diff --git a/src/qt/locale/bitcoin_ur_PK.ts b/src/qt/locale/bitcoin_ur_PK.ts index db5cca3cc..e37c87baa 100644 --- a/src/qt/locale/bitcoin_ur_PK.ts +++ b/src/qt/locale/bitcoin_ur_PK.ts @@ -123,6 +123,10 @@ CoinControlDialog + + Amount: + رقم: + Amount رقم @@ -138,6 +142,14 @@ EditAddressDialog + + &Label + چٹ + + + &Address + پتہ + FreespaceChecker @@ -185,6 +197,10 @@ ReceiveRequestDialog + + Copy &Address + کاپی پتہ + Address پتہ @@ -219,6 +235,14 @@ SendCoinsDialog + + Insufficient funds! + ناکافی فنڈز + + + Amount: + رقم: + Balance: بیلنس: diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts index 004857cf0..86724564f 100644 --- a/src/qt/locale/bitcoin_uz@Cyrl.ts +++ b/src/qt/locale/bitcoin_uz@Cyrl.ts @@ -792,6 +792,10 @@ About Bitcoin Core Bitcoin Core ҳақида + + Command-line options + Буйруқлар сатри мосламалари + Usage: Фойдаланиш: @@ -800,7 +804,7 @@ command-line options буйруқлар қатори орқали мослаш - + Intro @@ -905,6 +909,10 @@ &Network Тармоқ + + W&allet + Ҳамён + Proxy &IP: Прокси &IP рақами: @@ -1690,6 +1698,10 @@ Message: Хабар + + Pay To: + Тўлов олувчи: + ShutdownWindow @@ -2018,6 +2030,10 @@ Export Transaction History Ўтказмалар тарихини экспорт қилиш + + Watch-only + Фақат кўришга + Exporting Failed Экспорт қилиб бўлмади @@ -2113,22 +2129,10 @@ Connection options: Уланиш кўрсаткичлари: - - Choose data directory on startup (default: 0) - Ишга тушиш вақтида маълумотлар директориясини танлаш (стандарт: 0) - Information Маълумот - - Set SSL root certificates for payment request (default: -system-) - Тўлов сўровлари учун SSL асос сертификатларини ўрнатиш (стандарт: -system-) - - - Start minimized - Йиғилганларни бошлаш - Username for JSON-RPC connections JSON-RPC уланишлари учун фойдаланувчи номи @@ -2149,6 +2153,10 @@ Loading addresses... Манзиллар юкланмоқда... + + Insufficient funds + Кам миқдор + Loading block index... Тўсиқ индекси юкланмоқда... diff --git a/src/qt/locale/bitcoin_vi.ts b/src/qt/locale/bitcoin_vi.ts index 7a7c68c4b..47745a3bc 100644 --- a/src/qt/locale/bitcoin_vi.ts +++ b/src/qt/locale/bitcoin_vi.ts @@ -59,6 +59,10 @@ CoinControlDialog + + Amount: + Số lượng: + Amount Số lượng @@ -70,6 +74,14 @@ EditAddressDialog + + &Label + Nhãn dữ liệu + + + &Address + Địa chỉ + FreespaceChecker @@ -113,6 +125,10 @@ ReceiveRequestDialog + + Copy &Address + Sao chép địa chỉ + Address Địa chỉ @@ -143,6 +159,10 @@ SendCoinsDialog + + Amount: + Số lượng: + (no label) (chưa có nhãn) diff --git a/src/qt/locale/bitcoin_vi_VN.ts b/src/qt/locale/bitcoin_vi_VN.ts index c55aecd82..d55fa6188 100644 --- a/src/qt/locale/bitcoin_vi_VN.ts +++ b/src/qt/locale/bitcoin_vi_VN.ts @@ -165,6 +165,10 @@ Show information about Qt Xem thông tin về Qt + + &Receiving addresses... + Địa chỉ nhận + Open &URI... Mở &URI... @@ -354,6 +358,14 @@ EditAddressDialog + + &Label + Nhãn + + + &Address + Địa chỉ + FreespaceChecker @@ -417,6 +429,10 @@ MB MB + + W&allet + + &Display &Hiển thị @@ -467,6 +483,10 @@ RPCConsole + + &Information + Thông tin + General Nhìn Chung @@ -490,6 +510,10 @@ ReceiveCoinsDialog + + &Amount: + Lượng: + Copy label Copy nhãn @@ -501,6 +525,10 @@ ReceiveRequestDialog + + Copy &Address + &Copy Địa Chỉ + Address Địa chỉ @@ -535,6 +563,10 @@ SendCoinsDialog + + Insufficient funds! + Không đủ tiền + Quantity: Lượng: @@ -570,6 +602,10 @@ SendCoinsEntry + + A&mount: + Lượng: + ShutdownWindow @@ -673,6 +709,14 @@ bitcoin-core + + Options: + Lựa chọn: + + + (default: %u) + (mặc định: %u) + Information Thông tin diff --git a/src/qt/locale/bitcoin_zh.ts b/src/qt/locale/bitcoin_zh.ts new file mode 100644 index 000000000..aeb4faa71 --- /dev/null +++ b/src/qt/locale/bitcoin_zh.ts @@ -0,0 +1,221 @@ + + + AddressBookPage + + + AddressTableModel + + + AskPassphraseDialog + + + BanTableModel + + + BitcoinGUI + + Error + 错误 + + + Warning + 警告 + + + + ClientModel + + + CoinControlDialog + + Date + 日期 + + + + EditAddressDialog + + + FreespaceChecker + + + HelpMessageDialog + + + Intro + + Error + 错误 + + + + OpenURIDialog + + + OptionsDialog + + + OverviewPage + + + PaymentServer + + + PeerTableModel + + + QObject + + + QRImageWidget + + + RPCConsole + + + ReceiveCoinsDialog + + + ReceiveRequestDialog + + + RecentRequestsTableModel + + Date + 日期 + + + + SendCoinsDialog + + Insufficient funds! + 余额不足 + + + Choose... + 选择... + + + Pay only the required fee of %1 + 仅支付全额的%1 + + + The recipient address is not valid. Please recheck. + 收款人地址无效,请再次确认。 + + + Warning: Invalid Bitcoin address + 警告:比特币地址无效 + + + + SendCoinsEntry + + + ShutdownWindow + + + SignVerifyMessageDialog + + + SplashScreen + + + TrafficGraphWidget + + + TransactionDesc + + Date + 日期 + + + + TransactionDescDialog + + + TransactionTableModel + + Date + 日期 + + + + TransactionView + + Date + 日期 + + + + UnitDisplayStatusBarControl + + + WalletFrame + + + WalletModel + + + WalletView + + + bitcoin-core + + Transaction amounts must be positive + 转账额度须为正数 + + + Transaction too large for fee policy + 根据费率标准,本次转账超额 + + + Transaction too large + 超额转账 + + + Warning + 警告 + + + wallet.dat corrupt, salvage failed + wallet.dat文件受损,修复失败 + + + This help message + 此条帮助信息 + + + Loading addresses... + 正在载入地址... + + + Error loading wallet.dat: Wallet corrupted + wallet.dat文件加载错误:钱包受损 + + + Error loading wallet.dat + wallet.dat文件加载错误 + + + Insufficient funds + 余额不足 + + + Loading wallet... + 正在载入钱包... + + + Rescanning... + 再次扫描... + + + Done loading + 载入完成 + + + Error + 错误 + + + \ No newline at end of file diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index 1cd7eed50..0ae2c95c6 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -23,7 +23,7 @@ C&lose - 关闭(&C) + 关闭(&l) &Copy Address @@ -133,7 +133,7 @@ Encrypt wallet - 钱包加密 + 加密钱包 This operation needs your wallet passphrase to unlock the wallet. @@ -226,7 +226,11 @@ IP/Netmask IP/网络掩码 - + + Banned Until + 在此之前禁止: + + BitcoinGUI @@ -267,7 +271,7 @@ About &Qt - 关于 &Qt + 关于Qt(&Q) Show information about Qt @@ -303,7 +307,7 @@ Bitcoin Core client - 比特币核心钱包 + 比特币核心钱包客户端 Importing blocks from disk... @@ -311,7 +315,7 @@ Reindexing blocks on disk... - 正在为数据块建立索引... + 正在为数据块重建索引... Send coins to a Bitcoin address @@ -878,6 +882,34 @@ command-line options 命令行选项 + + UI Options: + 界面选项: + + + Choose data directory on startup (default: %u) + 在启动时选择目录(默认%u) + + + Set language, for example "de_DE" (default: system locale) + 设置语言, 例如“zh-CN”(默认:系统语言) + + + Start minimized + 启动时最小化 + + + Set SSL root certificates for payment request (default: -system-) + 设置付款请求的SSL根证书(默认:-系统-) + + + Show splash screen on startup (default: %u) + 显示启动画面(默认:%u) + + + Reset all settings changes made over the GUI + 重置所有图形界面所做的更改 + Intro @@ -1075,6 +1107,14 @@ Port of the proxy (e.g. 9050) 代理端口(例如 9050) + + Used for reaching peers via: + 连接到同伴的方式: + + + Shows, if the supplied default SOCKS5 proxy is used to reach peers via this network type. + 如果默认的SOCKS5代理被用于在该网络下连接同伴,则显示 + IPv4 IPv4 @@ -1087,6 +1127,14 @@ Tor Tor + + Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + 在Tor匿名网络下通过不同的SOCKS5代理连接比特币网络 + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services: + 通过Tor隐藏服务连接节点时 使用不同的SOCKS5代理 + &Window 窗口(&W) @@ -1457,6 +1505,18 @@ Current number of blocks 当前数据块数量 + + Memory Pool + 资金池 + + + Current number of transactions + 当前交易数量 + + + Memory usage + 内存使用 + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. 从当前的数据目录打开比特币核心调试日志文件。对于较大的日志文件,这可能需要几秒钟。 @@ -1473,6 +1533,10 @@ &Peers 同伴(&P) + + Banned peers + 节点黑名单 + Select a peer to view detailed information. 选择节点查看详细信息。 @@ -1489,6 +1553,10 @@ Version 版本 + + Starting Block + 正在启动数据块 + Synced Headers 同步区块头 @@ -1525,6 +1593,10 @@ Ping Time Ping 时间 + + Ping Wait + Ping等待 + Time Offset 时间偏移 @@ -1573,6 +1645,14 @@ Clear console 清空控制台 + + &Disconnect Node + (&D)断开节点连接 + + + Ban Node for + 禁止节点连接时长: + 1 &hour 1 小时(&H) @@ -1589,6 +1669,10 @@ 1 &year 1 年(&Y) + + &Unban Node + (&U)允许节点连接 + Welcome to the Bitcoin Core RPC console. 欢迎使用 比特币核心 RPC 控制台。 @@ -2013,6 +2097,10 @@ Copy change 复制零钱 + + Total Amount %1 + 总金额 %1 + or @@ -2045,6 +2133,10 @@ Payment request expired. 支付请求已过期。 + + Pay only the required fee of %1 + 只支付必要费用 %1 + Estimated to begin confirmation within %n block(s). 预计 %n 个数据块后被确认。 @@ -2680,6 +2772,10 @@ Copy transaction ID 复制交易编号 + + Copy raw transaction + 复制原始交易 + Edit label 编辑标签 @@ -2830,10 +2926,34 @@ 接受命令行和 JSON-RPC 命令 + + If <category> is not supplied or if <category> = 1, output all debugging information. + 如果<category>未提供或<category> = 1,输出所有调试信息。 + + + Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s) + 最大单次转账费用(%s),设置太低可能导致大宗交易失败(默认:%s) + + + Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly. + 警请检查电脑的日期时间设置是否正确!时间错误可能会导致比特币客户端运行异常。 + + + Prune configured below the minimum of %d MiB. Please use a higher number. + 修剪值被设置为低于最小值%d MiB,请使用更大的数值。 + + + Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again. + 无法在开启修剪的状态下重扫描,请使用 -reindex重新下载完整的区块链。 + Error: A fatal internal error occurred, see debug.log for details 错误:发生了致命的内部错误,详情见 debug.log 文件 + + Fee (in %s/kB) to add to transactions you send (default: %s) + 为付款交易添加交易费 (%s/kB) (默认: %s) + Pruning blockstore... 正在修剪区块存储... @@ -2844,6 +2964,10 @@ + + Unable to start HTTP server. See debug log for details. + 无法启动HTTP服务,查看日志获取更多信息 + Accept connections from outside (default: 1 if no -proxy or -connect) 接受来自外部的连接 (缺省: 如果不带 -proxy or -connect 参数设置为1) @@ -2868,6 +2992,10 @@ Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) 设置脚本验证的程序 (%u 到 %d, 0 = 自动, <0 = 保留自由的核心, 默认值: %d) + + The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct + 区块数据库包含未来的交易,这可能是由本机错误的日期时间引起。若确认本机日期时间正确,请重新建立区块数据库。 + This is a pre-release test build - use at your own risk - do not use for mining or merchant applications 这是测试用的预发布版本 - 请谨慎使用 - 不要用来挖矿,或者在正式商用环境下使用 @@ -2876,6 +3004,10 @@ Unable to bind to %s on this computer. Bitcoin Core is probably already running. 无法 %s的绑定到电脑上,比特币核心钱包可能已经在运行。 + + Use UPnP to map the listening port (default: 1 when listening and no -proxy) + 使用UPnP暴露本机监听端口(默认:1 当正在监听且不使用代理) + WARNING: abnormally high number of blocks generated, %d blocks received in the last %d hours (%d expected) 警告:数据块生成数量异常,最近 %d 小时收到了 %d 个数据块(预期为 %d 个) @@ -2901,8 +3033,8 @@ 节点白名单,网络掩码或IP址。可多次指定。 - (default: 1) - (默认值: 1) + -maxmempool must be at least %d MB + -maxmempool 最小为%d MB <category> can be: @@ -2936,6 +3068,22 @@ Do you want to rebuild the block database now? 你想现在就重建块数据库吗? + + Enable publish hash block in <address> + 允许在<address>广播哈希区块 + + + Enable publish hash transaction in <address> + 允许在<address>广播哈希交易 + + + Enable publish raw block in <address> + 允许在<address>广播原始区块 + + + Enable publish raw transaction in <address> + 允许在<address>广播原始交易 + Error initializing block database 初始化数据块数据库出错 @@ -2972,6 +3120,10 @@ Invalid -onion address: '%s' 无效的 -onion 地址:“%s” + + Keep the transaction memory pool below <n> megabytes (default: %u) + 保持交易内存池大小低于<n>MB(默认:%u) + Not enough file descriptors available. 没有足够的文件描述符可用。 @@ -3000,6 +3152,18 @@ Specify wallet file (within data directory) 指定钱包文件(数据目录内) + + Unsupported argument -benchmark ignored, use -debug=bench. + 忽略不支持的选项 -benchmark,使用 -debug=bench + + + Unsupported argument -debugnet ignored, use -debug=net. + 忽略不支持的选项 -debugnet,使用 -debug=net。 + + + Unsupported argument -tor found, use -onion. + 忽略不支持的选项 -tor,使用 -oinon + Use UPnP to map the listening port (default: %u) 使用UPnp映射监听端口 (默认: %u) @@ -3120,10 +3284,6 @@ Cannot resolve -whitebind address: '%s' 无法解析 -whitebind 地址: '%s' - - Choose data directory on startup (default: 0) - 在启动时选择数据目录(默认:0) - Connect through SOCKS5 proxy 通过 SOCKS5 代理连接 @@ -3168,6 +3328,10 @@ Invalid netmask specified in -whitelist: '%s' -whitelist: '%s' 指定的网络掩码无效 + + Keep at most <n> unconnectable transactions in memory (default: %u) + 内存中最多保留 <n> 笔孤立的交易 (默认: %u) + Need to specify a port with -whitebind: '%s' -whitebind: '%s' 需要指定一个端口 @@ -3188,6 +3352,10 @@ Receive and display P2P network alerts (default: %u) 收到并且显示P2P网络的告警(默认:%u) + + Rescan the block chain for missing wallet transactions on startup + 重新扫描区块链以查找遗漏的钱包交易 + Send trace/debug info to console instead of debug.log file 跟踪/调试信息输出到控制台,不输出到 debug.log 文件 @@ -3196,22 +3364,10 @@ Send transactions as zero-fee transactions if possible (default: %u) 发送时尽可能 不支付交易费用 (默认: %u) - - Set SSL root certificates for payment request (default: -system-) - 设置SSL根证书的付款请求(默认:-系统-) - - - Set language, for example "de_DE" (default: system locale) - 设置语言, 例如“zh-TW”(默认为系统语言) - Show all debugging options (usage: --help -help-debug) 显示所有调试选项 (用法: --帮助 -帮助调试) - - Show splash screen on startup (default: 1) - 启动时显示版权页 (缺省: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) 客户端启动时压缩debug.log文件(缺省:no-debug模式时为1) @@ -3220,11 +3376,6 @@ Signing transaction failed 签署交易失败 - - Start minimized - 启动时最小化 - - The transaction amount is too small to pay the fee 交易金额太小,不足以支付交易费 @@ -3249,14 +3400,14 @@ Transaction too large 交易太大 - - UI Options: - 界面选项: - Unable to bind to %s on this computer (bind returned error %s) 无法在此计算机上绑定 %s (绑定返回错误 %s) + + Upgrade wallet to latest format on startup + 程序启动时升级钱包到最新格式 + Username for JSON-RPC connections JSON-RPC 连接用户名 @@ -3269,6 +3420,10 @@ Warning 警告 + + Whether to operate in a blocks only mode (default: %u) + 是否用块方进行 (%u) + Zapping all transactions from wallet... Zapping all transactions from wallet... @@ -3327,6 +3482,10 @@ Output debugging information (default: %u, supplying <category> is optional) 输出调试信息 (默认: %u, 提供 <category> 是可选项) + + Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d) + 尝试保持上传带宽低于(MiB/24h),0=无限制(默认:%d) + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) 通过Tor隐藏服务连接节点时 使用不同的SOCKS5代理 (默认: %s) @@ -3335,6 +3494,10 @@ (default: %s) (默认: %s) + + Always query for peer addresses via DNS lookup (default: %u) + 始终通过 DNS 查询节点地址 (默认: %u) + Error loading wallet.dat wallet.dat 钱包文件加载出错 diff --git a/src/qt/locale/bitcoin_zh_HK.ts b/src/qt/locale/bitcoin_zh_HK.ts deleted file mode 100644 index 4b4c1c687..000000000 --- a/src/qt/locale/bitcoin_zh_HK.ts +++ /dev/null @@ -1,113 +0,0 @@ - - - AddressBookPage - - - AddressTableModel - - - AskPassphraseDialog - - - BanTableModel - - - BitcoinGUI - - - ClientModel - - - CoinControlDialog - - - EditAddressDialog - - - FreespaceChecker - - - HelpMessageDialog - - - Intro - - - OpenURIDialog - - - OptionsDialog - - - OverviewPage - - - PaymentServer - - - PeerTableModel - - - QObject - - - QRImageWidget - - - RPCConsole - - - ReceiveCoinsDialog - - - ReceiveRequestDialog - - - RecentRequestsTableModel - - - SendCoinsDialog - - - SendCoinsEntry - - - ShutdownWindow - - - SignVerifyMessageDialog - - - SplashScreen - - - TrafficGraphWidget - - - TransactionDesc - - - TransactionDescDialog - - - TransactionTableModel - - - TransactionView - - - UnitDisplayStatusBarControl - - - WalletFrame - - - WalletModel - - - WalletView - - - bitcoin-core - - \ No newline at end of file diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index b4dbf85a3..402609592 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -403,7 +403,7 @@ Request payments (generates QR codes and bitcoin: URIs) - 要求付款(產生 QR Code 和位元幣付款協議的 URI) + 要求付款(產生 QR Code 和位元幣付款協議的資源識別碼: URI) &About Bitcoin Core @@ -423,7 +423,7 @@ Open a bitcoin: URI or payment request - 開啓 bitcoin 協議的 URI 或付款要求 + 開啓 bitcoin 協議的資源識別碼(URI)或付款要求 &Command-line options @@ -882,6 +882,34 @@ command-line options 命令列選項 + + UI Options: + 使用介面選項: + + + Choose data directory on startup (default: %u) + 啓動時選擇資料目錄(預設值: %u) + + + Set language, for example "de_DE" (default: system locale) + 設定語言,比如說 de_DE (預設值: 系統語系) + + + Start minimized + 啓動時縮到最小 + + + Set SSL root certificates for payment request (default: -system-) + 設定付款請求時所使用的 SSL 根憑證(預設值: 系統憑證庫) + + + Show splash screen on startup (default: %u) + 顯示啓動畫面(預設值: %u) + + + Reset all settings changes made over the GUI + 重置所有在使用界面更改的設定 + Intro @@ -907,7 +935,7 @@ Use a custom data directory: - 使用自定的資料目錄: + 使用自訂的資料目錄: Bitcoin Core @@ -997,7 +1025,7 @@ Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. - 在交易頁籤的情境選單出現的第三方(比如說區塊探索網站)網址連結。網址中的 %s 會被取代為交易的雜湊值。可以用直線符號 | 來分隔多個連結。 + 在交易頁籤的情境選單出現的第三方網址連結(URL),比如說區塊探索網站。網址中的 %s 會被取代為交易的雜湊值。可以用直線符號 | 來分隔多個連結。 Third party transaction URLs @@ -1291,11 +1319,11 @@ Payment request fetch URL is invalid: %1 - 取得付款要求的 URL 無效: %1 + 取得付款要求的網址連結(URL)無效: %1 URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters. - 沒辦法解析 URI 位址!可能是因為位元幣位址無效,或是 URI 參數格式錯誤。 + 沒辦法解析資源識別碼(URI)!可能是因為位元幣位址無效,或是 URI 參數格式錯誤。 Payment request file handling @@ -1477,6 +1505,18 @@ Current number of blocks 目前區塊數 + + Memory Pool + 記憶體暫存池 + + + Current number of transactions + 目前交易數目 + + + Memory usage + 記憶體使用量 + Open the Bitcoin Core debug log file from the current data directory. This can take a few seconds for large log files. 從目前的資料目錄下開啓位元幣核心的除錯紀錄檔。當紀錄檔很大時,可能會花好幾秒的時間。 @@ -1923,7 +1963,7 @@ Custom change address - 自定找零位址 + 自訂找零位址 Transaction Fee: @@ -2101,6 +2141,10 @@ Pay only the required fee of %1 只付必要的手續費 %1 + + Estimated to begin confirmation within %n block(s). + 預計可在 %n 個區塊內開始確認。 + The recipient address is not valid. Please recheck. 收款位址無效。請再檢查看看。 @@ -2194,11 +2238,11 @@ This is an unauthenticated payment request. - 這是個沒驗證過的付款要求。 + 這是個沒有驗證過身份的付款要求。 This is an authenticated payment request. - 這是個已驗證的付款要求。 + 這是個已經驗證過身份的付款要求。 Enter a label for this address to add it to the list of used addresses @@ -2206,7 +2250,7 @@ A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network. - 附加在位元幣付款協議 URI 中的訊息,會和交易內容一起存起來,給你自己做參考。注意: 這個訊息不會送到位元幣網路上。 + 附加在位元幣付款協議的資源識別碼(URI)中的訊息,會和交易內容一起存起來,給你自己做參考。注意: 這個訊息不會送到位元幣網路上。 Pay To: @@ -2732,6 +2776,10 @@ Copy transaction ID 複製交易識別碼 + + Copy raw transaction + 複製交易原始資料 + Edit label 編輯標記 @@ -2992,10 +3040,6 @@ Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. 把來自指定網域或位址的節點放進白名單。這個選項可以設定多次。 - - (default: 1) - (預設值: 1) - -maxmempool must be at least %d MB 參數 -maxmempool 至少要給 %d 百萬位元組(MB) @@ -3094,7 +3138,7 @@ Only connect to nodes in network <net> (ipv4, ipv6 or onion) - 只有連接到網絡節點 <net> (IPv4,IPv6或onion) + 只和 <net> 網路上的節點連線(ipv4, ipv6, 或 onion) Prune cannot be configured with a negative value. @@ -3128,6 +3172,10 @@ Unsupported argument -tor found, use -onion. 找到不再支援的 -tor 參數,請改用 -onion 參數。 + + Use UPnP to map the listening port (default: %u) + 使用通用隨插即用 (UPnP) 協定來設定對應的服務連接埠(預設值: %u) + User Agent comment (%s) contains unsafe characters. 使用者代理註解(%s)中含有不安全的字元。 @@ -3230,7 +3278,7 @@ 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 - 在白名單中的節點不會因為偵測到阻斷服務攻擊而被停用。來自這些節點的交易也一定會被轉發,即使說交易本來就在記憶池裡了也一樣。適用於像是閘道伺服器。 + 在白名單中的節點不會因為偵測到阻斷服務攻擊(DoS)而被停用。來自這些節點的交易也一定會被轉發,即使說交易本來就在記憶池裡了也一樣。適用於像是閘道伺服器。 You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain @@ -3248,17 +3296,21 @@ Activating best chain... 啟用最佳鏈結... + + Always relay transactions received from whitelisted peers (default: %d) + 無條件轉發從白名點節點收到的交易(預設值: %d) + Attempt to recover private keys from a corrupt wallet.dat on startup 啟動時嘗試從壞掉的錢包檔 wallet.dat 復原密鑰 - Cannot resolve -whitebind address: '%s' - 沒辦法解析 -whitebind 指定的位址: '%s' + Automatically create Tor hidden service (default: %d) + 自動產生 Tor 隱藏服務(預設值: %d) - Choose data directory on startup (default: 0) - 啓動時選擇資料目錄(預設值: 0) + Cannot resolve -whitebind address: '%s' + 沒辦法解析 -whitebind 指定的位址: '%s' Connect through SOCKS5 proxy @@ -3348,22 +3400,10 @@ Send transactions as zero-fee transactions if possible (default: %u) 盡可能送出不用付手續費的交易(預設值: %u) - - Set SSL root certificates for payment request (default: -system-) - 設定付款請求時所使用的 SSL 根憑證 (預設值: 系統憑證庫) - - - Set language, for example "de_DE" (default: system locale) - 設定語言,比如說 de_DE (預設值: 系統語系) - Show all debugging options (usage: --help -help-debug) 顯示所有的除錯選項 (用法: --help --help-debug) - - Show splash screen on startup (default: 1) - 顯示啓動畫面(預設值: 1) - Shrink debug.log file on client startup (default: 1 when no -debug) 客戶端軟體啓動時把 debug.log 檔縮小(預設值: 當沒有 -debug 時為 1) @@ -3372,10 +3412,6 @@ Signing transaction failed 簽署交易失敗 - - Start minimized - 啓動時縮到最小 - The transaction amount is too small to pay the fee 交易金額太少而付不起手續費 @@ -3384,6 +3420,14 @@ This is experimental software. 這套軟體屬於實驗性質。 + + Tor control port password (default: empty) + Tor 控制埠密碼(預設值: 空白) + + + Tor control port to use if onion listening enabled (default: %s) + 開啟聽候 onion 連線時的 Tor 控制埠號碼(預設值: %s) + Transaction amount too small 交易金額太小 @@ -3400,10 +3444,6 @@ Transaction too large 交易位元量太大 - - UI Options: - 使用介面選項: - Unable to bind to %s on this computer (bind returned error %s) 無法和這台電腦上的 %s 繫結(回傳錯誤 %s) @@ -3424,6 +3464,10 @@ Warning 警告 + + Whether to operate in a blocks only mode (default: %u) + 是否要用只要區塊模式運作(預設值: %u) + Zapping all transactions from wallet... 正在砍掉錢包中的所有交易... @@ -3474,12 +3518,16 @@ Do not keep transactions in the mempool longer than <n> hours (default: %u) - 不要讓交易留在記憶體暫存池中超過 <n> 個小時(預設值: %u) + 不要讓交易留在記憶池中超過 <n> 個小時(預設值: %u) Error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. 讀取錢包檔 wallet.dat 時發生錯誤!所有的密鑰都正確讀取了,但是交易資料或位址簿資料可能會缺少或不正確。 + + Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s) + 當製造交易時,如果每千位元組(kB)的手續費比這個值(單位是 %s)低,就視為沒付手續費(預設值: %s) + How thorough the block verification of -checkblocks is (0-4, default: %u) 使用 -checkblocks 檢查區塊的仔細程度(0 到 4,預設值: %u) @@ -3496,6 +3544,10 @@ Output debugging information (default: %u, supplying <category> is optional) 輸出除錯資訊(預設值: %u, 不一定要指定 <category>) + + Support filtering of blocks and transaction with bloom filters (default: %u) + 支援用布倫過濾器來過濾區塊和交易(預設值: %u) + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. 網路版本字串的總長度(%i)超過最大長度(%i)了。請減少 uacomment 參數的數目或長度。 @@ -3512,6 +3564,10 @@ Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) 使用另外的 SOCK5 代理伺服器,來透過 Tor 隱藏服務跟其他節點聯絡(預設值: %s) + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + JSON-RPC 連線要用的使用者名稱和雜湊密碼。<userpw> 的格式是:<使用者名稱>:<調味值>$<雜湊值>。在 share/rpcuser 目錄下有一個示範的 python 程式。這個選項可以給很多次。 + (default: %s) (預設值: %s) diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index 8bd867c10..1c28593d4 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/macnotificationhandler.h b/src/qt/macnotificationhandler.h index bd66b96b2..d4749b3d5 100644 --- a/src/qt/macnotificationhandler.h +++ b/src/qt/macnotificationhandler.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 4541c7588..5f31f4937 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index 5a564248e..a45afde56 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/notificator.h b/src/qt/notificator.h index f2a15e9c3..f92b791d4 100644 --- a/src/qt/notificator.h +++ b/src/qt/notificator.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp index 1c843aecb..5a6616134 100644 --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/openuridialog.h b/src/qt/openuridialog.h index 28b8f56ca..e94593d5b 100644 --- a/src/qt/openuridialog.h +++ b/src/qt/openuridialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 79a740612..95a3fa8d2 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -34,8 +34,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : QDialog(parent), ui(new Ui::OptionsDialog), model(0), - mapper(0), - fProxyIpsValid(true) + mapper(0) { ui->setupUi(this); @@ -60,12 +59,11 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool))); connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool))); + connect(ui->connectSocks, SIGNAL(toggled(bool)), this, SLOT(updateProxyValidationState())); connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyIpTor, SLOT(setEnabled(bool))); connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyPortTor, SLOT(setEnabled(bool))); - - ui->proxyIp->installEventFilter(this); - ui->proxyIpTor->installEventFilter(this); + connect(ui->connectSocksTor, SIGNAL(toggled(bool)), this, SLOT(updateProxyValidationState())); /* Window elements init */ #ifdef Q_OS_MAC @@ -124,7 +122,12 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : mapper->setOrientation(Qt::Vertical); /* setup/change UI elements when proxy IPs are invalid/valid */ - connect(this, SIGNAL(proxyIpChecks(QValidatedLineEdit *, int)), this, SLOT(doProxyIpChecks(QValidatedLineEdit *, int))); + ui->proxyIp->setCheckValidator(new ProxyAddressValidator(parent)); + ui->proxyIpTor->setCheckValidator(new ProxyAddressValidator(parent)); + connect(ui->proxyIp, SIGNAL(validationDidChange(QValidatedLineEdit *)), this, SLOT(updateProxyValidationState())); + connect(ui->proxyIpTor, SIGNAL(validationDidChange(QValidatedLineEdit *)), this, SLOT(updateProxyValidationState())); + connect(ui->proxyPort, SIGNAL(textChanged(const QString&)), this, SLOT(updateProxyValidationState())); + connect(ui->proxyPortTor, SIGNAL(textChanged(const QString&)), this, SLOT(updateProxyValidationState())); } OptionsDialog::~OptionsDialog() @@ -205,18 +208,6 @@ void OptionsDialog::setMapper() mapper->addMapping(ui->thirdPartyTxUrls, OptionsModel::ThirdPartyTxUrls); } -void OptionsDialog::enableOkButton() -{ - /* prevent enabling of the OK button when data modified, if there is an invalid proxy address present */ - if(fProxyIpsValid) - setOkButtonState(true); -} - -void OptionsDialog::disableOkButton() -{ - setOkButtonState(false); -} - void OptionsDialog::setOkButtonState(bool fState) { ui->okButton->setEnabled(fState); @@ -274,24 +265,20 @@ void OptionsDialog::clearStatusLabel() ui->statusLabel->clear(); } -void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort) +void OptionsDialog::updateProxyValidationState() { - Q_UNUSED(nProxyPort); - - CService addrProxy; - - /* Check for a valid IPv4 / IPv6 address */ - if (!(fProxyIpsValid = LookupNumeric(pUiProxyIp->text().toStdString().c_str(), addrProxy))) + QValidatedLineEdit *pUiProxyIp = ui->proxyIp; + QValidatedLineEdit *otherProxyWidget = (pUiProxyIp == ui->proxyIpTor) ? ui->proxyIp : ui->proxyIpTor; + if (pUiProxyIp->isValid() && (!ui->proxyPort->isEnabled() || ui->proxyPort->text().toInt() > 0) && (!ui->proxyPortTor->isEnabled() || ui->proxyPortTor->text().toInt() > 0)) { - disableOkButton(); - pUiProxyIp->setValid(false); - ui->statusLabel->setStyleSheet("QLabel { color: red; }"); - ui->statusLabel->setText(tr("The supplied proxy address is invalid.")); + setOkButtonState(otherProxyWidget->isValid()); //only enable ok button if both proxys are valid + ui->statusLabel->clear(); } else { - enableOkButton(); - ui->statusLabel->clear(); + setOkButtonState(false); + ui->statusLabel->setStyleSheet("QLabel { color: red; }"); + ui->statusLabel->setText(tr("The supplied proxy address is invalid.")); } } @@ -317,18 +304,18 @@ void OptionsDialog::updateDefaultProxyNets() (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachTor->setChecked(true) : ui->proxyReachTor->setChecked(false); } -bool OptionsDialog::eventFilter(QObject *object, QEvent *event) +ProxyAddressValidator::ProxyAddressValidator(QObject *parent) : +QValidator(parent) { - if(event->type() == QEvent::FocusOut) - { - if(object == ui->proxyIp) - { - Q_EMIT proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt()); - } - else if(object == ui->proxyIpTor) - { - Q_EMIT proxyIpChecks(ui->proxyIpTor, ui->proxyPortTor->text().toInt()); - } - } - return QDialog::eventFilter(object, event); +} + +QValidator::State ProxyAddressValidator::validate(QString &input, int &pos) const +{ + Q_UNUSED(pos); + // Validate the proxy + proxyType addrProxy = proxyType(CService(input.toStdString(), 9050), true); + if (addrProxy.IsValid()) + return QValidator::Acceptable; + + return QValidator::Invalid; } diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index 348489c59..e944fb9ee 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -6,6 +6,7 @@ #define BITCOIN_QT_OPTIONSDIALOG_H #include +#include class OptionsModel; class QValidatedLineEdit; @@ -18,6 +19,18 @@ namespace Ui { class OptionsDialog; } +/** Proxy address widget validator, checks for a valid proxy address. + */ +class ProxyAddressValidator : public QValidator +{ + Q_OBJECT + +public: + explicit ProxyAddressValidator(QObject *parent); + + State validate(QString &input, int &pos) const; +}; + /** Preferences dialog. */ class OptionsDialog : public QDialog { @@ -30,14 +43,7 @@ public: void setModel(OptionsModel *model); void setMapper(); -protected: - bool eventFilter(QObject *object, QEvent *event); - private Q_SLOTS: - /* enable OK button */ - void enableOkButton(); - /* disable OK button */ - void disableOkButton(); /* set OK button state (enabled / disabled) */ void setOkButtonState(bool fState); void on_resetButton_clicked(); @@ -46,7 +52,7 @@ private Q_SLOTS: void showRestartWarning(bool fPersistent = false); void clearStatusLabel(); - void doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort); + void updateProxyValidationState(); /* query the networks, for which the default proxy is used */ void updateDefaultProxyNets(); @@ -57,7 +63,6 @@ private: Ui::OptionsDialog *ui; OptionsModel *model; QDataWidgetMapper *mapper; - bool fProxyIpsValid; }; #endif // BITCOIN_QT_OPTIONSDIALOG_H diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 3e5c6c72b..d091bb9e6 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index d5bddb1a9..841711dd2 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index a56c80ac6..d577345e4 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 4139eb35d..911443c76 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 78a783dea..20e1f79ff 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -145,7 +145,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c int error = X509_STORE_CTX_get_error(store_ctx); // For testing payment requests, we allow self signed root certs! // This option is just shown in the UI options, if -help-debug is enabled. - if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && GetBoolArg("-allowselfsignedrootcertificates", false))) { + if (!(error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && GetBoolArg("-allowselfsignedrootcertificates", DEFAULT_SELFSIGNED_ROOTCERTS))) { throw SSLVerifyError(X509_verify_cert_error_string(error)); } else { qDebug() << "PaymentRequestPlus::getMerchant: Allowing self signed root certificate, because -allowselfsignedrootcertificates is true."; @@ -201,7 +201,7 @@ QList > PaymentRequestPlus::getPayTo() const const unsigned char* scriptStr = (const unsigned char*)details.outputs(i).script().data(); CScript s(scriptStr, scriptStr+details.outputs(i).script().size()); - result.append(make_pair(s, details.outputs(i).amount())); + result.append(std::make_pair(s, details.outputs(i).amount())); } return result; } diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h index 99a7186b8..a73fe5f29 100644 --- a/src/qt/paymentrequestplus.h +++ b/src/qt/paymentrequestplus.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin developers +// Copyright (c) 2011-2015 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,6 +15,8 @@ #include #include +static const bool DEFAULT_SELFSIGNED_ROOTCERTS = false; + // // Wraps dumb protocol buffer paymentRequest // with extra methods diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 31a6d65a8..c80aebb00 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index fa120a435..2d27ed078 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 770a86054..84ad0052f 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -85,7 +85,7 @@ public: } if (sortColumn >= 0) - // sort cacheNodeStats (use stable sort to prevent rows jumping around unneceesarily) + // sort cacheNodeStats (use stable sort to prevent rows jumping around unnecessarily) qStableSort(cachedNodeStats.begin(), cachedNodeStats.end(), NodeLessThan(sortColumn, sortOrder)); // build index map @@ -147,7 +147,7 @@ int PeerTableModel::rowCount(const QModelIndex &parent) const int PeerTableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return columns.length();; + return columns.length(); } QVariant PeerTableModel::data(const QModelIndex &index, int role) const diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h index 5f149ea87..a2aaaa5d2 100644 --- a/src/qt/peertablemodel.h +++ b/src/qt/peertablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp index 346369392..baa2eb67f 100644 --- a/src/qt/qvalidatedlineedit.cpp +++ b/src/qt/qvalidatedlineedit.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -99,9 +99,25 @@ void QValidatedLineEdit::checkValidity() } else setValid(false); + + Q_EMIT validationDidChange(this); } void QValidatedLineEdit::setCheckValidator(const QValidator *v) { checkValidator = v; } + +bool QValidatedLineEdit::isValid() +{ + // use checkValidator in case the QValidatedLineEdit is disabled + if (checkValidator) + { + QString address = text(); + int pos = 0; + if (checkValidator->validate(address, pos) == QValidator::Acceptable) + return true; + } + + return valid; +} diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h index 8665acda5..66734cc9d 100644 --- a/src/qt/qvalidatedlineedit.h +++ b/src/qt/qvalidatedlineedit.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -18,6 +18,7 @@ public: explicit QValidatedLineEdit(QWidget *parent); void clear(); void setCheckValidator(const QValidator *v); + bool isValid(); protected: void focusInEvent(QFocusEvent *evt); @@ -31,6 +32,9 @@ public Q_SLOTS: void setValid(bool valid); void setEnabled(bool enabled); +Q_SIGNALS: + void validationDidChange(QValidatedLineEdit *validatedLineEdit); + private Q_SLOTS: void markValid(); void checkValidity(); diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp index 800436661..146f3dd57 100644 --- a/src/qt/qvaluecombobox.cpp +++ b/src/qt/qvaluecombobox.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h index 5b20e6a5a..f26630231 100644 --- a/src/qt/qvaluecombobox.h +++ b/src/qt/qvaluecombobox.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 7fb68cc32..0b355837a 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -82,6 +82,7 @@ void ReceiveCoinsDialog::setModel(WalletModel *model) tableView->setSelectionMode(QAbstractItemView::ContiguousSelection); tableView->setColumnWidth(RecentRequestsTableModel::Date, DATE_COLUMN_WIDTH); tableView->setColumnWidth(RecentRequestsTableModel::Label, LABEL_COLUMN_WIDTH); + tableView->setColumnWidth(RecentRequestsTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH); connect(tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index eaaf129a9..226fd65cf 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -36,7 +36,7 @@ public: enum ColumnWidths { DATE_COLUMN_WIDTH = 130, LABEL_COLUMN_WIDTH = 120, - AMOUNT_MINIMUM_COLUMN_WIDTH = 160, + AMOUNT_MINIMUM_COLUMN_WIDTH = 180, MINIMUM_COLUMN_WIDTH = 130 }; diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 0c4a20cf9..a1e9156ee 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -144,7 +144,7 @@ void ReceiveRequestDialog::update() html += "" + GUIUtil::HtmlEscape(uri) + "
"; html += ""+tr("Address")+": " + GUIUtil::HtmlEscape(info.address) + "
"; if(info.amount) - html += ""+tr("Amount")+": " + BitcoinUnits::formatWithUnit(model->getDisplayUnit(), info.amount) + "
"; + html += ""+tr("Amount")+": " + BitcoinUnits::formatHtmlWithUnit(model->getDisplayUnit(), info.amount) + "
"; if(!info.label.isEmpty()) html += ""+tr("Label")+": " + GUIUtil::HtmlEscape(info.label) + "
"; if(!info.message.isEmpty()) diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 69f84ebbd..4cab4caff 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 5692a7aae..2335d6b28 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -83,7 +83,7 @@ QVariant RecentRequestsTableModel::data(const QModelIndex &index, int role) cons } case Amount: if (rec->recipient.amount == 0 && role == Qt::DisplayRole) - return tr("(no amount)"); + return tr("(no amount requested)"); else if (role == Qt::EditRole) return BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), rec->recipient.amount, false, BitcoinUnits::separatorNever); else @@ -125,12 +125,7 @@ void RecentRequestsTableModel::updateAmountColumnTitle() /** Gets title for amount column including current display unit if optionsModel reference available. */ QString RecentRequestsTableModel::getAmountTitle() { - QString amountTitle = tr("Amount"); - if (this->walletModel->getOptionsModel() != NULL) - { - amountTitle += " ("+BitcoinUnits::name(this->walletModel->getOptionsModel()->getDisplayUnit()) + ")"; - } - return amountTitle; + return (this->walletModel->getOptionsModel() != NULL) ? tr("Requested") + " ("+BitcoinUnits::name(this->walletModel->getOptionsModel()->getDisplayUnit()) + ")" : ""; } QModelIndex RecentRequestsTableModel::index(int row, int column, const QModelIndex &parent) const diff --git a/src/qt/recentrequeststablemodel.h b/src/qt/recentrequeststablemodel.h index 64faa72d4..f3cf03f4e 100644 --- a/src/qt/recentrequeststablemodel.h +++ b/src/qt/recentrequeststablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/res/icons/chevron.png b/src/qt/res/icons/chevron.png new file mode 100644 index 000000000..ac985052c Binary files /dev/null and b/src/qt/res/icons/chevron.png differ diff --git a/src/qt/res/icons/fontbigger.png b/src/qt/res/icons/fontbigger.png new file mode 100644 index 000000000..5ca5c563b Binary files /dev/null and b/src/qt/res/icons/fontbigger.png differ diff --git a/src/qt/res/icons/fontsmaller.png b/src/qt/res/icons/fontsmaller.png new file mode 100644 index 000000000..1a6bb3a61 Binary files /dev/null and b/src/qt/res/icons/fontsmaller.png differ diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index b60aa00f1..c18c40525 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -16,8 +16,8 @@ #include "bantablemodel.h" #include "chainparams.h" -#include "rpcserver.h" -#include "rpcclient.h" +#include "rpc/server.h" +#include "rpc/client.h" #include "util.h" #include @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -45,9 +46,9 @@ // TODO: receive errors and debug messages through ClientModel const int CONSOLE_HISTORY = 50; -const QSize ICON_SIZE(24, 24); - const int INITIAL_TRAFFIC_GRAPH_MINS = 30; +const QSize FONT_RANGE(4, 40); +const char fontSizeSettingsKey[] = "consoleFontSize"; const struct { const char *url; @@ -249,7 +250,8 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : cachedNodeid(-1), platformStyle(platformStyle), peersTableContextMenu(0), - banTableContextMenu(0) + banTableContextMenu(0), + consoleFontSize(0) { ui->setupUi(this); GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this); @@ -260,16 +262,26 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : ui->openDebugLogfileButton->setIcon(platformStyle->SingleColorIcon(":/icons/export")); } ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove")); + ui->fontBiggerButton->setIcon(platformStyle->SingleColorIcon(":/icons/fontbigger")); + ui->fontSmallerButton->setIcon(platformStyle->SingleColorIcon(":/icons/fontsmaller")); // Install event filter for up and down arrow ui->lineEdit->installEventFilter(this); ui->messagesWidget->installEventFilter(this); connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); + connect(ui->fontBiggerButton, SIGNAL(clicked()), this, SLOT(fontBigger())); + connect(ui->fontSmallerButton, SIGNAL(clicked()), this, SLOT(fontSmaller())); connect(ui->btnClearTrafficGraph, SIGNAL(clicked()), ui->trafficGraph, SLOT(clear())); // set library version labels + +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION)); +#else + ui->openSSLVersion->setText(OpenSSL_version(OPENSSL_VERSION)); +#endif + #ifdef ENABLE_WALLET ui->berkeleyDBVersion->setText(DbEnv::version(0, 0, 0)); #else @@ -278,7 +290,9 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : #endif // Register RPC timer interface rpcTimerInterface = new QtRPCTimerInterface(); - RPCRegisterTimerInterface(rpcTimerInterface); + // avoid accidentally overwriting an existing, non QTThread + // based timer interface + RPCSetTimerInterfaceIfUnset(rpcTimerInterface); startExecutor(); setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS); @@ -286,6 +300,8 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : ui->detailWidget->hide(); ui->peerHeading->setText(tr("Select a peer to view detailed information.")); + QSettings settings; + consoleFontSize = settings.value(fontSizeSettingsKey, QFontInfo(QFont()).pointSize()).toInt(); clear(); } @@ -293,7 +309,7 @@ RPCConsole::~RPCConsole() { GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this); Q_EMIT stopExecutor(); - RPCUnregisterTimerInterface(rpcTimerInterface); + RPCUnsetTimerInterface(rpcTimerInterface); delete rpcTimerInterface; delete ui; } @@ -343,8 +359,8 @@ void RPCConsole::setClientModel(ClientModel *model) setNumConnections(model->getNumConnections()); connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); - setNumBlocks(model->getNumBlocks(), model->getLastBlockDate()); - connect(model, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime))); + setNumBlocks(model->getNumBlocks(), model->getLastBlockDate(), model->getVerificationProgress(NULL)); + connect(model, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(setNumBlocks(int,QDateTime,double))); updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent()); connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64))); @@ -451,6 +467,41 @@ static QString categoryClass(int category) } } +void RPCConsole::fontBigger() +{ + setFontSize(consoleFontSize+1); +} + +void RPCConsole::fontSmaller() +{ + setFontSize(consoleFontSize-1); +} + +void RPCConsole::setFontSize(int newSize) +{ + QSettings settings; + + //don't allow a insane font size + if (newSize < FONT_RANGE.width() || newSize > FONT_RANGE.height()) + return; + + // temp. store the console content + QString str = ui->messagesWidget->toHtml(); + + // replace font tags size in current content + str.replace(QString("font-size:%1pt").arg(consoleFontSize), QString("font-size:%1pt").arg(newSize)); + + // store the new font size + consoleFontSize = newSize; + settings.setValue(fontSizeSettingsKey, consoleFontSize); + + // clear console (reset icon sizes, default stylesheet) and re-add the content + float oldPosFactor = 1.0 / ui->messagesWidget->verticalScrollBar()->maximum() * ui->messagesWidget->verticalScrollBar()->value(); + clear(); + ui->messagesWidget->setHtml(str); + ui->messagesWidget->verticalScrollBar()->setValue(oldPosFactor * ui->messagesWidget->verticalScrollBar()->maximum()); +} + void RPCConsole::clear() { ui->messagesWidget->clear(); @@ -466,22 +517,20 @@ void RPCConsole::clear() ui->messagesWidget->document()->addResource( QTextDocument::ImageResource, QUrl(ICON_MAPPING[i].url), - platformStyle->SingleColorImage(ICON_MAPPING[i].source).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + platformStyle->SingleColorImage(ICON_MAPPING[i].source).scaled(QSize(consoleFontSize*2, consoleFontSize*2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); } // Set default style sheet QFontInfo fixedFontInfo(GUIUtil::fixedPitchFont()); - // Try to make fixed font adequately large on different OS - QString ptSize = QString("%1pt").arg(QFontInfo(QFont()).pointSize() * 8.5 / 9); ui->messagesWidget->document()->setDefaultStyleSheet( QString( "table { }" - "td.time { color: #808080; padding-top: 3px; } " + "td.time { color: #808080; font-size: %2; padding-top: 3px; } " "td.message { font-family: %1; font-size: %2; white-space:pre-wrap; } " "td.cmd-request { color: #006060; } " "td.cmd-error { color: red; } " "b { color: #006060; } " - ).arg(fixedFontInfo.family(), ptSize) + ).arg(fixedFontInfo.family(), QString("%1pt").arg(consoleFontSize)) ); message(CMD_REPLY, (tr("Welcome to the %1 RPC console.").arg(tr(PACKAGE_NAME)) + "
" + @@ -525,7 +574,7 @@ void RPCConsole::setNumConnections(int count) ui->numberOfConnections->setText(connections); } -void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate) +void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress) { ui->numberOfBlocks->setText(QString::number(count)); ui->lastBlockTime->setText(blockDate.toString()); diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 4b242affc..648e32638 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -78,12 +78,15 @@ private Q_SLOTS: public Q_SLOTS: void clear(); + void fontBigger(); + void fontSmaller(); + void setFontSize(int newSize); /** Append the message to the message widget */ 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 and last block date shown in the UI */ - void setNumBlocks(int count, const QDateTime& blockDate); + void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress); /** Set size (number of transactions and memory usage) of the mempool in the UI */ void setMempoolSize(long numberOfTxs, size_t dynUsage); /** Go forward or back in history */ @@ -118,7 +121,7 @@ private: enum ColumnWidths { ADDRESS_COLUMN_WIDTH = 200, - SUBVERSION_COLUMN_WIDTH = 100, + SUBVERSION_COLUMN_WIDTH = 150, PING_COLUMN_WIDTH = 80, BANSUBNET_COLUMN_WIDTH = 200, BANTIME_COLUMN_WIDTH = 250 @@ -134,6 +137,7 @@ private: RPCTimerInterface *rpcTimerInterface; QMenu *peersTableContextMenu; QMenu *banTableContextMenu; + int consoleFontSize; }; #endif // BITCOIN_QT_RPCCONSOLE_H diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 4b030fdaa..5fc7b57a4 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -124,7 +124,7 @@ void SendCoinsDialog::setClientModel(ClientModel *clientModel) this->clientModel = clientModel; if (clientModel) { - connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(updateSmartFeeLabel())); + connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime,double)), this, SLOT(updateSmartFeeLabel())); } } @@ -373,8 +373,6 @@ SendCoinsEntry *SendCoinsDialog::addEntry() connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels())); connect(entry, SIGNAL(subtractFeeFromAmountChanged()), this, SLOT(coinControlUpdateLabels())); - updateTabsAndLabels(); - // Focus the field, so that entry can start immediately entry->clear(); entry->setFocus(); @@ -383,6 +381,8 @@ SendCoinsEntry *SendCoinsDialog::addEntry() QScrollBar* bar = ui->scrollArea->verticalScrollBar(); if(bar) bar->setSliderPosition(bar->maximum()); + + updateTabsAndLabels(); return entry; } @@ -585,7 +585,7 @@ void SendCoinsDialog::updateFeeSectionControls() ui->checkBoxMinimumFee ->setEnabled(ui->radioCustomFee->isChecked()); ui->labelMinFeeWarning ->setEnabled(ui->radioCustomFee->isChecked()); ui->radioCustomPerKilobyte ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked()); - ui->radioCustomAtLeast ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked()); + ui->radioCustomAtLeast ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked() && CoinControlDialog::coinControl->HasSelected()); ui->customFee ->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked()); } @@ -600,7 +600,10 @@ void SendCoinsDialog::updateGlobalFeeVariables() { nTxConfirmTarget = defaultConfirmTarget; payTxFee = CFeeRate(ui->customFee->value()); - fPayAtLeastCustomFee = ui->radioCustomAtLeast->isChecked(); + + // if user has selected to set a minimum absolute fee, pass the value to coincontrol + // set nMinimumTotalFee to 0 in case of user has selected that the fee is per KB + CoinControlDialog::coinControl->nMinimumTotalFee = ui->radioCustomAtLeast->isChecked() ? ui->customFee->value() : 0; } fSendFreeTransactions = ui->checkBoxFreeTx->isChecked(); @@ -633,18 +636,21 @@ void SendCoinsDialog::updateSmartFeeLabel() return; int nBlocksToConfirm = defaultConfirmTarget - ui->sliderSmartFee->value(); - CFeeRate feeRate = mempool.estimateFee(nBlocksToConfirm); + int estimateFoundAtBlocks = nBlocksToConfirm; + CFeeRate feeRate = mempool.estimateSmartFee(nBlocksToConfirm, &estimateFoundAtBlocks); if (feeRate <= CFeeRate(0)) // not enough data => minfee { - ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), CWallet::GetRequiredFee(1000)) + "/kB"); + ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), + std::max(CWallet::fallbackFee.GetFeePerK(), CWallet::GetRequiredFee(1000))) + "/kB"); ui->labelSmartFee2->show(); // (Smart fee not initialized yet. This usually takes a few blocks...) ui->labelFeeEstimation->setText(""); } else { - ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), feeRate.GetFeePerK()) + "/kB"); + ui->labelSmartFee->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), + std::max(feeRate.GetFeePerK(), CWallet::GetRequiredFee(1000))) + "/kB"); ui->labelSmartFee2->hide(); - ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %n block(s).", "", nBlocksToConfirm)); + ui->labelFeeEstimation->setText(tr("Estimated to begin confirmation within %n block(s).", "", estimateFoundAtBlocks)); } updateFeeMinimizedLabel(); @@ -706,8 +712,7 @@ void SendCoinsDialog::coinControlFeatureChanged(bool checked) if (!checked && model) // coin control features disabled CoinControlDialog::coinControl->SetNull(); - if (checked) - coinControlUpdateLabels(); + coinControlUpdateLabels(); } // Coin Control: button inputs -> show actual coin control dialog @@ -781,16 +786,31 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text) // Coin Control: update labels void SendCoinsDialog::coinControlUpdateLabels() { - if (!model || !model->getOptionsModel() || !model->getOptionsModel()->getCoinControlFeatures()) + if (!model || !model->getOptionsModel()) return; + if (model->getOptionsModel()->getCoinControlFeatures()) + { + // enable minimum absolute fee UI controls + ui->radioCustomAtLeast->setVisible(true); + + // only enable the feature if inputs are selected + ui->radioCustomAtLeast->setEnabled(CoinControlDialog::coinControl->HasSelected()); + } + else + { + // in case coin control is disabled (=default), hide minimum absolute fee UI controls + ui->radioCustomAtLeast->setVisible(false); + return; + } + // set pay amounts CoinControlDialog::payAmounts.clear(); CoinControlDialog::fSubtractFeeFromAmount = false; for(int i = 0; i < ui->entries->count(); ++i) { SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); - if(entry) + if(entry && !entry->isHidden()) { SendCoinsRecipient rcp = entry->getValue(); CoinControlDialog::payAmounts.append(rcp.amount); diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 391905ffc..ec171734f 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 4f4b5b70d..d063f2c89 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index 107ab7015..a8be670c2 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 96f50a265..8e2e8a509 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/signverifymessagedialog.h b/src/qt/signverifymessagedialog.h index d651d5049..d2e04cd4f 100644 --- a/src/qt/signverifymessagedialog.h +++ b/src/qt/signverifymessagedialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 21dab957f..b46321fa8 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/splashscreen.h b/src/qt/splashscreen.h index 29d16d4ea..821f39db1 100644 --- a/src/qt/splashscreen.h +++ b/src/qt/splashscreen.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h index c548ffe42..74a2db8ea 100644 --- a/src/qt/test/paymentrequestdata.h +++ b/src/qt/test/paymentrequestdata.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp index fa5696325..84ccfea73 100644 --- a/src/qt/test/paymentservertests.cpp +++ b/src/qt/test/paymentservertests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/paymentservertests.h b/src/qt/test/paymentservertests.h index 71d61fcbe..9ffcbb02a 100644 --- a/src/qt/test/paymentservertests.h +++ b/src/qt/test/paymentservertests.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index f91de2008..db193420b 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/test/uritests.h b/src/qt/test/uritests.h index 434169dcd..499484279 100644 --- a/src/qt/test/uritests.h +++ b/src/qt/test/uritests.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp index 9b67445bc..601d554c0 100644 --- a/src/qt/trafficgraphwidget.cpp +++ b/src/qt/trafficgraphwidget.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/trafficgraphwidget.h b/src/qt/trafficgraphwidget.h index 6336a8d14..00660574a 100644 --- a/src/qt/trafficgraphwidget.h +++ b/src/qt/trafficgraphwidget.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 801c6c62d..5cb4cd5af 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -35,9 +35,11 @@ QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) { int nDepth = wtx.GetDepthInMainChain(); if (nDepth < 0) - return tr("conflicted"); + return tr("conflicted with a transaction with %1 confirmations").arg(-nDepth); else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) return tr("%1/offline").arg(nDepth); + else if (nDepth == 0) + return tr("0/unconfirmed, %1").arg((wtx.InMempool() ? tr("in memory pool") : tr("not in memory pool"))); else if (nDepth < 6) return tr("%1/unconfirmed").arg(nDepth); else diff --git a/src/qt/transactiondesc.h b/src/qt/transactiondesc.h index 5467348ee..01b90b130 100644 --- a/src/qt/transactiondesc.h +++ b/src/qt/transactiondesc.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp index fadaa98f4..f7b6995b2 100644 --- a/src/qt/transactiondescdialog.cpp +++ b/src/qt/transactiondescdialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/transactiondescdialog.h b/src/qt/transactiondescdialog.h index 54374e359..f1371b385 100644 --- a/src/qt/transactiondescdialog.h +++ b/src/qt/transactiondescdialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp index 7981eb7c9..9dcb72f55 100644 --- a/src/qt/transactionfilterproxy.cpp +++ b/src/qt/transactionfilterproxy.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h index acea9a1e3..7db02cd61 100644 --- a/src/qt/transactionfilterproxy.h +++ b/src/qt/transactionfilterproxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index d8623daf5..5b16b108e 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index a5bc37571..49753ee31 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index e8ada9f76..1647b2a6f 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 601f893d4..fe59a15f6 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 11e6d750a..4a9a19821 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -267,7 +267,7 @@ void TransactionView::chooseDate(int idx) break; case LastMonth: transactionProxyModel->setDateRange( - QDateTime(QDate(current.year(), current.month()-1, 1)), + QDateTime(QDate(current.year(), current.month(), 1).addMonths(-1)), QDateTime(QDate(current.year(), current.month(), 1))); break; case ThisYear: diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index dde700c4d..cf2b8fbcd 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 5fafa5759..947bcdb15 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,6 +12,9 @@ #include "bitcoingui.h" #include "clientmodel.h" +#include "guiconstants.h" +#include "intro.h" +#include "paymentrequestplus.h" #include "guiutil.h" #include "clientversion.h" @@ -74,7 +77,22 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) : cursor.insertText(header); cursor.insertBlock(); - QString coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT)); + std::string strUsage = HelpMessage(HMM_BITCOIN_QT); + const bool showDebug = GetBoolArg("-help-debug", false); + strUsage += HelpMessageGroup(tr("UI Options:").toStdString()); + if (showDebug) { + strUsage += HelpMessageOpt("-allowselfsignedrootcertificates", strprintf("Allow self signed root certificates (default: %u)", DEFAULT_SELFSIGNED_ROOTCERTS)); + } + strUsage += HelpMessageOpt("-choosedatadir", strprintf(tr("Choose data directory on startup (default: %u)").toStdString(), DEFAULT_CHOOSE_DATADIR)); + strUsage += HelpMessageOpt("-lang=", tr("Set language, for example \"de_DE\" (default: system locale)").toStdString()); + strUsage += HelpMessageOpt("-min", tr("Start minimized").toStdString()); + strUsage += HelpMessageOpt("-rootcertificates=", tr("Set SSL root certificates for payment request (default: -system-)").toStdString()); + strUsage += HelpMessageOpt("-splash", strprintf(tr("Show splash screen on startup (default: %u)").toStdString(), DEFAULT_SPLASHSCREEN)); + strUsage += HelpMessageOpt("-resetguisettings", tr("Reset all settings changed in the GUI").toStdString()); + if (showDebug) { + strUsage += HelpMessageOpt("-uiplatform", strprintf("Select platform to customize UI for (one of windows, macosx, other; default: %s)", BitcoinGUI::DEFAULT_UIPLATFORM)); + } + QString coreOptions = QString::fromStdString(strUsage); text = version + "\n" + header + "\n" + coreOptions; QTextTableFormat tf; diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index 47282ae2d..843bd7f67 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index ba8c28464..e4ca5e183 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index 9a56e97f9..9a5bc273c 100644 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 690ea0811..cf38c64eb 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index a5e877d81..7a47eda86 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 6a9b2d5bd..8c970ee8a 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h index 7765fea4a..64922efad 100644 --- a/src/qt/walletmodeltransaction.h +++ b/src/qt/walletmodeltransaction.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 77efdb5cd..6ce98ef16 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/qt/walletview.h b/src/qt/walletview.h index 2a6a6a2df..dbb289f42 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/random.cpp b/src/random.cpp index 0ba0de908..6155c0d8c 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rest.cpp b/src/rest.cpp index 5d69542a9..ebdccc940 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,7 +9,7 @@ #include "primitives/transaction.h" #include "main.h" #include "httpserver.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "streams.h" #include "sync.h" #include "txmempool.h" @@ -494,7 +494,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS) return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); - // check spentness and form a bitmap (as well as a JSON capable human-readble string representation) + // check spentness and form a bitmap (as well as a JSON capable human-readable string representation) vector bitmap; vector outs; std::string bitmapStringRepresentation; diff --git a/src/reverselock.h b/src/reverselock.h index 567636e16..fac1ccb79 100644 --- a/src/reverselock.h +++ b/src/reverselock.h @@ -15,10 +15,12 @@ public: explicit reverse_lock(Lock& lock) : lock(lock) { lock.unlock(); + lock.swap(templock); } ~reverse_lock() { - lock.lock(); + templock.lock(); + templock.swap(lock); } private: @@ -26,6 +28,7 @@ private: reverse_lock& operator=(reverse_lock const&); Lock& lock; + Lock templock; }; #endif // BITCOIN_REVERSELOCK_H diff --git a/src/rpcblockchain.cpp b/src/rpc/blockchain.cpp similarity index 96% rename from src/rpcblockchain.cpp rename to src/rpc/blockchain.cpp index 012370ed1..de6bda4ea 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -10,8 +10,9 @@ #include "coins.h" #include "consensus/validation.h" #include "main.h" +#include "policy/policy.h" #include "primitives/transaction.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "streams.h" #include "sync.h" #include "txmempool.h" @@ -189,13 +190,14 @@ UniValue mempoolToJSON(bool fVerbose = false) UniValue info(UniValue::VOBJ); info.push_back(Pair("size", (int)e.GetTxSize())); info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); + info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee()))); info.push_back(Pair("time", e.GetTime())); info.push_back(Pair("height", (int)e.GetHeight())); info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); - info.push_back(Pair("descendantfees", e.GetFeesWithDescendants())); + info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants())); const CTransaction& tx = e.GetTx(); set setDepends; BOOST_FOREACH(const CTxIn& txin, tx.vin) @@ -246,13 +248,14 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) " \"transactionid\" : { (json object)\n" " \"size\" : n, (numeric) transaction size in bytes\n" " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" + " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n" " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" " \"height\" : n, (numeric) block height when transaction entered pool\n" " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" " \"currentpriority\" : n, (numeric) transaction priority now\n" " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n" - " \"descendantfees\" : n, (numeric) fees of in-mempool descendants (including this one)\n" + " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" " \"transactionid\", (string) parent transaction id\n" " ... ]\n" @@ -320,7 +323,8 @@ UniValue getblockheader(const UniValue& params, bool fHelp) " \"bits\" : \"1d00ffff\", (string) The bits\n" " \"difficulty\" : x.xxx, (numeric) The difficulty\n" " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" - " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n" + " \"nextblockhash\" : \"hash\", (string) The hash of the next block\n" + " \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n" "}\n" "\nResult (for verbose=false):\n" "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" @@ -381,6 +385,7 @@ UniValue getblock(const UniValue& params, bool fHelp) " \"nonce\" : n, (numeric) The nonce\n" " \"bits\" : \"1d00ffff\", (string) The bits\n" " \"difficulty\" : x.xxx, (numeric) The difficulty\n" + " \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n" " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n" "}\n" @@ -469,8 +474,8 @@ UniValue gettxout(const UniValue& params, bool fHelp) "\nReturns details about an unspent transaction output.\n" "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" - "2. n (numeric, required) vout value\n" - "3. includemempool (boolean, optional) Whether to included the mem pool\n" + "2. n (numeric, required) vout number\n" + "3. includemempool (boolean, optional) Whether to include the mem pool\n" "\nResult:\n" "{\n" " \"bestblock\" : \"hash\", (string) the block hash\n" @@ -566,7 +571,7 @@ UniValue verifychain(const UniValue& params, bool fHelp) if (params.size() > 1) nCheckDepth = params[1].get_int(); - return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth); + return CVerifyDB().VerifyDB(Params(), pcoinsTip, nCheckLevel, nCheckDepth); } /** Implementation of IsSuperMajority with better feedback */ @@ -794,9 +799,11 @@ UniValue getmempoolinfo(const UniValue& params, bool fHelp) "\nReturns details on the active state of the TX memory pool.\n" "\nResult:\n" "{\n" - " \"size\": xxxxx (numeric) Current tx count\n" - " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n" - " \"usage\": xxxxx (numeric) Total memory usage for the mempool\n" + " \"size\": xxxxx, (numeric) Current tx count\n" + " \"bytes\": xxxxx, (numeric) Sum of all tx sizes\n" + " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n" + " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n" + " \"mempoolminfee\": xxxxx (numeric) Minimum fee for tx to be accepted\n" "}\n" "\nExamples:\n" + HelpExampleCli("getmempoolinfo", "") @@ -834,7 +841,7 @@ UniValue invalidateblock(const UniValue& params, bool fHelp) } if (state.IsValid()) { - ActivateBestChain(state); + ActivateBestChain(state, Params()); } if (!state.IsValid()) { @@ -873,7 +880,7 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp) } if (state.IsValid()) { - ActivateBestChain(state); + ActivateBestChain(state, Params()); } if (!state.IsValid()) { diff --git a/src/rpcclient.cpp b/src/rpc/client.cpp similarity index 96% rename from src/rpcclient.cpp rename to src/rpc/client.cpp index 343b6234d..b0e9b6f15 100644 --- a/src/rpcclient.cpp +++ b/src/rpc/client.cpp @@ -1,11 +1,10 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "rpcclient.h" - -#include "rpcprotocol.h" +#include "rpc/client.h" +#include "rpc/protocol.h" #include "util.h" #include @@ -96,6 +95,8 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getrawmempool", 0 }, { "estimatefee", 0 }, { "estimatepriority", 0 }, + { "estimatesmartfee", 0 }, + { "estimatesmartpriority", 0 }, { "prioritisetransaction", 1 }, { "prioritisetransaction", 2 }, { "setban", 2 }, diff --git a/src/rpcclient.h b/src/rpc/client.h similarity index 91% rename from src/rpcclient.h rename to src/rpc/client.h index 8937a56f0..ae015860b 100644 --- a/src/rpcclient.h +++ b/src/rpc/client.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcmining.cpp b/src/rpc/mining.cpp similarity index 90% rename from src/rpcmining.cpp rename to src/rpc/mining.cpp index 3fd07fc37..996b7f9cb 100644 --- a/src/rpcmining.cpp +++ b/src/rpc/mining.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -14,7 +14,7 @@ #include "miner.h" #include "net.h" #include "pow.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "txmempool.h" #include "util.h" #include "utilstrencodings.h" @@ -99,7 +99,7 @@ UniValue getgenerate(const UniValue& params, bool fHelp) throw runtime_error( "getgenerate\n" "\nReturn if the server is set to generate coins or not. The default is false.\n" - "It is set with the command line argument -gen (or bitcoin.conf setting gen)\n" + "It is set with the command line argument -gen (or " + std::string(BITCOIN_CONF_FILENAME) + " setting gen)\n" "It can also be set with the setgenerate call.\n" "\nResult\n" "true|false (boolean) If the server is set to generate coins or not\n" @@ -109,7 +109,7 @@ UniValue getgenerate(const UniValue& params, bool fHelp) ); LOCK(cs_main); - return GetBoolArg("-gen", false); + return GetBoolArg("-gen", DEFAULT_GENERATE); } UniValue generate(const UniValue& params, bool fHelp) @@ -726,3 +726,75 @@ UniValue estimatepriority(const UniValue& params, bool fHelp) return mempool.estimatePriority(nBlocks); } + +UniValue estimatesmartfee(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "estimatesmartfee nblocks\n" + "\nWARNING: This interface is unstable and may disappear or change!\n" + "\nEstimates the approximate fee per kilobyte needed for a transaction to begin\n" + "confirmation within nblocks blocks if possible and return the number of blocks\n" + "for which the estimate is valid.\n" + "\nArguments:\n" + "1. nblocks (numeric)\n" + "\nResult:\n" + "{\n" + " \"feerate\" : x.x, (numeric) estimate fee-per-kilobyte (in BTC)\n" + " \"blocks\" : n (numeric) block number where estimate was found\n" + "}\n" + "\n" + "A negative value is returned if not enough transactions and blocks\n" + "have been observed to make an estimate for any number of blocks.\n" + "However it will not return a value below the mempool reject fee.\n" + "\nExample:\n" + + HelpExampleCli("estimatesmartfee", "6") + ); + + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); + + int nBlocks = params[0].get_int(); + + UniValue result(UniValue::VOBJ); + int answerFound; + CFeeRate feeRate = mempool.estimateSmartFee(nBlocks, &answerFound); + result.push_back(Pair("feerate", feeRate == CFeeRate(0) ? -1.0 : ValueFromAmount(feeRate.GetFeePerK()))); + result.push_back(Pair("blocks", answerFound)); + return result; +} + +UniValue estimatesmartpriority(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "estimatesmartpriority nblocks\n" + "\nWARNING: This interface is unstable and may disappear or change!\n" + "\nEstimates the approximate priority a zero-fee transaction needs to begin\n" + "confirmation within nblocks blocks if possible and return the number of blocks\n" + "for which the estimate is valid.\n" + "\nArguments:\n" + "1. nblocks (numeric)\n" + "\nResult:\n" + "{\n" + " \"priority\" : x.x, (numeric) estimated priority\n" + " \"blocks\" : n (numeric) block number where estimate was found\n" + "}\n" + "\n" + "A negative value is returned if not enough transactions and blocks\n" + "have been observed to make an estimate for any number of blocks.\n" + "However if the mempool reject fee is set it will return 1e9 * MAX_MONEY.\n" + "\nExample:\n" + + HelpExampleCli("estimatesmartpriority", "6") + ); + + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); + + int nBlocks = params[0].get_int(); + + UniValue result(UniValue::VOBJ); + int answerFound; + double priority = mempool.estimateSmartPriority(nBlocks, &answerFound); + result.push_back(Pair("priority", priority)); + result.push_back(Pair("blocks", answerFound)); + return result; +} diff --git a/src/rpcmisc.cpp b/src/rpc/misc.cpp similarity index 99% rename from src/rpcmisc.cpp rename to src/rpc/misc.cpp index 0c656d5cf..0aab9c304 100644 --- a/src/rpcmisc.cpp +++ b/src/rpc/misc.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,7 +9,7 @@ #include "main.h" #include "net.h" #include "netbase.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "timedata.h" #include "util.h" #include "utilstrencodings.h" diff --git a/src/rpcnet.cpp b/src/rpc/net.cpp similarity index 95% rename from src/rpcnet.cpp rename to src/rpc/net.cpp index 257884889..065214a98 100644 --- a/src/rpcnet.cpp +++ b/src/rpc/net.cpp @@ -1,8 +1,8 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "rpcserver.h" +#include "rpc/server.h" #include "chainparams.h" #include "clientversion.h" @@ -111,6 +111,14 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) " n, (numeric) The heights of blocks we're currently asking from this peer\n" " ...\n" " ]\n" + " \"bytessent_per_msg\": {\n" + " \"addr\": n, (numeric) The total bytes sent aggregated by message type\n" + " ...\n" + " }\n" + " \"bytesrecv_per_msg\": {\n" + " \"addr\": n, (numeric) The total bytes received aggregated by message type\n" + " ...\n" + " }\n" " }\n" " ,...\n" "]\n" @@ -165,6 +173,20 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) } obj.push_back(Pair("whitelisted", stats.fWhitelisted)); + UniValue sendPerMsgCmd(UniValue::VOBJ); + BOOST_FOREACH(const mapMsgCmdSize::value_type &i, stats.mapSendBytesPerMsgCmd) { + if (i.second > 0) + sendPerMsgCmd.push_back(Pair(i.first, i.second)); + } + obj.push_back(Pair("bytessent_per_msg", sendPerMsgCmd)); + + UniValue recvPerMsgCmd(UniValue::VOBJ); + BOOST_FOREACH(const mapMsgCmdSize::value_type &i, stats.mapRecvBytesPerMsgCmd) { + if (i.second > 0) + recvPerMsgCmd.push_back(Pair(i.first, i.second)); + } + obj.push_back(Pair("bytesrecv_per_msg", recvPerMsgCmd)); + ret.push_back(obj); } diff --git a/src/rpcprotocol.cpp b/src/rpc/protocol.cpp similarity index 97% rename from src/rpcprotocol.cpp rename to src/rpc/protocol.cpp index d83cd87f9..f5275062a 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpc/protocol.cpp @@ -1,9 +1,9 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "rpcprotocol.h" +#include "rpc/protocol.h" #include "random.h" #include "tinyformat.h" diff --git a/src/rpcprotocol.h b/src/rpc/protocol.h similarity index 98% rename from src/rpcprotocol.h rename to src/rpc/protocol.h index 9cf1ab6d9..55d0aac68 100644 --- a/src/rpcprotocol.h +++ b/src/rpc/protocol.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpcrawtransaction.cpp b/src/rpc/rawtransaction.cpp similarity index 98% rename from src/rpcrawtransaction.cpp rename to src/rpc/rawtransaction.cpp index 3bda45924..2ec80f468 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -15,7 +15,7 @@ #include "net.h" #include "policy/policy.h" #include "primitives/transaction.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "script/script.h" #include "script/script_error.h" #include "script/sign.h" @@ -62,6 +62,7 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); + entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION))); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); UniValue vin(UniValue::VARR); @@ -133,6 +134,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) "{\n" " \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n" " \"txid\" : \"id\", (string) The transaction id (same as provided)\n" + " \"size\" : n, (numeric) The transaction size\n" " \"version\" : n, (numeric) The version\n" " \"locktime\" : ttt, (numeric) The lock time\n" " \"vin\" : [ (array of json objects)\n" @@ -336,7 +338,7 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) " ]\n" "2. \"outputs\" (string, required) a json object with outputs\n" " {\n" - " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the " + CURRENCY_UNIT + " amount\n" + " \"address\": x.xxx (numeric or string, required) The key is the bitcoin address, the numeric value (can be string) is the " + CURRENCY_UNIT + " amount\n" " \"data\": \"hex\", (string, required) The key is \"data\", the value is hex encoded data\n" " ...\n" " }\n" @@ -351,7 +353,6 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"{\\\"data\\\":\\\"00010203\\\"}\"") ); - LOCK(cs_main); RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)(UniValue::VNUM), true); if (params[0].isNull() || params[1].isNull()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, arguments 1 and 2 must be non-null"); @@ -429,6 +430,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp) "\nResult:\n" "{\n" " \"txid\" : \"id\", (string) The transaction id\n" + " \"size\" : n, (numeric) The transaction size\n" " \"version\" : n, (numeric) The version\n" " \"locktime\" : ttt, (numeric) The lock time\n" " \"vin\" : [ (array of json objects)\n" diff --git a/src/rpcserver.cpp b/src/rpc/server.cpp similarity index 80% rename from src/rpcserver.cpp rename to src/rpc/server.cpp index 8bda5a037..b2d4559cc 100644 --- a/src/rpcserver.cpp +++ b/src/rpc/server.cpp @@ -1,9 +1,9 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "rpcserver.h" +#include "rpc/server.h" #include "base58.h" #include "init.h" @@ -33,7 +33,7 @@ static bool fRPCInWarmup = true; static std::string rpcWarmupStatus("RPC server started"); static CCriticalSection cs_rpcWarmup; /* Timer-creating functions */ -static std::vector timerInterfaces; +static RPCTimerInterface* timerInterface = NULL; /* Map of name to timer. * @note Can be changed to std::unique_ptr when C++11 */ static std::map > deadlineTimers; @@ -309,9 +309,6 @@ static const CRPCCommand vRPCCommands[] = { "rawtransactions", "getrawtransaction", &getrawtransaction, true }, { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false }, { "rawtransactions", "signrawtransaction", &signrawtransaction, false }, /* uses wallet if enabled */ -#ifdef ENABLE_WALLET - { "rawtransactions", "fundrawtransaction", &fundrawtransaction, false }, -#endif /* Utility functions */ { "util", "createmultisig", &createmultisig, true }, @@ -319,58 +316,13 @@ static const CRPCCommand vRPCCommands[] = { "util", "verifymessage", &verifymessage, true }, { "util", "estimatefee", &estimatefee, true }, { "util", "estimatepriority", &estimatepriority, true }, + { "util", "estimatesmartfee", &estimatesmartfee, true }, + { "util", "estimatesmartpriority", &estimatesmartpriority, true }, /* Not shown in help */ { "hidden", "invalidateblock", &invalidateblock, true }, { "hidden", "reconsiderblock", &reconsiderblock, true }, { "hidden", "setmocktime", &setmocktime, true }, -#ifdef ENABLE_WALLET - { "hidden", "resendwallettransactions", &resendwallettransactions, true}, -#endif - -#ifdef ENABLE_WALLET - /* Wallet */ - { "wallet", "addmultisigaddress", &addmultisigaddress, true }, - { "wallet", "backupwallet", &backupwallet, true }, - { "wallet", "dumpprivkey", &dumpprivkey, true }, - { "wallet", "dumpwallet", &dumpwallet, true }, - { "wallet", "encryptwallet", &encryptwallet, true }, - { "wallet", "getaccountaddress", &getaccountaddress, true }, - { "wallet", "getaccount", &getaccount, true }, - { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true }, - { "wallet", "getbalance", &getbalance, false }, - { "wallet", "getnewaddress", &getnewaddress, true }, - { "wallet", "getrawchangeaddress", &getrawchangeaddress, true }, - { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false }, - { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false }, - { "wallet", "gettransaction", &gettransaction, false }, - { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false }, - { "wallet", "getwalletinfo", &getwalletinfo, false }, - { "wallet", "importprivkey", &importprivkey, true }, - { "wallet", "importwallet", &importwallet, true }, - { "wallet", "importaddress", &importaddress, true }, - { "wallet", "importpubkey", &importpubkey, true }, - { "wallet", "keypoolrefill", &keypoolrefill, true }, - { "wallet", "listaccounts", &listaccounts, false }, - { "wallet", "listaddressgroupings", &listaddressgroupings, false }, - { "wallet", "listlockunspent", &listlockunspent, false }, - { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false }, - { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false }, - { "wallet", "listsinceblock", &listsinceblock, false }, - { "wallet", "listtransactions", &listtransactions, false }, - { "wallet", "listunspent", &listunspent, false }, - { "wallet", "lockunspent", &lockunspent, true }, - { "wallet", "move", &movecmd, false }, - { "wallet", "sendfrom", &sendfrom, false }, - { "wallet", "sendmany", &sendmany, false }, - { "wallet", "sendtoaddress", &sendtoaddress, false }, - { "wallet", "setaccount", &setaccount, true }, - { "wallet", "settxfee", &settxfee, true }, - { "wallet", "signmessage", &signmessage, true }, - { "wallet", "walletlock", &walletlock, true }, - { "wallet", "walletpassphrasechange", &walletpassphrasechange, true }, - { "wallet", "walletpassphrase", &walletpassphrase, true }, -#endif // ENABLE_WALLET }; CRPCTable::CRPCTable() @@ -393,6 +345,20 @@ const CRPCCommand *CRPCTable::operator[](const std::string &name) const return (*it).second; } +bool CRPCTable::appendCommand(const std::string& name, const CRPCCommand* pcmd) +{ + if (IsRPCRunning()) + return false; + + // don't allow overwriting for now + map::const_iterator it = mapCommands.find(name); + if (it != mapCommands.end()) + return false; + + mapCommands[name] = pcmd; + return true; +} + bool StartRPC() { LogPrint("rpc", "Starting RPC\n"); @@ -544,26 +510,30 @@ std::string HelpExampleRpc(const std::string& methodname, const std::string& arg "\"method\": \"" + methodname + "\", \"params\": [" + args + "] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/\n"; } -void RPCRegisterTimerInterface(RPCTimerInterface *iface) +void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface) { - timerInterfaces.push_back(iface); + if (!timerInterface) + timerInterface = iface; } -void RPCUnregisterTimerInterface(RPCTimerInterface *iface) +void RPCSetTimerInterface(RPCTimerInterface *iface) { - std::vector::iterator i = std::find(timerInterfaces.begin(), timerInterfaces.end(), iface); - assert(i != timerInterfaces.end()); - timerInterfaces.erase(i); + timerInterface = iface; +} + +void RPCUnsetTimerInterface(RPCTimerInterface *iface) +{ + if (timerInterface == iface) + timerInterface = NULL; } void RPCRunLater(const std::string& name, boost::function func, int64_t nSeconds) { - if (timerInterfaces.empty()) + if (!timerInterface) throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC"); deadlineTimers.erase(name); - RPCTimerInterface* timerInterface = timerInterfaces[0]; LogPrint("rpc", "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name()); deadlineTimers.insert(std::make_pair(name, boost::shared_ptr(timerInterface->NewTimer(func, nSeconds*1000)))); } -const CRPCTable tableRPC; +CRPCTable tableRPC; diff --git a/src/rpcserver.h b/src/rpc/server.h similarity index 73% rename from src/rpcserver.h rename to src/rpc/server.h index dde8dfdcc..99ffad5d4 100644 --- a/src/rpcserver.h +++ b/src/rpc/server.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,7 +7,7 @@ #define BITCOIN_RPCSERVER_H #include "amount.h" -#include "rpcprotocol.h" +#include "rpc/protocol.h" #include "uint256.h" #include @@ -100,10 +100,12 @@ public: virtual RPCTimerBase* NewTimer(boost::function& func, int64_t millis) = 0; }; -/** Register factory function for timers */ -void RPCRegisterTimerInterface(RPCTimerInterface *iface); -/** Unregister factory function for timers */ -void RPCUnregisterTimerInterface(RPCTimerInterface *iface); +/** Set the factory function for timers */ +void RPCSetTimerInterface(RPCTimerInterface *iface); +/** Set the factory function for timer, but only, if unset */ +void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface); +/** Unset factory function for timers */ +void RPCUnsetTimerInterface(RPCTimerInterface *iface); /** * Run func nSeconds from now. @@ -142,9 +144,17 @@ public: * @throws an exception (UniValue) when an error happens. */ UniValue execute(const std::string &method, const UniValue ¶ms) const; + + + /** + * Appends a CRPCCommand to the dispatch table. + * Returns false if RPC server is already running (dump concurrency protection). + * Commands cannot be overwritten (returns false). + */ + bool appendCommand(const std::string& name, const CRPCCommand* pcmd); }; -extern const CRPCTable tableRPC; +extern CRPCTable tableRPC; /** * Utilities: convert hex-encoded Values @@ -165,7 +175,7 @@ extern std::string HelpExampleRpc(const std::string& methodname, const std::stri extern void EnsureWalletIsUnlocked(); -extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpcnet.cpp +extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpc/net.cpp extern UniValue getpeerinfo(const UniValue& params, bool fHelp); extern UniValue ping(const UniValue& params, bool fHelp); extern UniValue addnode(const UniValue& params, bool fHelp); @@ -176,14 +186,7 @@ extern UniValue setban(const UniValue& params, bool fHelp); extern UniValue listbanned(const UniValue& params, bool fHelp); extern UniValue clearbanned(const UniValue& params, bool fHelp); -extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp -extern UniValue importprivkey(const UniValue& params, bool fHelp); -extern UniValue importaddress(const UniValue& params, bool fHelp); -extern UniValue importpubkey(const UniValue& params, bool fHelp); -extern UniValue dumpwallet(const UniValue& params, bool fHelp); -extern UniValue importwallet(const UniValue& params, bool fHelp); - -extern UniValue getgenerate(const UniValue& params, bool fHelp); // in rpcmining.cpp +extern UniValue getgenerate(const UniValue& params, bool fHelp); // in rpc/mining.cpp extern UniValue setgenerate(const UniValue& params, bool fHelp); extern UniValue generate(const UniValue& params, bool fHelp); extern UniValue getnetworkhashps(const UniValue& params, bool fHelp); @@ -193,60 +196,30 @@ extern UniValue getblocktemplate(const UniValue& params, bool fHelp); extern UniValue submitblock(const UniValue& params, bool fHelp); extern UniValue estimatefee(const UniValue& params, bool fHelp); extern UniValue estimatepriority(const UniValue& params, bool fHelp); +extern UniValue estimatesmartfee(const UniValue& params, bool fHelp); +extern UniValue estimatesmartpriority(const UniValue& params, bool fHelp); -extern UniValue getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp -extern UniValue getaccountaddress(const UniValue& params, bool fHelp); -extern UniValue getrawchangeaddress(const UniValue& params, bool fHelp); -extern UniValue setaccount(const UniValue& params, bool fHelp); -extern UniValue getaccount(const UniValue& params, bool fHelp); -extern UniValue getaddressesbyaccount(const UniValue& params, bool fHelp); -extern UniValue sendtoaddress(const UniValue& params, bool fHelp); -extern UniValue signmessage(const UniValue& params, bool fHelp); extern UniValue verifymessage(const UniValue& params, bool fHelp); -extern UniValue getreceivedbyaddress(const UniValue& params, bool fHelp); -extern UniValue getreceivedbyaccount(const UniValue& params, bool fHelp); -extern UniValue getbalance(const UniValue& params, bool fHelp); -extern UniValue getunconfirmedbalance(const UniValue& params, bool fHelp); -extern UniValue movecmd(const UniValue& params, bool fHelp); -extern UniValue sendfrom(const UniValue& params, bool fHelp); -extern UniValue sendmany(const UniValue& params, bool fHelp); -extern UniValue addmultisigaddress(const UniValue& params, bool fHelp); extern UniValue createmultisig(const UniValue& params, bool fHelp); -extern UniValue listreceivedbyaddress(const UniValue& params, bool fHelp); -extern UniValue listreceivedbyaccount(const UniValue& params, bool fHelp); -extern UniValue listtransactions(const UniValue& params, bool fHelp); -extern UniValue listaddressgroupings(const UniValue& params, bool fHelp); -extern UniValue listaccounts(const UniValue& params, bool fHelp); -extern UniValue listsinceblock(const UniValue& params, bool fHelp); -extern UniValue gettransaction(const UniValue& params, bool fHelp); -extern UniValue backupwallet(const UniValue& params, bool fHelp); -extern UniValue keypoolrefill(const UniValue& params, bool fHelp); -extern UniValue walletpassphrase(const UniValue& params, bool fHelp); -extern UniValue walletpassphrasechange(const UniValue& params, bool fHelp); -extern UniValue walletlock(const UniValue& params, bool fHelp); -extern UniValue encryptwallet(const UniValue& params, bool fHelp); extern UniValue validateaddress(const UniValue& params, bool fHelp); extern UniValue getinfo(const UniValue& params, bool fHelp); -extern UniValue getwalletinfo(const UniValue& params, bool fHelp); extern UniValue getblockchaininfo(const UniValue& params, bool fHelp); extern UniValue getnetworkinfo(const UniValue& params, bool fHelp); extern UniValue setmocktime(const UniValue& params, bool fHelp); -extern UniValue resendwallettransactions(const UniValue& params, bool fHelp); -extern UniValue getrawtransaction(const UniValue& params, bool fHelp); // in rcprawtransaction.cpp +extern UniValue getrawtransaction(const UniValue& params, bool fHelp); // in rpc/rawtransaction.cpp extern UniValue listunspent(const UniValue& params, bool fHelp); extern UniValue lockunspent(const UniValue& params, bool fHelp); extern UniValue listlockunspent(const UniValue& params, bool fHelp); extern UniValue createrawtransaction(const UniValue& params, bool fHelp); extern UniValue decoderawtransaction(const UniValue& params, bool fHelp); extern UniValue decodescript(const UniValue& params, bool fHelp); -extern UniValue fundrawtransaction(const UniValue& params, bool fHelp); extern UniValue signrawtransaction(const UniValue& params, bool fHelp); extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); extern UniValue gettxoutproof(const UniValue& params, bool fHelp); extern UniValue verifytxoutproof(const UniValue& params, bool fHelp); -extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpcblockchain.cpp +extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpc/blockchain.cpp extern UniValue getbestblockhash(const UniValue& params, bool fHelp); extern UniValue getdifficulty(const UniValue& params, bool fHelp); extern UniValue settxfee(const UniValue& params, bool fHelp); diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index 79504f6ad..47ad1d080 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h index a48ff1e18..5b8c33c6b 100644 --- a/src/script/bitcoinconsensus.h +++ b/src/script/bitcoinconsensus.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 8dcab832c..a92822326 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -1023,7 +1023,7 @@ public: // Serialize the script if (nInput != nIn) // Blank out other inputs' signatures - ::Serialize(s, CScript(), nType, nVersion); + ::Serialize(s, CScriptBase(), nType, nVersion); else SerializeScriptCode(s, nType, nVersion); // Serialize the nSequence diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 213e8c765..7b34547ff 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/script.cpp b/src/script/script.cpp index 263c89def..9f2809e59 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -131,7 +131,7 @@ const char* GetOpName(opcodetype opcode) // expanson case OP_NOP1 : return "OP_NOP1"; - case OP_NOP2 : return "OP_NOP2"; + case OP_CHECKLOCKTIMEVERIFY : return "OP_CHECKLOCKTIMEVERIFY"; case OP_NOP3 : return "OP_NOP3"; case OP_NOP4 : return "OP_NOP4"; case OP_NOP5 : return "OP_NOP5"; @@ -205,9 +205,9 @@ bool CScript::IsPayToScriptHash() const { // Extra-fast test for pay-to-script-hash CScripts: return (this->size() == 23 && - this->at(0) == OP_HASH160 && - this->at(1) == 0x14 && - this->at(22) == OP_EQUAL); + (*this)[0] == OP_HASH160 && + (*this)[1] == 0x14 && + (*this)[22] == OP_EQUAL); } bool CScript::IsPushOnly(const_iterator pc) const diff --git a/src/script/script.h b/src/script/script.h index a38d33a18..6551eea30 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,6 +7,7 @@ #define BITCOIN_SCRIPT_SCRIPT_H #include "crypto/common.h" +#include "prevector.h" #include #include @@ -161,8 +162,8 @@ enum opcodetype // expansion OP_NOP1 = 0xb0, - OP_NOP2 = 0xb1, - OP_CHECKLOCKTIMEVERIFY = OP_NOP2, + OP_CHECKLOCKTIMEVERIFY = 0xb1, + OP_NOP2 = OP_CHECKLOCKTIMEVERIFY, OP_NOP3 = 0xb2, OP_NOP4 = 0xb3, OP_NOP5 = 0xb4, @@ -354,8 +355,10 @@ private: int64_t m_value; }; +typedef prevector<28, unsigned char> CScriptBase; + /** Serialized script, used inside transaction inputs and outputs */ -class CScript : public std::vector +class CScript : public CScriptBase { protected: CScript& push_int64(int64_t n) @@ -376,9 +379,10 @@ protected: } public: CScript() { } - CScript(const CScript& b) : std::vector(b.begin(), b.end()) { } - CScript(const_iterator pbegin, const_iterator pend) : std::vector(pbegin, pend) { } - CScript(const unsigned char* pbegin, const unsigned char* pend) : std::vector(pbegin, pend) { } + CScript(const CScript& b) : CScriptBase(b.begin(), b.end()) { } + CScript(const_iterator pbegin, const_iterator pend) : CScriptBase(pbegin, pend) { } + CScript(std::vector::const_iterator pbegin, std::vector::const_iterator pend) : CScriptBase(pbegin, pend) { } + CScript(const unsigned char* pbegin, const unsigned char* pend) : CScriptBase(pbegin, pend) { } CScript& operator+=(const CScript& b) { @@ -611,7 +615,7 @@ public: void clear() { // The default std::vector::clear() does not release memory. - std::vector().swap(*this); + CScriptBase().swap(*this); } }; diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index eee96e7c2..bdc0bfdc1 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/sigcache.h b/src/script/sigcache.h index 226997256..be1df09c2 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 8b43183b6..2f4111f78 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -16,7 +16,7 @@ using namespace std; -typedef vector valtype; +typedef std::vector valtype; TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), checker(txTo, nIn) {} @@ -118,7 +118,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu bool fSolved = SignStep(creator, subscript, scriptSig, subType) && subType != TX_SCRIPTHASH; // Append serialized subscript whether or not it is completely signed: - scriptSig << static_cast(subscript); + scriptSig << valtype(subscript.begin(), subscript.end()); if (!fSolved) return false; } diff --git a/src/script/sign.h b/src/script/sign.h index 13f45007d..47a9cde7f 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/script/standard.cpp b/src/script/standard.cpp index bfef8afa1..67b6af327 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -16,6 +16,7 @@ using namespace std; typedef vector valtype; +bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER; unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY; CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {} @@ -160,27 +161,6 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector >& vSolutions) -{ - switch (t) - { - case TX_NONSTANDARD: - case TX_NULL_DATA: - return -1; - case TX_PUBKEY: - return 1; - case TX_PUBKEYHASH: - return 2; - case TX_MULTISIG: - if (vSolutions.size() < 1 || vSolutions[0].size() < 1) - return -1; - return vSolutions[0][0] + 1; - case TX_SCRIPTHASH: - return 1; // doesn't include args needed by the script - } - return -1; -} - bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) { vector vSolutions; diff --git a/src/script/standard.h b/src/script/standard.h index ae1bbecca..64bf010ec 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -13,6 +13,8 @@ #include +static const bool DEFAULT_ACCEPT_DATACARRIER = true; + class CKeyID; class CScript; @@ -26,6 +28,7 @@ public: }; static const unsigned int MAX_OP_RETURN_RELAY = 83; //! bytes (+1 for OP_RETURN, +2 for the pushdata opcodes) +extern bool fAcceptDatacarrier; extern unsigned nMaxDatacarrierBytes; /** @@ -68,7 +71,6 @@ typedef boost::variant CTxDestination; const char* GetTxnOutputType(txnouttype t); bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector >& vSolutionsRet); -int ScriptSigArgsExpected(txnouttype t, const std::vector >& vSolutions); bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet); bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector& addressRet, int& nRequiredRet); diff --git a/src/secp256k1/Makefile.am b/src/secp256k1/Makefile.am index f4121f170..7772a4e9d 100644 --- a/src/secp256k1/Makefile.am +++ b/src/secp256k1/Makefile.am @@ -75,7 +75,7 @@ TESTS = tests endif if USE_ECMULT_STATIC_PRECOMPUTATION -CPPFLAGS_FOR_BUILD +=-I$(top_srcdir)/ +CPPFLAGS_FOR_BUILD +=-I$(top_srcdir) CFLAGS_FOR_BUILD += -Wall -Wextra -Wno-unused-function gen_context_OBJECTS = gen_context.o diff --git a/src/serialize.h b/src/serialize.h index 53d8af142..5c2db9d33 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -20,7 +20,7 @@ #include #include -class CScript; +#include "prevector.h" static const unsigned int MAX_SIZE = 0x02000000; @@ -49,26 +49,26 @@ inline T* NCONST_PTR(const T* val) * @note These functions avoid the undefined case of indexing into an empty * vector, as well as that of indexing after the end of the vector. */ -template -inline T* begin_ptr(std::vector& v) +template +inline typename V::value_type* begin_ptr(V& v) { return v.empty() ? NULL : &v[0]; } /** Get begin pointer of vector (const version) */ -template -inline const T* begin_ptr(const std::vector& v) +template +inline const typename V::value_type* begin_ptr(const V& v) { return v.empty() ? NULL : &v[0]; } /** Get end pointer of vector (non-const version) */ -template -inline T* end_ptr(std::vector& v) +template +inline typename V::value_type* end_ptr(V& v) { return v.empty() ? NULL : (&v[0] + v.size()); } /** Get end pointer of vector (const version) */ -template -inline const T* end_ptr(const std::vector& v) +template +inline const typename V::value_type* end_ptr(const V& v) { return v.empty() ? NULL : (&v[0] + v.size()); } @@ -391,6 +391,12 @@ public: pbegin = (char*)begin_ptr(v); pend = (char*)end_ptr(v); } + template + explicit CFlatData(prevector &v) + { + pbegin = (char*)begin_ptr(v); + pend = (char*)end_ptr(v); + } char* begin() { return pbegin; } const char* begin() const { return pbegin; } char* end() { return pend; } @@ -485,6 +491,20 @@ template unsigned int GetSerializeSize(const std::basic_string& s template void Serialize(Stream& os, const std::basic_string& str, int, int=0); template void Unserialize(Stream& is, std::basic_string& str, int, int=0); +/** + * prevector + * prevectors of unsigned char are a special case and are intended to be serialized as a single opaque blob. + */ +template unsigned int GetSerializeSize_impl(const prevector& v, int nType, int nVersion, const unsigned char&); +template unsigned int GetSerializeSize_impl(const prevector& v, int nType, int nVersion, const V&); +template inline unsigned int GetSerializeSize(const prevector& v, int nType, int nVersion); +template void Serialize_impl(Stream& os, const prevector& v, int nType, int nVersion, const unsigned char&); +template void Serialize_impl(Stream& os, const prevector& v, int nType, int nVersion, const V&); +template inline void Serialize(Stream& os, const prevector& v, int nType, int nVersion); +template void Unserialize_impl(Stream& is, prevector& v, int nType, int nVersion, const unsigned char&); +template void Unserialize_impl(Stream& is, prevector& v, int nType, int nVersion, const V&); +template inline void Unserialize(Stream& is, prevector& v, int nType, int nVersion); + /** * vector * vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob. @@ -499,13 +519,6 @@ template void Unserialize_impl(Stream& template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const V&); template inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion); -/** - * others derived from vector - */ -extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion); -template void Serialize(Stream& os, const CScript& v, int nType, int nVersion); -template void Unserialize(Stream& is, CScript& v, int nType, int nVersion); - /** * pair */ @@ -587,6 +600,96 @@ void Unserialize(Stream& is, std::basic_string& str, int, int) +/** + * prevector + */ +template +unsigned int GetSerializeSize_impl(const prevector& v, int nType, int nVersion, const unsigned char&) +{ + return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T)); +} + +template +unsigned int GetSerializeSize_impl(const prevector& v, int nType, int nVersion, const V&) +{ + unsigned int nSize = GetSizeOfCompactSize(v.size()); + for (typename prevector::const_iterator vi = v.begin(); vi != v.end(); ++vi) + nSize += GetSerializeSize((*vi), nType, nVersion); + return nSize; +} + +template +inline unsigned int GetSerializeSize(const prevector& v, int nType, int nVersion) +{ + return GetSerializeSize_impl(v, nType, nVersion, T()); +} + + +template +void Serialize_impl(Stream& os, const prevector& v, int nType, int nVersion, const unsigned char&) +{ + WriteCompactSize(os, v.size()); + if (!v.empty()) + os.write((char*)&v[0], v.size() * sizeof(T)); +} + +template +void Serialize_impl(Stream& os, const prevector& v, int nType, int nVersion, const V&) +{ + WriteCompactSize(os, v.size()); + for (typename prevector::const_iterator vi = v.begin(); vi != v.end(); ++vi) + ::Serialize(os, (*vi), nType, nVersion); +} + +template +inline void Serialize(Stream& os, const prevector& v, int nType, int nVersion) +{ + Serialize_impl(os, v, nType, nVersion, T()); +} + + +template +void Unserialize_impl(Stream& is, prevector& v, int nType, int nVersion, const unsigned char&) +{ + // Limit size per read so bogus size value won't cause out of memory + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + while (i < nSize) + { + unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); + v.resize(i + blk); + is.read((char*)&v[i], blk * sizeof(T)); + i += blk; + } +} + +template +void Unserialize_impl(Stream& is, prevector& v, int nType, int nVersion, const V&) +{ + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + unsigned int nMid = 0; + while (nMid < nSize) + { + nMid += 5000000 / sizeof(T); + if (nMid > nSize) + nMid = nSize; + v.resize(nMid); + for (; i < nMid; i++) + Unserialize(is, v[i], nType, nVersion); + } +} + +template +inline void Unserialize(Stream& is, prevector& v, int nType, int nVersion) +{ + Unserialize_impl(is, v, nType, nVersion, T()); +} + + + /** * vector */ @@ -677,28 +780,6 @@ inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersio -/** - * others derived from vector - */ -inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion) -{ - return GetSerializeSize((const std::vector&)v, nType, nVersion); -} - -template -void Serialize(Stream& os, const CScript& v, int nType, int nVersion) -{ - Serialize(os, (const std::vector&)v, nType, nVersion); -} - -template -void Unserialize(Stream& is, CScript& v, int nType, int nVersion) -{ - Unserialize(is, (std::vector&)v, nType, nVersion); -} - - - /** * pair */ diff --git a/src/streams.h b/src/streams.h index 8610e4d18..0fc6135a6 100644 --- a/src/streams.h +++ b/src/streams.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/support/allocators/secure.h b/src/support/allocators/secure.h index 5e7bb66ea..1ec40fe83 100644 --- a/src/support/allocators/secure.h +++ b/src/support/allocators/secure.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/support/allocators/zeroafterfree.h b/src/support/allocators/zeroafterfree.h index 41e23392e..28a940ad1 100644 --- a/src/support/allocators/zeroafterfree.h +++ b/src/support/allocators/zeroafterfree.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/support/pagelocker.cpp b/src/support/pagelocker.cpp index 440e0a519..7cea2d88c 100644 --- a/src/support/pagelocker.cpp +++ b/src/support/pagelocker.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/support/pagelocker.h b/src/support/pagelocker.h index 88b95cce7..6b3979e55 100644 --- a/src/support/pagelocker.h +++ b/src/support/pagelocker.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/sync.cpp b/src/sync.cpp index 1837e8d53..8df8ae43f 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2012 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/sync.h b/src/sync.h index 68a944308..34dd8c228 100644 --- a/src/sync.h +++ b/src/sync.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index 0a23c430e..1b7d368e1 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index da296a046..95342498f 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -49,7 +49,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning) CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); // Should get banned - SendMessages(&dummyNode1, false); + SendMessages(&dummyNode1); BOOST_CHECK(CNode::IsBanned(addr1)); BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned @@ -57,11 +57,11 @@ BOOST_AUTO_TEST_CASE(DoS_banning) CNode dummyNode2(INVALID_SOCKET, addr2, "", true); dummyNode2.nVersion = 1; Misbehaving(dummyNode2.GetId(), 50); - SendMessages(&dummyNode2, false); + SendMessages(&dummyNode2); BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet... BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be Misbehaving(dummyNode2.GetId(), 50); - SendMessages(&dummyNode2, false); + SendMessages(&dummyNode2); BOOST_CHECK(CNode::IsBanned(addr2)); } @@ -73,13 +73,13 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) CNode dummyNode1(INVALID_SOCKET, addr1, "", true); dummyNode1.nVersion = 1; Misbehaving(dummyNode1.GetId(), 100); - SendMessages(&dummyNode1, false); + SendMessages(&dummyNode1); BOOST_CHECK(!CNode::IsBanned(addr1)); Misbehaving(dummyNode1.GetId(), 10); - SendMessages(&dummyNode1, false); + SendMessages(&dummyNode1); BOOST_CHECK(!CNode::IsBanned(addr1)); Misbehaving(dummyNode1.GetId(), 1); - SendMessages(&dummyNode1, false); + SendMessages(&dummyNode1); BOOST_CHECK(CNode::IsBanned(addr1)); mapArgs.erase("-banscore"); } @@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) dummyNode.nVersion = 1; Misbehaving(dummyNode.GetId(), 100); - SendMessages(&dummyNode, false); + SendMessages(&dummyNode); BOOST_CHECK(CNode::IsBanned(addr)); SetMockTime(nStartTime+60*60); diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp index 4a294c671..dad191c68 100644 --- a/src/test/accounting_tests.cpp +++ b/src/test/accounting_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index cfcdd9abb..767b653e4 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "addrman.h" @@ -6,11 +6,49 @@ #include #include +#include "hash.h" #include "random.h" using namespace std; -class CAddrManTest : public CAddrMan{}; +class CAddrManTest : public CAddrMan +{ + uint64_t state; + +public: + CAddrManTest() + { + state = 1; + } + + //! Ensure that bucket placement is always the same for testing purposes. + void MakeDeterministic() + { + nKey.SetNull(); + seed_insecure_rand(true); + } + + int RandomInt(int nMax) + { + state = (CHashWriter(SER_GETHASH, 0) << state).GetHash().GetCheapHash(); + return (unsigned int)(state % nMax); + } + + CAddrInfo* Find(const CNetAddr& addr, int* pnId = NULL) + { + return CAddrMan::Find(addr, pnId); + } + + CAddrInfo* Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId = NULL) + { + return CAddrMan::Create(addr, addrSource, pnId); + } + + void Delete(int nId) + { + CAddrMan::Delete(nId); + } +}; BOOST_FIXTURE_TEST_SUITE(addrman_tests, BasicTestingSetup) @@ -21,7 +59,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CNetAddr source = CNetAddr("252.2.2.2:8333"); + CNetAddr source = CNetAddr("252.2.2.2"); // Test 1: Does Addrman respond correctly when empty. BOOST_CHECK(addrman.size() == 0); @@ -29,26 +67,26 @@ BOOST_AUTO_TEST_CASE(addrman_simple) BOOST_CHECK(addr_null.ToString() == "[::]:0"); // Test 2: Does Addrman::Add work as expected. - CService addr1 = CService("250.1.1.1:8333"); + CService addr1 = CService("250.1.1.1", 8333); addrman.Add(CAddress(addr1), source); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret1 = addrman.Select(); BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); - // Test 3: Does IP address deduplication work correctly. + // Test 3: Does IP address deduplication work correctly. // Expected dup IP should not be added. - CService addr1_dup = CService("250.1.1.1:8333"); + CService addr1_dup = CService("250.1.1.1", 8333); addrman.Add(CAddress(addr1_dup), source); BOOST_CHECK(addrman.size() == 1); // Test 5: New table has one addr and we add a diff addr we should // have two addrs. - CService addr2 = CService("250.1.1.2:8333"); + CService addr2 = CService("250.1.1.2", 8333); addrman.Add(CAddress(addr2), source); BOOST_CHECK(addrman.size() == 2); - // Test 6: AddrMan::Clear() should empty the new table. + // Test 6: AddrMan::Clear() should empty the new table. addrman.Clear(); BOOST_CHECK(addrman.size() == 0); CAddrInfo addr_null2 = addrman.Select(); @@ -62,16 +100,16 @@ BOOST_AUTO_TEST_CASE(addrman_ports) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CNetAddr source = CNetAddr("252.2.2.2:8333"); + CNetAddr source = CNetAddr("252.2.2.2"); BOOST_CHECK(addrman.size() == 0); // Test 7; Addr with same IP but diff port does not replace existing addr. - CService addr1 = CService("250.1.1.1:8333"); + CService addr1 = CService("250.1.1.1", 8333); addrman.Add(CAddress(addr1), source); BOOST_CHECK(addrman.size() == 1); - CService addr1_port = CService("250.1.1.1:8334"); + CService addr1_port = CService("250.1.1.1", 8334); addrman.Add(CAddress(addr1_port), source); BOOST_CHECK(addrman.size() == 1); CAddrInfo addr_ret2 = addrman.Select(); @@ -94,10 +132,10 @@ BOOST_AUTO_TEST_CASE(addrman_select) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CNetAddr source = CNetAddr("252.2.2.2:8333"); + CNetAddr source = CNetAddr("252.2.2.2"); // Test 9: Select from new with 1 addr in new. - CService addr1 = CService("250.1.1.1:8333"); + CService addr1 = CService("250.1.1.1", 8333); addrman.Add(CAddress(addr1), source); BOOST_CHECK(addrman.size() == 1); @@ -105,7 +143,6 @@ BOOST_AUTO_TEST_CASE(addrman_select) CAddrInfo addr_ret1 = addrman.Select(newOnly); BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333"); - // Test 10: move addr to tried, select from new expected nothing returned. addrman.Good(CAddress(addr1)); BOOST_CHECK(addrman.size() == 1); @@ -114,6 +151,39 @@ BOOST_AUTO_TEST_CASE(addrman_select) CAddrInfo addr_ret3 = addrman.Select(); BOOST_CHECK(addr_ret3.ToString() == "250.1.1.1:8333"); + + BOOST_CHECK(addrman.size() == 1); + + + // Add three addresses to new table. + CService addr2 = CService("250.3.1.1", 8333); + CService addr3 = CService("250.3.2.2", 9999); + CService addr4 = CService("250.3.3.3", 9999); + + addrman.Add(CAddress(addr2), CService("250.3.1.1", 8333)); + addrman.Add(CAddress(addr3), CService("250.3.1.1", 8333)); + addrman.Add(CAddress(addr4), CService("250.4.1.1", 8333)); + + // Add three addresses to tried table. + CService addr5 = CService("250.4.4.4", 8333); + CService addr6 = CService("250.4.5.5", 7777); + CService addr7 = CService("250.4.6.6", 8333); + + addrman.Add(CAddress(addr5), CService("250.3.1.1", 8333)); + addrman.Good(CAddress(addr5)); + addrman.Add(CAddress(addr6), CService("250.3.1.1", 8333)); + addrman.Good(CAddress(addr6)); + addrman.Add(CAddress(addr7), CService("250.1.1.3", 8333)); + addrman.Good(CAddress(addr7)); + + // Test 11: 6 addrs + 1 addr from last test = 7. + BOOST_CHECK(addrman.size() == 7); + + // Test 12: Select pulls from new and tried regardless of port number. + BOOST_CHECK(addrman.Select().ToString() == "250.4.6.6:8333"); + BOOST_CHECK(addrman.Select().ToString() == "250.3.2.2:9999"); + BOOST_CHECK(addrman.Select().ToString() == "250.3.3.3:9999"); + BOOST_CHECK(addrman.Select().ToString() == "250.4.4.4:8333"); } BOOST_AUTO_TEST_CASE(addrman_new_collisions) @@ -123,26 +193,26 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CNetAddr source = CNetAddr("252.2.2.2:8333"); + CNetAddr source = CNetAddr("252.2.2.2"); BOOST_CHECK(addrman.size() == 0); - for (unsigned int i = 1; i < 4; i++){ - CService addr = CService("250.1.1."+boost::to_string(i)); + for (unsigned int i = 1; i < 18; i++) { + CService addr = CService("250.1.1." + boost::to_string(i)); addrman.Add(CAddress(addr), source); - //Test 11: No collision in new table yet. + //Test 13: No collision in new table yet. BOOST_CHECK(addrman.size() == i); } - //Test 12: new table collision! - CService addr1 = CService("250.1.1.4"); + //Test 14: new table collision! + CService addr1 = CService("250.1.1.18"); addrman.Add(CAddress(addr1), source); - BOOST_CHECK(addrman.size() == 3); + BOOST_CHECK(addrman.size() == 17); - CService addr2 = CService("250.1.1.5"); + CService addr2 = CService("250.1.1.19"); addrman.Add(CAddress(addr2), source); - BOOST_CHECK(addrman.size() == 4); + BOOST_CHECK(addrman.size() == 18); } BOOST_AUTO_TEST_CASE(addrman_tried_collisions) @@ -152,29 +222,300 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) // Set addrman addr placement to be deterministic. addrman.MakeDeterministic(); - CNetAddr source = CNetAddr("252.2.2.2:8333"); + CNetAddr source = CNetAddr("252.2.2.2"); BOOST_CHECK(addrman.size() == 0); - for (unsigned int i = 1; i < 75; i++){ - CService addr = CService("250.1.1."+boost::to_string(i)); + for (unsigned int i = 1; i < 80; i++) { + CService addr = CService("250.1.1." + boost::to_string(i)); addrman.Add(CAddress(addr), source); addrman.Good(CAddress(addr)); - //Test 13: No collision in tried table yet. + //Test 15: No collision in tried table yet. BOOST_TEST_MESSAGE(addrman.size()); BOOST_CHECK(addrman.size() == i); } - //Test 14: tried table collision! - CService addr1 = CService("250.1.1.76"); + //Test 16: tried table collision! + CService addr1 = CService("250.1.1.80"); addrman.Add(CAddress(addr1), source); - BOOST_CHECK(addrman.size() == 74); + BOOST_CHECK(addrman.size() == 79); - CService addr2 = CService("250.1.1.77"); + CService addr2 = CService("250.1.1.81"); addrman.Add(CAddress(addr2), source); - BOOST_CHECK(addrman.size() == 75); + BOOST_CHECK(addrman.size() == 80); +} + +BOOST_AUTO_TEST_CASE(addrman_find) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + BOOST_CHECK(addrman.size() == 0); + + CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); + CAddress addr2 = CAddress(CService("250.1.2.1", 9999)); + CAddress addr3 = CAddress(CService("251.255.2.1", 8333)); + + CNetAddr source1 = CNetAddr("250.1.2.1"); + CNetAddr source2 = CNetAddr("250.1.2.2"); + + addrman.Add(addr1, source1); + addrman.Add(addr2, source2); + addrman.Add(addr3, source1); + + // Test 17: ensure Find returns an IP matching what we searched on. + CAddrInfo* info1 = addrman.Find(addr1); + BOOST_CHECK(info1); + if (info1) + BOOST_CHECK(info1->ToString() == "250.1.2.1:8333"); + + // Test 18; Find does not discriminate by port number. + CAddrInfo* info2 = addrman.Find(addr2); + BOOST_CHECK(info2); + if (info2) + BOOST_CHECK(info2->ToString() == info1->ToString()); + + // Test 19: Find returns another IP matching what we searched on. + CAddrInfo* info3 = addrman.Find(addr3); + BOOST_CHECK(info3); + if (info3) + BOOST_CHECK(info3->ToString() == "251.255.2.1:8333"); +} + +BOOST_AUTO_TEST_CASE(addrman_create) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + BOOST_CHECK(addrman.size() == 0); + + CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); + CNetAddr source1 = CNetAddr("250.1.2.1"); + + int nId; + CAddrInfo* pinfo = addrman.Create(addr1, source1, &nId); + + // Test 20: The result should be the same as the input addr. + BOOST_CHECK(pinfo->ToString() == "250.1.2.1:8333"); + + CAddrInfo* info2 = addrman.Find(addr1); + BOOST_CHECK(info2->ToString() == "250.1.2.1:8333"); } +BOOST_AUTO_TEST_CASE(addrman_delete) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + BOOST_CHECK(addrman.size() == 0); + + CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); + CNetAddr source1 = CNetAddr("250.1.2.1"); + + int nId; + addrman.Create(addr1, source1, &nId); + + // Test 21: Delete should actually delete the addr. + BOOST_CHECK(addrman.size() == 1); + addrman.Delete(nId); + BOOST_CHECK(addrman.size() == 0); + CAddrInfo* info2 = addrman.Find(addr1); + BOOST_CHECK(info2 == NULL); +} + +BOOST_AUTO_TEST_CASE(addrman_getaddr) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + // Test 22: Sanity check, GetAddr should never return anything if addrman + // is empty. + BOOST_CHECK(addrman.size() == 0); + vector vAddr1 = addrman.GetAddr(); + BOOST_CHECK(vAddr1.size() == 0); + + CAddress addr1 = CAddress(CService("250.250.2.1", 8333)); + addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false + CAddress addr2 = CAddress(CService("250.251.2.2", 9999)); + addr2.nTime = GetAdjustedTime(); + CAddress addr3 = CAddress(CService("251.252.2.3", 8333)); + addr3.nTime = GetAdjustedTime(); + CAddress addr4 = CAddress(CService("252.253.3.4", 8333)); + addr4.nTime = GetAdjustedTime(); + CAddress addr5 = CAddress(CService("252.254.4.5", 8333)); + addr5.nTime = GetAdjustedTime(); + CNetAddr source1 = CNetAddr("250.1.2.1"); + CNetAddr source2 = CNetAddr("250.2.3.3"); + + // Test 23: Ensure GetAddr works with new addresses. + addrman.Add(addr1, source1); + addrman.Add(addr2, source2); + addrman.Add(addr3, source1); + addrman.Add(addr4, source2); + addrman.Add(addr5, source1); + + // GetAddr returns 23% of addresses, 23% of 5 is 1 rounded down. + BOOST_CHECK(addrman.GetAddr().size() == 1); + + // Test 24: Ensure GetAddr works with new and tried addresses. + addrman.Good(CAddress(addr1)); + addrman.Good(CAddress(addr2)); + BOOST_CHECK(addrman.GetAddr().size() == 1); + + // Test 25: Ensure GetAddr still returns 23% when addrman has many addrs. + for (unsigned int i = 1; i < (8 * 256); i++) { + int octet1 = i % 256; + int octet2 = (i / 256) % 256; + int octet3 = (i / (256 * 2)) % 256; + string strAddr = boost::to_string(octet1) + "." + boost::to_string(octet2) + "." + boost::to_string(octet3) + ".23"; + CAddress addr = CAddress(CService(strAddr)); + + // Ensure that for all addrs in addrman, isTerrible == false. + addr.nTime = GetAdjustedTime(); + addrman.Add(addr, CNetAddr(strAddr)); + if (i % 8 == 0) + addrman.Good(addr); + } + vector vAddr = addrman.GetAddr(); + + size_t percent23 = (addrman.size() * 23) / 100; + BOOST_CHECK(vAddr.size() == percent23); + BOOST_CHECK(vAddr.size() == 461); + // (Addrman.size() < number of addresses added) due to address collisons. + BOOST_CHECK(addrman.size() == 2007); +} + + +BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + CAddress addr1 = CAddress(CService("250.1.1.1", 8333)); + CAddress addr2 = CAddress(CService("250.1.1.1", 9999)); + + CNetAddr source1 = CNetAddr("250.1.1.1"); + + + CAddrInfo info1 = CAddrInfo(addr1, source1); + + uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash(); + uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash(); + + + BOOST_CHECK(info1.GetTriedBucket(nKey1) == 40); + + // Test 26: Make sure key actually randomizes bucket placement. A fail on + // this test could be a security issue. + BOOST_CHECK(info1.GetTriedBucket(nKey1) != info1.GetTriedBucket(nKey2)); + + // Test 27: Two addresses with same IP but different ports can map to + // different buckets because they have different keys. + CAddrInfo info2 = CAddrInfo(addr2, source1); + + BOOST_CHECK(info1.GetKey() != info2.GetKey()); + BOOST_CHECK(info1.GetTriedBucket(nKey1) != info2.GetTriedBucket(nKey1)); + + set buckets; + for (int i = 0; i < 255; i++) { + CAddrInfo infoi = CAddrInfo( + CAddress(CService("250.1.1." + boost::to_string(i))), + CNetAddr("250.1.1." + boost::to_string(i))); + int bucket = infoi.GetTriedBucket(nKey1); + buckets.insert(bucket); + } + // Test 28: IP addresses in the same group (\16 prefix for IPv4) should + // never get more than 8 buckets + BOOST_CHECK(buckets.size() == 8); + + buckets.clear(); + for (int j = 0; j < 255; j++) { + CAddrInfo infoj = CAddrInfo( + CAddress(CService("250." + boost::to_string(j) + ".1.1")), + CNetAddr("250." + boost::to_string(j) + ".1.1")); + int bucket = infoj.GetTriedBucket(nKey1); + buckets.insert(bucket); + } + // Test 29: IP addresses in the different groups should map to more than + // 8 buckets. + BOOST_CHECK(buckets.size() == 160); +} + +BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) +{ + CAddrManTest addrman; + + // Set addrman addr placement to be deterministic. + addrman.MakeDeterministic(); + + CAddress addr1 = CAddress(CService("250.1.2.1", 8333)); + CAddress addr2 = CAddress(CService("250.1.2.1", 9999)); + + CNetAddr source1 = CNetAddr("250.1.2.1"); + + CAddrInfo info1 = CAddrInfo(addr1, source1); + + uint256 nKey1 = (uint256)(CHashWriter(SER_GETHASH, 0) << 1).GetHash(); + uint256 nKey2 = (uint256)(CHashWriter(SER_GETHASH, 0) << 2).GetHash(); + + BOOST_CHECK(info1.GetNewBucket(nKey1) == 786); + + // Test 30: Make sure key actually randomizes bucket placement. A fail on + // this test could be a security issue. + BOOST_CHECK(info1.GetNewBucket(nKey1) != info1.GetNewBucket(nKey2)); + + // Test 31: Ports should not effect bucket placement in the addr + CAddrInfo info2 = CAddrInfo(addr2, source1); + BOOST_CHECK(info1.GetKey() != info2.GetKey()); + BOOST_CHECK(info1.GetNewBucket(nKey1) == info2.GetNewBucket(nKey1)); + + set buckets; + for (int i = 0; i < 255; i++) { + CAddrInfo infoi = CAddrInfo( + CAddress(CService("250.1.1." + boost::to_string(i))), + CNetAddr("250.1.1." + boost::to_string(i))); + int bucket = infoi.GetNewBucket(nKey1); + buckets.insert(bucket); + } + // Test 32: IP addresses in the same group (\16 prefix for IPv4) should + // always map to the same bucket. + BOOST_CHECK(buckets.size() == 1); + + buckets.clear(); + for (int j = 0; j < 4 * 255; j++) { + CAddrInfo infoj = CAddrInfo(CAddress( + CService( + boost::to_string(250 + (j / 255)) + "." + boost::to_string(j % 256) + ".1.1")), + CNetAddr("251.4.1.1")); + int bucket = infoj.GetNewBucket(nKey1); + buckets.insert(bucket); + } + // Test 33: IP addresses in the same source groups should map to no more + // than 64 buckets. + BOOST_CHECK(buckets.size() <= 64); + + buckets.clear(); + for (int p = 0; p < 255; p++) { + CAddrInfo infoj = CAddrInfo( + CAddress(CService("250.1.1.1")), + CNetAddr("250." + boost::to_string(p) + ".1.1")); + int bucket = infoj.GetNewBucket(nKey1); + buckets.insert(bucket); + } + // Test 34: IP addresses in the different source groups should map to more + // than 64 buckets. + BOOST_CHECK(buckets.size() > 64); +} BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index 468eda1c9..0895ef332 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index 2108efece..613f6c12d 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index 17d6bed6d..53ab7e95e 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp index 8ec886142..6422b3a88 100644 --- a/src/test/base32_tests.cpp +++ b/src/test/base32_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 9845df697..e5a2e28b2 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp index 54c081b0e..ccad94d94 100644 --- a/src/test/base64_tests.cpp +++ b/src/test/base64_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/bignum.h b/src/test/bignum.h deleted file mode 100644 index e7aeee9db..000000000 --- a/src/test/bignum.h +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_TEST_BIGNUM_H -#define BITCOIN_TEST_BIGNUM_H - -#include -#include -#include -#include -#include -#include - -#include - -class bignum_error : public std::runtime_error -{ -public: - explicit bignum_error(const std::string& str) : std::runtime_error(str) {} -}; - - -/** C++ wrapper for BIGNUM (OpenSSL bignum) */ -class CBigNum : public BIGNUM -{ -public: - CBigNum() - { - BN_init(this); - } - - CBigNum(const CBigNum& b) - { - BN_init(this); - if (!BN_copy(this, &b)) - { - BN_clear_free(this); - throw bignum_error("CBigNum::CBigNum(const CBigNum&): BN_copy failed"); - } - } - - CBigNum& operator=(const CBigNum& b) - { - if (!BN_copy(this, &b)) - throw bignum_error("CBigNum::operator=: BN_copy failed"); - return (*this); - } - - ~CBigNum() - { - BN_clear_free(this); - } - - CBigNum(long long n) { BN_init(this); setint64(n); } - - explicit CBigNum(const std::vector& vch) - { - BN_init(this); - setvch(vch); - } - - int getint() const - { - BN_ULONG n = BN_get_word(this); - if (!BN_is_negative(this)) - return (n > (BN_ULONG)std::numeric_limits::max() ? std::numeric_limits::max() : n); - else - return (n > (BN_ULONG)std::numeric_limits::max() ? std::numeric_limits::min() : -(int)n); - } - - void setint64(int64_t sn) - { - unsigned char pch[sizeof(sn) + 6]; - unsigned char* p = pch + 4; - bool fNegative; - uint64_t n; - - if (sn < (int64_t)0) - { - // Since the minimum signed integer cannot be represented as positive so long as its type is signed, - // and it's not well-defined what happens if you make it unsigned before negating it, - // we instead increment the negative integer by 1, convert it, then increment the (now positive) unsigned integer by 1 to compensate - n = -(sn + 1); - ++n; - fNegative = true; - } else { - n = sn; - fNegative = false; - } - - bool fLeadingZeroes = true; - for (int i = 0; i < 8; i++) - { - unsigned char c = (n >> 56) & 0xff; - n <<= 8; - if (fLeadingZeroes) - { - if (c == 0) - continue; - if (c & 0x80) - *p++ = (fNegative ? 0x80 : 0); - else if (fNegative) - c |= 0x80; - fLeadingZeroes = false; - } - *p++ = c; - } - unsigned int nSize = p - (pch + 4); - pch[0] = (nSize >> 24) & 0xff; - pch[1] = (nSize >> 16) & 0xff; - pch[2] = (nSize >> 8) & 0xff; - pch[3] = (nSize) & 0xff; - BN_mpi2bn(pch, p - pch, this); - } - - void setvch(const std::vector& vch) - { - std::vector vch2(vch.size() + 4); - unsigned int nSize = vch.size(); - // BIGNUM's byte stream format expects 4 bytes of - // big endian size data info at the front - vch2[0] = (nSize >> 24) & 0xff; - vch2[1] = (nSize >> 16) & 0xff; - vch2[2] = (nSize >> 8) & 0xff; - vch2[3] = (nSize >> 0) & 0xff; - // swap data to big endian - reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4); - BN_mpi2bn(&vch2[0], vch2.size(), this); - } - - std::vector getvch() const - { - unsigned int nSize = BN_bn2mpi(this, NULL); - if (nSize <= 4) - return std::vector(); - std::vector vch(nSize); - BN_bn2mpi(this, &vch[0]); - vch.erase(vch.begin(), vch.begin() + 4); - reverse(vch.begin(), vch.end()); - return vch; - } - - friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b); -}; - - - -inline const CBigNum operator+(const CBigNum& a, const CBigNum& b) -{ - CBigNum r; - if (!BN_add(&r, &a, &b)) - throw bignum_error("CBigNum::operator+: BN_add failed"); - return r; -} - -inline const CBigNum operator-(const CBigNum& a, const CBigNum& b) -{ - CBigNum r; - if (!BN_sub(&r, &a, &b)) - throw bignum_error("CBigNum::operator-: BN_sub failed"); - return r; -} - -inline const CBigNum operator-(const CBigNum& a) -{ - CBigNum r(a); - BN_set_negative(&r, !BN_is_negative(&r)); - return r; -} - -inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); } -inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); } -inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); } -inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); } -inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); } -inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); } - -#endif // BITCOIN_TEST_BIGNUM_H diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 69084213a..ce29e692d 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 6b30d6aa8..98f9de767 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp index f7e247061..c945a95ad 100644 --- a/src/test/checkblock_tests.cpp +++ b/src/test/checkblock_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2014 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 946f904df..3fe536f91 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -164,14 +164,23 @@ BOOST_AUTO_TEST_CASE(coins_cache_simulation_test) } } + if (insecure_rand() % 100 == 0) { + // Every 100 iterations, flush an intermediate cache + if (stack.size() > 1 && insecure_rand() % 2 == 0) { + unsigned int flushIndex = insecure_rand() % (stack.size() - 1); + stack[flushIndex]->Flush(); + } + } if (insecure_rand() % 100 == 0) { // Every 100 iterations, change the cache stack. if (stack.size() > 0 && insecure_rand() % 2 == 0) { + //Remove the top cache stack.back()->Flush(); delete stack.back(); stack.pop_back(); } if (stack.size() == 0 || (stack.size() < 4 && insecure_rand() % 2)) { + //Add a new cache CCoinsView* tip = &base; if (stack.size() > 0) { tip = stack.back(); @@ -304,6 +313,13 @@ BOOST_AUTO_TEST_CASE(updatecoins_simulation_test) } } + if (insecure_rand() % 100 == 0) { + // Every 100 iterations, flush an intermediate cache + if (stack.size() > 1 && insecure_rand() % 2 == 0) { + unsigned int flushIndex = insecure_rand() % (stack.size() - 1); + stack[flushIndex]->Flush(); + } + } if (insecure_rand() % 100 == 0) { // Every 100 iterations, change the cache stack. if (stack.size() > 0 && insecure_rand() % 2 == 0) { diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp index 376ae9368..35e4458bb 100644 --- a/src/test/compress_tests.cpp +++ b/src/test/compress_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index aeb2a5caa..0b46d718d 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 7afa2abf4..7ce7e0879 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -160,12 +160,12 @@ ["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "disabled"], ["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "disabled"], -["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"], -["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"], +["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"], ["Ensure 100% coverage of discouraged NOPS"], ["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP2", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index a4e15faea..e5f0d17b0 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -232,8 +232,8 @@ ["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC"], -["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"], -["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"], +["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"], ["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "Discourage NOPx flag allows OP_NOP"], @@ -442,7 +442,7 @@ ["NOP", "CODESEPARATOR 1", "P2SH,STRICTENC"], ["NOP", "NOP1 1", "P2SH,STRICTENC"], -["NOP", "NOP2 1", "P2SH,STRICTENC"], +["NOP", "CHECKLOCKTIMEVERIFY 1", "P2SH,STRICTENC"], ["NOP", "NOP3 1", "P2SH,STRICTENC"], ["NOP", "NOP4 1", "P2SH,STRICTENC"], ["NOP", "NOP5 1", "P2SH,STRICTENC"], diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index cc059e814..902584194 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -127,66 +127,66 @@ ["CHECKLOCKTIMEVERIFY tests"], ["By-height locks, with argument just beyond tx nLockTime"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000fe64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], ["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000001 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument missing"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000001b1010000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument negative with by-blockheight nLockTime=0"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument negative with by-blocktime nLockTime=500,000,000"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000004005194b1010000000100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Input locked"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b1ffffffff0100000000000000000002000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Another input being unlocked isn't sufficient; the CHECKLOCKTIMEVERIFY-using input must be unlocked"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"] , +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"] , ["0000000000000000000000000000000000000000000000000000000000000200", 1, "1"]], "010000000200010000000000000000000000000000000000000000000000000000000000000000000000ffffffff00020000000000000000000000000000000000000000000000000000000000000100000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument/tx height/time mismatch, both versions"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000251b100000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], ["Argument 2^32 with nLockTime=2^32-1"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967296 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"], ["Same, but with nLockTime=2^31-1"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffff7f", "P2SH,CHECKLOCKTIMEVERIFY"], ["6 byte non-minimally-encoded arguments are invalid even if their contents are valid"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Failure due to failing CHECKLOCKTIMEVERIFY in scriptSig"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 0dfef73ae..76d29bcf2 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -190,35 +190,35 @@ ["CHECKLOCKTIMEVERIFY tests"], ["By-height locks, with argument == 0 and == tx nLockTime"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ff64cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], ["By-time locks, with argument just beyond tx nLockTime (but within numerical boundaries)"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "500000000 CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000ffffffff", "P2SH,CHECKLOCKTIMEVERIFY"], ["Any non-maxint nSequence is fine"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["The argument can be calculated rather than created directly by a PUSHDATA"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 1ADD NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "499999999 1ADD CHECKLOCKTIMEVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000065cd1d", "P2SH,CHECKLOCKTIMEVERIFY"], ["Perhaps even by an ADD producing a 5-byte result that is out of bounds for other opcodes"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 2147483647 ADD NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 2147483647 ADD CHECKLOCKTIMEVERIFY 1"]], "0100000001000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000feffffff", "P2SH,CHECKLOCKTIMEVERIFY"], ["5 byte non-minimally-encoded arguments are valid"], -[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 NOP2 1"]], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 CHECKLOCKTIMEVERIFY 1"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKLOCKTIMEVERIFY"], ["Valid CHECKLOCKTIMEVERIFY in scriptSig"], diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 8b6b0697a..e39931587 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index eb61a2884..9f59de3ef 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index e5d2e5a43..35079d161 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 13ca94946..4978c9513 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index 21ae46d6e..dbfbdd934 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -72,5 +72,4 @@ BOOST_AUTO_TEST_CASE(test_combiner_all) Test.disconnect(&ReturnTrue); BOOST_CHECK(Test()); } - BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index 896e1237e..1347d2365 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -102,12 +102,13 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) removed.clear(); } +template void CheckSort(CTxMemPool &pool, std::vector &sortedOrder) { BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size()); - CTxMemPool::indexed_transaction_set::nth_index<1>::type::iterator it = pool.mapTx.get<1>().begin(); + typename CTxMemPool::indexed_transaction_set::nth_index::type::iterator it = pool.mapTx.get().begin(); int count=0; - for (; it != pool.mapTx.get<1>().end(); ++it, ++count) { + for (; it != pool.mapTx.get().end(); ++it, ++count) { BOOST_CHECK_EQUAL(it->GetTx().GetHash().ToString(), sortedOrder[count]); } } @@ -163,7 +164,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) sortedOrder[2] = tx1.GetHash().ToString(); // 10000 sortedOrder[3] = tx4.GetHash().ToString(); // 15000 sortedOrder[4] = tx2.GetHash().ToString(); // 20000 - CheckSort(pool, sortedOrder); + CheckSort<1>(pool, sortedOrder); /* low fee but with high fee child */ /* tx6 -> tx7 -> tx8, tx9 -> tx10 */ @@ -175,7 +176,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) BOOST_CHECK_EQUAL(pool.size(), 6); // Check that at this point, tx6 is sorted low sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString()); - CheckSort(pool, sortedOrder); + CheckSort<1>(pool, sortedOrder); CTxMemPool::setEntries setAncestors; setAncestors.insert(pool.mapTx.find(tx6.GetHash())); @@ -201,7 +202,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) sortedOrder.erase(sortedOrder.begin()); sortedOrder.push_back(tx6.GetHash().ToString()); sortedOrder.push_back(tx7.GetHash().ToString()); - CheckSort(pool, sortedOrder); + CheckSort<1>(pool, sortedOrder); /* low fee child of tx7 */ CMutableTransaction tx8 = CMutableTransaction(); @@ -216,7 +217,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) // Now tx8 should be sorted low, but tx6/tx both high sortedOrder.insert(sortedOrder.begin(), tx8.GetHash().ToString()); - CheckSort(pool, sortedOrder); + CheckSort<1>(pool, sortedOrder); /* low fee child of tx7 */ CMutableTransaction tx9 = CMutableTransaction(); @@ -231,7 +232,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) // tx9 should be sorted low BOOST_CHECK_EQUAL(pool.size(), 9); sortedOrder.insert(sortedOrder.begin(), tx9.GetHash().ToString()); - CheckSort(pool, sortedOrder); + CheckSort<1>(pool, sortedOrder); std::vector snapshotOrder = sortedOrder; @@ -273,7 +274,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) sortedOrder.insert(sortedOrder.begin()+5, tx9.GetHash().ToString()); sortedOrder.insert(sortedOrder.begin()+6, tx8.GetHash().ToString()); sortedOrder.insert(sortedOrder.begin()+7, tx10.GetHash().ToString()); // tx10 is just before tx6 - CheckSort(pool, sortedOrder); + CheckSort<1>(pool, sortedOrder); // there should be 10 transactions in the mempool BOOST_CHECK_EQUAL(pool.size(), 10); @@ -281,9 +282,42 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) // Now try removing tx10 and verify the sort order returns to normal std::list removed; pool.remove(pool.mapTx.find(tx10.GetHash())->GetTx(), removed, true); - CheckSort(pool, snapshotOrder); + CheckSort<1>(pool, snapshotOrder); + + pool.remove(pool.mapTx.find(tx9.GetHash())->GetTx(), removed, true); + pool.remove(pool.mapTx.find(tx8.GetHash())->GetTx(), removed, true); + /* Now check the sort on the mining score index. + * Final order should be: + * + * tx7 (2M) + * tx2 (20k) + * tx4 (15000) + * tx1/tx5 (10000) + * tx3/6 (0) + * (Ties resolved by hash) + */ + sortedOrder.clear(); + sortedOrder.push_back(tx7.GetHash().ToString()); + sortedOrder.push_back(tx2.GetHash().ToString()); + sortedOrder.push_back(tx4.GetHash().ToString()); + if (tx1.GetHash() < tx5.GetHash()) { + sortedOrder.push_back(tx5.GetHash().ToString()); + sortedOrder.push_back(tx1.GetHash().ToString()); + } else { + sortedOrder.push_back(tx1.GetHash().ToString()); + sortedOrder.push_back(tx5.GetHash().ToString()); + } + if (tx3.GetHash() < tx6.GetHash()) { + sortedOrder.push_back(tx6.GetHash().ToString()); + sortedOrder.push_back(tx3.GetHash().ToString()); + } else { + sortedOrder.push_back(tx3.GetHash().ToString()); + sortedOrder.push_back(tx6.GetHash().ToString()); + } + CheckSort<3>(pool, sortedOrder); } + BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) { CTxMemPool pool(CFeeRate(1000)); diff --git a/src/test/merkle_tests.cpp b/src/test/merkle_tests.cpp new file mode 100644 index 000000000..b40ab848d --- /dev/null +++ b/src/test/merkle_tests.cpp @@ -0,0 +1,136 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "consensus/merkle.h" +#include "test/test_bitcoin.h" +#include "random.h" + +#include + +BOOST_FIXTURE_TEST_SUITE(merkle_tests, TestingSetup) + +// Older version of the merkle root computation code, for comparison. +static uint256 BlockBuildMerkleTree(const CBlock& block, bool* fMutated, std::vector& vMerkleTree) +{ + vMerkleTree.clear(); + vMerkleTree.reserve(block.vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes. + for (std::vector::const_iterator it(block.vtx.begin()); it != block.vtx.end(); ++it) + vMerkleTree.push_back(it->GetHash()); + int j = 0; + bool mutated = false; + for (int nSize = block.vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + { + for (int i = 0; i < nSize; i += 2) + { + int i2 = std::min(i+1, nSize-1); + if (i2 == i + 1 && i2 + 1 == nSize && vMerkleTree[j+i] == vMerkleTree[j+i2]) { + // Two identical hashes at the end of the list at a particular level. + mutated = true; + } + vMerkleTree.push_back(Hash(vMerkleTree[j+i].begin(), vMerkleTree[j+i].end(), + vMerkleTree[j+i2].begin(), vMerkleTree[j+i2].end())); + } + j += nSize; + } + if (fMutated) { + *fMutated = mutated; + } + return (vMerkleTree.empty() ? uint256() : vMerkleTree.back()); +} + +// Older version of the merkle branch computation code, for comparison. +static std::vector BlockGetMerkleBranch(const CBlock& block, const std::vector& vMerkleTree, int nIndex) +{ + std::vector vMerkleBranch; + int j = 0; + for (int nSize = block.vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + { + int i = std::min(nIndex^1, nSize-1); + vMerkleBranch.push_back(vMerkleTree[j+i]); + nIndex >>= 1; + j += nSize; + } + return vMerkleBranch; +} + +static inline int ctz(uint32_t i) { + if (i == 0) return 0; + int j = 0; + while (!(i & 1)) { + j++; + i >>= 1; + } + return j; +} + +BOOST_AUTO_TEST_CASE(merkle_test) +{ + for (int i = 0; i < 32; i++) { + // Try 32 block sizes: all sizes from 0 to 16 inclusive, and then 15 random sizes. + int ntx = (i <= 16) ? i : 17 + (insecure_rand() % 4000); + // Try up to 3 mutations. + for (int mutate = 0; mutate <= 3; mutate++) { + int duplicate1 = mutate >= 1 ? 1 << ctz(ntx) : 0; // The last how many transactions to duplicate first. + if (duplicate1 >= ntx) break; // Duplication of the entire tree results in a different root (it adds a level). + int ntx1 = ntx + duplicate1; // The resulting number of transactions after the first duplication. + int duplicate2 = mutate >= 2 ? 1 << ctz(ntx1) : 0; // Likewise for the second mutation. + if (duplicate2 >= ntx1) break; + int ntx2 = ntx1 + duplicate2; + int duplicate3 = mutate >= 3 ? 1 << ctz(ntx2) : 0; // And for the third mutation. + if (duplicate3 >= ntx2) break; + int ntx3 = ntx2 + duplicate3; + // Build a block with ntx different transactions. + CBlock block; + block.vtx.resize(ntx); + for (int j = 0; j < ntx; j++) { + CMutableTransaction mtx; + mtx.nLockTime = j; + block.vtx[j] = mtx; + } + // Compute the root of the block before mutating it. + bool unmutatedMutated = false; + uint256 unmutatedRoot = BlockMerkleRoot(block, &unmutatedMutated); + BOOST_CHECK(unmutatedMutated == false); + // Optionally mutate by duplicating the last transactions, resulting in the same merkle root. + block.vtx.resize(ntx3); + for (int j = 0; j < duplicate1; j++) { + block.vtx[ntx + j] = block.vtx[ntx + j - duplicate1]; + } + for (int j = 0; j < duplicate2; j++) { + block.vtx[ntx1 + j] = block.vtx[ntx1 + j - duplicate2]; + } + for (int j = 0; j < duplicate3; j++) { + block.vtx[ntx2 + j] = block.vtx[ntx2 + j - duplicate3]; + } + // Compute the merkle root and merkle tree using the old mechanism. + bool oldMutated = false; + std::vector merkleTree; + uint256 oldRoot = BlockBuildMerkleTree(block, &oldMutated, merkleTree); + // Compute the merkle root using the new mechanism. + bool newMutated = false; + uint256 newRoot = BlockMerkleRoot(block, &newMutated); + BOOST_CHECK(oldRoot == newRoot); + BOOST_CHECK(newRoot == unmutatedRoot); + BOOST_CHECK((newRoot == uint256()) == (ntx == 0)); + BOOST_CHECK(oldMutated == newMutated); + BOOST_CHECK(newMutated == !!mutate); + // If no mutation was done (once for every ntx value), try up to 16 branches. + if (mutate == 0) { + for (int loop = 0; loop < std::min(ntx, 16); loop++) { + // If ntx <= 16, try all branches. Otherise, try 16 random ones. + int mtx = loop; + if (ntx > 16) { + mtx = insecure_rand() % ntx; + } + std::vector newBranch = BlockMerkleBranch(block, mtx); + std::vector oldBranch = BlockGetMerkleBranch(block, merkleTree, mtx); + BOOST_CHECK(oldBranch == newBranch); + BOOST_CHECK(ComputeMerkleRootFromBranch(block.vtx[mtx].GetHash(), newBranch, mtx) == oldRoot); + } + } + } + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index dc20e3463..71b52409b 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -1,10 +1,11 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "chainparams.h" #include "coins.h" #include "consensus/consensus.h" +#include "consensus/merkle.h" #include "consensus/validation.h" #include "main.h" #include "miner.h" @@ -93,7 +94,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) pblock->vtx[0] = CTransaction(txCoinbase); if (txFirst.size() < 2) txFirst.push_back(new CTransaction(pblock->vtx[0])); - pblock->hashMerkleRoot = pblock->ComputeMerkleRoot(); + pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); pblock->nNonce = blockinfo[i].nonce; CValidationState state; BOOST_CHECK(ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL)); @@ -118,7 +119,23 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { tx.vout[0].nValue -= 1000000; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); + bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase + // If we don't set the # of sig ops in the CTxMemPoolEntry, template creation fails + mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); + tx.vin[0].prevout.hash = hash; + } + BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); + mempool.clear(); + + tx.vin[0].prevout.hash = txFirst[0]->GetHash(); + tx.vout[0].nValue = 5000000000LL; + for (unsigned int i = 0; i < 1001; ++i) + { + tx.vout[0].nValue -= 1000000; + hash = tx.GetHash(); + bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase + // If we do set the # of sig ops in the CTxMemPoolEntry, template creation passes + mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).SigOps(20).FromTx(tx)); tx.vin[0].prevout.hash = hash; } BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); @@ -138,18 +155,18 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { tx.vout[0].nValue -= 10000000; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); + bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase + mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; mempool.clear(); - // orphan in mempool + // orphan in mempool, template creation fails hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); - delete pblocktemplate; + mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).FromTx(tx)); + BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); // child with higher priority than parent @@ -157,7 +174,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].prevout.hash = txFirst[1]->GetHash(); tx.vout[0].nValue = 4900000000LL; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(100000000LL).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vin[0].prevout.hash = hash; tx.vin.resize(2); tx.vin[1].scriptSig = CScript() << OP_1; @@ -165,23 +182,23 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[1].prevout.n = 0; tx.vout[0].nValue = 5900000000LL; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(400000000LL).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); delete pblocktemplate; mempool.clear(); - // coinbase in mempool + // coinbase in mempool, template creation fails tx.vin.resize(1); tx.vin[0].prevout.SetNull(); tx.vin[0].scriptSig = CScript() << OP_0 << OP_1; tx.vout[0].nValue = 0; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); - delete pblocktemplate; + // give it a fee so it'll get mined + mempool.addUnchecked(hash, entry.Fee(100000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); - // invalid (pre-p2sh) txn in mempool + // invalid (pre-p2sh) txn in mempool, template creation fails tx.vin[0].prevout.hash = txFirst[0]->GetHash(); tx.vin[0].prevout.n = 0; tx.vin[0].scriptSig = CScript() << OP_1; @@ -189,28 +206,26 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) script = CScript() << OP_0; tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script)); hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(10000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vin[0].prevout.hash = hash; - tx.vin[0].scriptSig = CScript() << (std::vector)script; + tx.vin[0].scriptSig = CScript() << std::vector(script.begin(), script.end()); tx.vout[0].nValue -= 1000000; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); - delete pblocktemplate; + mempool.addUnchecked(hash, entry.Fee(1000000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); + BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); - // double spend txn pair in mempool + // double spend txn pair in mempool, template creation fails tx.vin[0].prevout.hash = txFirst[0]->GetHash(); tx.vin[0].scriptSig = CScript() << OP_1; tx.vout[0].nValue = 4900000000LL; tx.vout[0].scriptPubKey = CScript() << OP_1; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); - BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); - delete pblocktemplate; + mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); + BOOST_CHECK_THROW(CreateNewBlock(chainparams, scriptPubKey), std::runtime_error); mempool.clear(); // subsidy changing @@ -234,7 +249,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].scriptPubKey = CScript() << OP_1; tx.nLockTime = chainActive.Tip()->nHeight+1; hash = tx.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); + mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); BOOST_CHECK(!CheckFinalTx(tx, LOCKTIME_MEDIAN_TIME_PAST)); // time locked @@ -248,7 +263,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx2.vout[0].scriptPubKey = CScript() << OP_1; tx2.nLockTime = chainActive.Tip()->GetMedianTimePast()+1; hash = tx2.GetHash(); - mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx2)); + mempool.addUnchecked(hash, entry.Fee(100000000L).Time(GetTime()).SpendsCoinbase(true).FromTx(tx2)); BOOST_CHECK(!CheckFinalTx(tx2, LOCKTIME_MEDIAN_TIME_PAST)); BOOST_CHECK(pblocktemplate = CreateNewBlock(chainparams, scriptPubKey)); diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp deleted file mode 100644 index 2b68f8899..000000000 --- a/src/test/mruset_tests.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2012-2013 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 "mruset.h" - -#include "random.h" -#include "util.h" -#include "test/test_bitcoin.h" - -#include - -#include - -#define NUM_TESTS 16 -#define MAX_SIZE 100 - -using namespace std; - -BOOST_FIXTURE_TEST_SUITE(mruset_tests, BasicTestingSetup) - -BOOST_AUTO_TEST_CASE(mruset_test) -{ - // The mruset being tested. - mruset mru(5000); - - // Run the test 10 times. - for (int test = 0; test < 10; test++) { - // Reset mru. - mru.clear(); - - // A deque + set to simulate the mruset. - std::deque rep; - std::set all; - - // Insert 10000 random integers below 15000. - for (int j=0; j<10000; j++) { - int add = GetRandInt(15000); - mru.insert(add); - - // Add the number to rep/all as well. - if (all.count(add) == 0) { - all.insert(add); - rep.push_back(add); - if (all.size() == 5001) { - all.erase(rep.front()); - rep.pop_front(); - } - } - - // Do a full comparison between mru and the simulated mru every 1000 and every 5001 elements. - if (j % 1000 == 0 || j % 5001 == 0) { - mruset mru2 = mru; // Also try making a copy - - // Check that all elements that should be in there, are in there. - BOOST_FOREACH(int x, rep) { - BOOST_CHECK(mru.count(x)); - BOOST_CHECK(mru2.count(x)); - } - - // Check that all elements that are in there, should be in there. - BOOST_FOREACH(int x, mru) { - BOOST_CHECK(all.count(x)); - } - - // Check that all elements that are in there, should be in there. - BOOST_FOREACH(int x, mru2) { - BOOST_CHECK(all.count(x)); - } - - for (int t = 0; t < 10; t++) { - int r = GetRandInt(15000); - BOOST_CHECK(all.count(r) == mru.count(r)); - BOOST_CHECK(all.count(r) == mru2.count(r)); - } - } - } - } -} - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index b65c299ad..edf1650ca 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-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. diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index b1ef0ed24..4168f75e9 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index d9f3c3e46..113b9437e 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -1,7 +1,8 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "consensus/merkle.h" #include "merkleblock.h" #include "serialize.h" #include "streams.h" @@ -48,7 +49,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1) } // calculate actual merkle root and height - uint256 merkleRoot1 = block.ComputeMerkleRoot(); + uint256 merkleRoot1 = BlockMerkleRoot(block); std::vector vTxid(nTx, uint256()); for (unsigned int j=0; j 8*baseRate.GetFeePerK() - deltaFee); + BOOST_CHECK(mpool.estimateFee(2) == CFeeRate(0)); + BOOST_CHECK(mpool.estimateFee(3) == CFeeRate(0)); + BOOST_CHECK(mpool.estimateFee(4).GetFeePerK() < 8*baseRate.GetFeePerK() + deltaFee); + BOOST_CHECK(mpool.estimateFee(4).GetFeePerK() > 8*baseRate.GetFeePerK() - deltaFee); + int answerFound; + BOOST_CHECK(mpool.estimateSmartFee(1, &answerFound) == mpool.estimateFee(4) && answerFound == 4); + BOOST_CHECK(mpool.estimateSmartFee(3, &answerFound) == mpool.estimateFee(4) && answerFound == 4); + BOOST_CHECK(mpool.estimateSmartFee(4, &answerFound) == mpool.estimateFee(4) && answerFound == 4); + BOOST_CHECK(mpool.estimateSmartFee(8, &answerFound) == mpool.estimateFee(8) && answerFound == 8); } } @@ -97,9 +104,9 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) // Highest feerate is 10*baseRate and gets in all blocks, // second highest feerate is 9*baseRate and gets in 9/10 blocks = 90%, // third highest feerate is 8*base rate, and gets in 8/10 blocks = 80%, - // so estimateFee(1) should return 9*baseRate. - // Third highest feerate has 90% chance of being included by 2 blocks, - // so estimateFee(2) should return 8*baseRate etc... + // so estimateFee(1) should return 10*baseRate. + // Second highest feerate has 100% chance of being included by 2 blocks, + // so estimateFee(2) should return 9*baseRate etc... for (int i = 1; i < 10;i++) { origFeeEst.push_back(mpool.estimateFee(i).GetFeePerK()); origPriEst.push_back(mpool.estimatePriority(i)); @@ -107,10 +114,11 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) BOOST_CHECK(origFeeEst[i-1] <= origFeeEst[i-2]); BOOST_CHECK(origPriEst[i-1] <= origPriEst[i-2]); } - BOOST_CHECK(origFeeEst[i-1] < (10-i)*baseRate.GetFeePerK() + deltaFee); - BOOST_CHECK(origFeeEst[i-1] > (10-i)*baseRate.GetFeePerK() - deltaFee); - BOOST_CHECK(origPriEst[i-1] < pow(10,10-i) * basepri + deltaPri); - BOOST_CHECK(origPriEst[i-1] > pow(10,10-i) * basepri - deltaPri); + int mult = 11-i; + BOOST_CHECK(origFeeEst[i-1] < mult*baseRate.GetFeePerK() + deltaFee); + BOOST_CHECK(origFeeEst[i-1] > mult*baseRate.GetFeePerK() - deltaFee); + BOOST_CHECK(origPriEst[i-1] < pow(10,mult) * basepri + deltaPri); + BOOST_CHECK(origPriEst[i-1] > pow(10,mult) * basepri - deltaPri); } // Mine 50 more blocks with no transactions happening, estimates shouldn't change @@ -140,9 +148,12 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) mpool.removeForBlock(block, ++blocknum, dummyConflicted); } + int answerFound; for (int i = 1; i < 10;i++) { - BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); - BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri); + BOOST_CHECK(mpool.estimateFee(i) == CFeeRate(0) || mpool.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee); + BOOST_CHECK(mpool.estimateSmartFee(i, &answerFound).GetFeePerK() > origFeeEst[answerFound-1] - deltaFee); + BOOST_CHECK(mpool.estimatePriority(i) == -1 || mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri); + BOOST_CHECK(mpool.estimateSmartPriority(i, &answerFound) > origPriEst[answerFound-1] - deltaPri); } // Mine all those transactions @@ -162,9 +173,9 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) BOOST_CHECK(mpool.estimatePriority(i) > origPriEst[i-1] - deltaPri); } - // Mine 100 more blocks where everything is mined every block - // Estimates should be below original estimates (not possible for last estimate) - while (blocknum < 365) { + // Mine 200 more blocks where everything is mined every block + // Estimates should be below original estimates + while (blocknum < 465) { for (int j = 0; j < 10; j++) { // For each fee/pri multiple for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx tx.vin[0].prevout.n = 10000*blocknum+100*j+k; @@ -178,10 +189,22 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) mpool.removeForBlock(block, ++blocknum, dummyConflicted); block.clear(); } - for (int i = 1; i < 9; i++) { + for (int i = 1; i < 10; i++) { BOOST_CHECK(mpool.estimateFee(i).GetFeePerK() < origFeeEst[i-1] - deltaFee); BOOST_CHECK(mpool.estimatePriority(i) < origPriEst[i-1] - deltaPri); } + + // Test that if the mempool is limited, estimateSmartFee won't return a value below the mempool min fee + // and that estimateSmartPriority returns essentially an infinite value + mpool.addUnchecked(tx.GetHash(), entry.Fee(feeV[0][5]).Time(GetTime()).Priority(priV[1][5]).Height(blocknum).FromTx(tx, &mpool)); + // evict that transaction which should set a mempool min fee of minRelayTxFee + feeV[0][5] + mpool.TrimToSize(1); + BOOST_CHECK(mpool.GetMinFee(1).GetFeePerK() > feeV[0][5]); + for (int i = 1; i < 10; i++) { + BOOST_CHECK(mpool.estimateSmartFee(i).GetFeePerK() >= mpool.estimateFee(i).GetFeePerK()); + BOOST_CHECK(mpool.estimateSmartFee(i).GetFeePerK() >= mpool.GetMinFee(1).GetFeePerK()); + BOOST_CHECK(mpool.estimateSmartPriority(i) == INF_PRIORITY); + } } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp new file mode 100644 index 000000000..01a45b540 --- /dev/null +++ b/src/test/prevector_tests.cpp @@ -0,0 +1,217 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include "prevector.h" +#include "random.h" + +#include "serialize.h" +#include "streams.h" + +#include "test/test_bitcoin.h" + +#include + +BOOST_FIXTURE_TEST_SUITE(PrevectorTests, TestingSetup) + +template +class prevector_tester { + typedef std::vector realtype; + realtype real_vector; + + typedef prevector pretype; + pretype pre_vector; + + typedef typename pretype::size_type Size; + + void test() { + const pretype& const_pre_vector = pre_vector; + BOOST_CHECK_EQUAL(real_vector.size(), pre_vector.size()); + BOOST_CHECK_EQUAL(real_vector.empty(), pre_vector.empty()); + for (Size s = 0; s < real_vector.size(); s++) { + BOOST_CHECK(real_vector[s] == pre_vector[s]); + BOOST_CHECK(&(pre_vector[s]) == &(pre_vector.begin()[s])); + BOOST_CHECK(&(pre_vector[s]) == &*(pre_vector.begin() + s)); + BOOST_CHECK(&(pre_vector[s]) == &*((pre_vector.end() + s) - real_vector.size())); + } + // BOOST_CHECK(realtype(pre_vector) == real_vector); + BOOST_CHECK(pretype(real_vector.begin(), real_vector.end()) == pre_vector); + BOOST_CHECK(pretype(pre_vector.begin(), pre_vector.end()) == pre_vector); + size_t pos = 0; + BOOST_FOREACH(const T& v, pre_vector) { + BOOST_CHECK(v == real_vector[pos++]); + } + BOOST_REVERSE_FOREACH(const T& v, pre_vector) { + BOOST_CHECK(v == real_vector[--pos]); + } + BOOST_FOREACH(const T& v, const_pre_vector) { + BOOST_CHECK(v == real_vector[pos++]); + } + BOOST_REVERSE_FOREACH(const T& v, const_pre_vector) { + BOOST_CHECK(v == real_vector[--pos]); + } + CDataStream ss1(SER_DISK, 0); + CDataStream ss2(SER_DISK, 0); + ss1 << real_vector; + ss2 << pre_vector; + BOOST_CHECK_EQUAL(ss1.size(), ss2.size()); + for (Size s = 0; s < ss1.size(); s++) { + BOOST_CHECK_EQUAL(ss1[s], ss2[s]); + } + } + +public: + void resize(Size s) { + real_vector.resize(s); + BOOST_CHECK_EQUAL(real_vector.size(), s); + pre_vector.resize(s); + BOOST_CHECK_EQUAL(pre_vector.size(), s); + test(); + } + + void reserve(Size s) { + real_vector.reserve(s); + BOOST_CHECK(real_vector.capacity() >= s); + pre_vector.reserve(s); + BOOST_CHECK(pre_vector.capacity() >= s); + test(); + } + + void insert(Size position, const T& value) { + real_vector.insert(real_vector.begin() + position, value); + pre_vector.insert(pre_vector.begin() + position, value); + test(); + } + + void insert(Size position, Size count, const T& value) { + real_vector.insert(real_vector.begin() + position, count, value); + pre_vector.insert(pre_vector.begin() + position, count, value); + test(); + } + + template + void insert_range(Size position, I first, I last) { + real_vector.insert(real_vector.begin() + position, first, last); + pre_vector.insert(pre_vector.begin() + position, first, last); + test(); + } + + void erase(Size position) { + real_vector.erase(real_vector.begin() + position); + pre_vector.erase(pre_vector.begin() + position); + test(); + } + + void erase(Size first, Size last) { + real_vector.erase(real_vector.begin() + first, real_vector.begin() + last); + pre_vector.erase(pre_vector.begin() + first, pre_vector.begin() + last); + test(); + } + + void update(Size pos, const T& value) { + real_vector[pos] = value; + pre_vector[pos] = value; + test(); + } + + void push_back(const T& value) { + real_vector.push_back(value); + pre_vector.push_back(value); + test(); + } + + void pop_back() { + real_vector.pop_back(); + pre_vector.pop_back(); + test(); + } + + void clear() { + real_vector.clear(); + pre_vector.clear(); + } + + void assign(Size n, const T& value) { + real_vector.assign(n, value); + pre_vector.assign(n, value); + } + + Size size() { + return real_vector.size(); + } + + Size capacity() { + return pre_vector.capacity(); + } + + void shrink_to_fit() { + pre_vector.shrink_to_fit(); + test(); + } +}; + +BOOST_AUTO_TEST_CASE(PrevectorTestInt) +{ + for (int j = 0; j < 64; j++) { + prevector_tester<8, int> test; + for (int i = 0; i < 2048; i++) { + int r = insecure_rand(); + if ((r % 4) == 0) { + test.insert(insecure_rand() % (test.size() + 1), insecure_rand()); + } + if (test.size() > 0 && ((r >> 2) % 4) == 1) { + test.erase(insecure_rand() % test.size()); + } + if (((r >> 4) % 8) == 2) { + int new_size = std::max(0, std::min(30, test.size() + (insecure_rand() % 5) - 2)); + test.resize(new_size); + } + if (((r >> 7) % 8) == 3) { + test.insert(insecure_rand() % (test.size() + 1), 1 + (insecure_rand() % 2), insecure_rand()); + } + if (((r >> 10) % 8) == 4) { + int del = std::min(test.size(), 1 + (insecure_rand() % 2)); + int beg = insecure_rand() % (test.size() + 1 - del); + test.erase(beg, beg + del); + } + if (((r >> 13) % 16) == 5) { + test.push_back(insecure_rand()); + } + if (test.size() > 0 && ((r >> 17) % 16) == 6) { + test.pop_back(); + } + if (((r >> 21) % 32) == 7) { + int values[4]; + int num = 1 + (insecure_rand() % 4); + for (int i = 0; i < num; i++) { + values[i] = insecure_rand(); + } + test.insert_range(insecure_rand() % (test.size() + 1), values, values + num); + } + if (((r >> 26) % 32) == 8) { + int del = std::min(test.size(), 1 + (insecure_rand() % 4)); + int beg = insecure_rand() % (test.size() + 1 - del); + test.erase(beg, beg + del); + } + r = insecure_rand(); + if (r % 32 == 9) { + test.reserve(insecure_rand() % 32); + } + if ((r >> 5) % 64 == 10) { + test.shrink_to_fit(); + } + if (test.size() > 0) { + test.update(insecure_rand() % test.size(), insecure_rand()); + } + if (((r >> 11) & 1024) == 11) { + test.clear(); + } + if (((r >> 21) & 512) == 12) { + test.assign(insecure_rand() % 32, insecure_rand()); + } + } + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/reverselock_tests.cpp b/src/test/reverselock_tests.cpp index e7e627ae0..8bdff9700 100644 --- a/src/test/reverselock_tests.cpp +++ b/src/test/reverselock_tests.cpp @@ -42,22 +42,18 @@ BOOST_AUTO_TEST_CASE(reverselock_errors) BOOST_CHECK(failed); BOOST_CHECK(!lock.owns_lock()); - // Make sure trying to lock a lock after it has been reverse locked fails - failed = false; - bool locked = false; + // Locking the original lock after it has been taken by a reverse lock + // makes no sense. Ensure that the original lock no longer owns the lock + // after giving it to a reverse one. lock.lock(); BOOST_CHECK(lock.owns_lock()); - - try { + { reverse_lock > rlock(lock); - lock.lock(); - locked = true; - } catch(...) { - failed = true; + BOOST_CHECK(!lock.owns_lock()); } - BOOST_CHECK(locked && failed); + BOOST_CHECK(failed); BOOST_CHECK(lock.owns_lock()); } diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 2a486f08e..d6309ca38 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -1,9 +1,9 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "rpcserver.h" -#include "rpcclient.h" +#include "rpc/server.h" +#include "rpc/client.h" #include "base58.h" #include "netbase.h" @@ -72,6 +72,7 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams) BOOST_CHECK_THROW(CallRPC("decoderawtransaction DEADBEEF"), runtime_error); string rawtx = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000"; BOOST_CHECK_NO_THROW(r = CallRPC(string("decoderawtransaction ")+rawtx)); + BOOST_CHECK_EQUAL(find_value(r.get_obj(), "size").get_int(), 193); BOOST_CHECK_EQUAL(find_value(r.get_obj(), "version").get_int(), 1); BOOST_CHECK_EQUAL(find_value(r.get_obj(), "locktime").get_int(), 0); BOOST_CHECK_THROW(r = CallRPC(string("decoderawtransaction ")+rawtx+" extra"), runtime_error); @@ -236,7 +237,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) UniValue o1 = ar[0].get_obj(); UniValue adr = find_value(o1, "address"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/32"); - BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove")));; + BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); ar = r.get_array(); BOOST_CHECK_EQUAL(ar.size(), 0); @@ -259,14 +260,14 @@ BOOST_AUTO_TEST_CASE(rpc_ban) adr = find_value(o1, "address"); banned_until = find_value(o1, "banned_until"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24"); - int64_t now = GetTime(); + int64_t now = GetTime(); BOOST_CHECK(banned_until.get_int64() > now); BOOST_CHECK(banned_until.get_int64()-now <= 200); // must throw an exception because 127.0.0.1 is in already banned suubnet range BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.1 add")), runtime_error); - BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0/24 remove")));; + BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0/24 remove"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned"))); ar = r.get_array(); BOOST_CHECK_EQUAL(ar.size(), 0); diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 2e652f76e..3443be209 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -1,9 +1,9 @@ -// Copyright (c) 2013-2014 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "rpcserver.h" -#include "rpcclient.h" +#include "rpc/server.h" +#include "rpc/client.h" #include "base58.h" #include "main.h" diff --git a/src/test/sanity_tests.cpp b/src/test/sanity_tests.cpp index f5f7f381d..51f9e9f39 100644 --- a/src/test/sanity_tests.cpp +++ b/src/test/sanity_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp index cb1a427db..9acd0e243 100644 --- a/src/test/scheduler_tests.cpp +++ b/src/test/scheduler_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -40,6 +40,7 @@ static void MicroSleep(uint64_t n) #endif } +#if 0 /* Disabled for now because there is a race condition issue in this test - see #6540 */ BOOST_AUTO_TEST_CASE(manythreads) { seed_insecure_rand(false); @@ -115,5 +116,6 @@ BOOST_AUTO_TEST_CASE(manythreads) } BOOST_CHECK_EQUAL(counterSum, 200); } +#endif BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index 16c9a4a86..28b85e8d2 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -25,7 +25,7 @@ using namespace std; static std::vector Serialize(const CScript& s) { - std::vector sSerialized(s); + std::vector sSerialized(s.begin(), s.end()); return sSerialized; } @@ -339,22 +339,13 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) // SignSignature doesn't know how to sign these. We're // not testing validating signatures, so just create // dummy signatures that DO include the correct P2SH scripts: - txTo.vin[3].scriptSig << OP_11 << OP_11 << static_cast >(oneAndTwo); - txTo.vin[4].scriptSig << static_cast >(fifteenSigops); + txTo.vin[3].scriptSig << OP_11 << OP_11 << vector(oneAndTwo.begin(), oneAndTwo.end()); + txTo.vin[4].scriptSig << vector(fifteenSigops.begin(), fifteenSigops.end()); BOOST_CHECK(::AreInputsStandard(txTo, coins)); // 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4] BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txTo, coins), 22U); - // Make sure adding crap to the scriptSigs makes them non-standard: - for (int i = 0; i < 3; i++) - { - CScript t = txTo.vin[i].scriptSig; - txTo.vin[i].scriptSig = (CScript() << 11) + t; - BOOST_CHECK(!::AreInputsStandard(txTo, coins)); - txTo.vin[i].scriptSig = t; - } - CMutableTransaction txToNonStd1; txToNonStd1.vout.resize(1); txToNonStd1.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID()); @@ -362,7 +353,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txToNonStd1.vin.resize(1); txToNonStd1.vin[0].prevout.n = 5; txToNonStd1.vin[0].prevout.hash = txFrom.GetHash(); - txToNonStd1.vin[0].scriptSig << static_cast >(sixteenSigops); + txToNonStd1.vin[0].scriptSig << vector(sixteenSigops.begin(), sixteenSigops.end()); BOOST_CHECK(!::AreInputsStandard(txToNonStd1, coins)); BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd1, coins), 16U); @@ -374,7 +365,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txToNonStd2.vin.resize(1); txToNonStd2.vin[0].prevout.n = 6; txToNonStd2.vin[0].prevout.hash = txFrom.GetHash(); - txToNonStd2.vin[0].scriptSig << static_cast >(twentySigops); + txToNonStd2.vin[0].scriptSig << vector(twentySigops.begin(), twentySigops.end()); BOOST_CHECK(!::AreInputsStandard(txToNonStd2, coins)); BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd2, coins), 20U); diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 882f9eb19..10175ebe8 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -260,7 +260,7 @@ public: TestBuilder& PushRedeem() { - DoPush(static_cast >(scriptPubKey)); + DoPush(std::vector(scriptPubKey.begin(), scriptPubKey.end())); return *this; } @@ -892,7 +892,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig); // dummy scriptSigCopy with placeholder, should always choose non-placeholder: - scriptSigCopy = CScript() << OP_0 << static_cast >(pkSingle); + scriptSigCopy = CScript() << OP_0 << vector(pkSingle.begin(), pkSingle.end()); combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); BOOST_CHECK(combined == scriptSig); combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, scriptSigCopy); @@ -985,10 +985,10 @@ BOOST_AUTO_TEST_CASE(script_IsPushOnly_on_invalid_scripts) BOOST_AUTO_TEST_CASE(script_GetScriptAsm) { - BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2, true)); - BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true)); - BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2)); - BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY)); + BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_NOP2, true)); + BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true)); + BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_NOP2)); + BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY)); string derSig("304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090"); string pubKey("03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2"); diff --git a/src/test/scriptnum10.h b/src/test/scriptnum10.h new file mode 100644 index 000000000..94dd58526 --- /dev/null +++ b/src/test/scriptnum10.h @@ -0,0 +1,183 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_TEST_SCRIPTNUM10_H +#define BITCOIN_TEST_SCRIPTNUM10_H + +#include +#include +#include +#include +#include +#include +#include "assert.h" + +class scriptnum10_error : public std::runtime_error +{ +public: + explicit scriptnum10_error(const std::string& str) : std::runtime_error(str) {} +}; + +class CScriptNum10 +{ +/** + * The ScriptNum implementation from Bitcoin Core 0.10.0, for cross-comparison. + */ +public: + + explicit CScriptNum10(const int64_t& n) + { + m_value = n; + } + + static const size_t nDefaultMaxNumSize = 4; + + explicit CScriptNum10(const std::vector& vch, bool fRequireMinimal, + const size_t nMaxNumSize = nDefaultMaxNumSize) + { + if (vch.size() > nMaxNumSize) { + throw scriptnum10_error("script number overflow"); + } + if (fRequireMinimal && vch.size() > 0) { + // Check that the number is encoded with the minimum possible + // number of bytes. + // + // If the most-significant-byte - excluding the sign bit - is zero + // then we're not minimal. Note how this test also rejects the + // negative-zero encoding, 0x80. + if ((vch.back() & 0x7f) == 0) { + // One exception: if there's more than one byte and the most + // significant bit of the second-most-significant-byte is set + // it would conflict with the sign bit. An example of this case + // is +-255, which encode to 0xff00 and 0xff80 respectively. + // (big-endian). + if (vch.size() <= 1 || (vch[vch.size() - 2] & 0x80) == 0) { + throw scriptnum10_error("non-minimally encoded script number"); + } + } + } + m_value = set_vch(vch); + } + + inline bool operator==(const int64_t& rhs) const { return m_value == rhs; } + inline bool operator!=(const int64_t& rhs) const { return m_value != rhs; } + inline bool operator<=(const int64_t& rhs) const { return m_value <= rhs; } + inline bool operator< (const int64_t& rhs) const { return m_value < rhs; } + inline bool operator>=(const int64_t& rhs) const { return m_value >= rhs; } + inline bool operator> (const int64_t& rhs) const { return m_value > rhs; } + + inline bool operator==(const CScriptNum10& rhs) const { return operator==(rhs.m_value); } + inline bool operator!=(const CScriptNum10& rhs) const { return operator!=(rhs.m_value); } + inline bool operator<=(const CScriptNum10& rhs) const { return operator<=(rhs.m_value); } + inline bool operator< (const CScriptNum10& rhs) const { return operator< (rhs.m_value); } + inline bool operator>=(const CScriptNum10& rhs) const { return operator>=(rhs.m_value); } + inline bool operator> (const CScriptNum10& rhs) const { return operator> (rhs.m_value); } + + inline CScriptNum10 operator+( const int64_t& rhs) const { return CScriptNum10(m_value + rhs);} + inline CScriptNum10 operator-( const int64_t& rhs) const { return CScriptNum10(m_value - rhs);} + inline CScriptNum10 operator+( const CScriptNum10& rhs) const { return operator+(rhs.m_value); } + inline CScriptNum10 operator-( const CScriptNum10& rhs) const { return operator-(rhs.m_value); } + + inline CScriptNum10& operator+=( const CScriptNum10& rhs) { return operator+=(rhs.m_value); } + inline CScriptNum10& operator-=( const CScriptNum10& rhs) { return operator-=(rhs.m_value); } + + inline CScriptNum10 operator-() const + { + assert(m_value != std::numeric_limits::min()); + return CScriptNum10(-m_value); + } + + inline CScriptNum10& operator=( const int64_t& rhs) + { + m_value = rhs; + return *this; + } + + inline CScriptNum10& operator+=( const int64_t& rhs) + { + assert(rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits::max() - rhs) || + (rhs < 0 && m_value >= std::numeric_limits::min() - rhs)); + m_value += rhs; + return *this; + } + + inline CScriptNum10& operator-=( const int64_t& rhs) + { + assert(rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits::min() + rhs) || + (rhs < 0 && m_value <= std::numeric_limits::max() + rhs)); + m_value -= rhs; + return *this; + } + + int getint() const + { + if (m_value > std::numeric_limits::max()) + return std::numeric_limits::max(); + else if (m_value < std::numeric_limits::min()) + return std::numeric_limits::min(); + return m_value; + } + + std::vector getvch() const + { + return serialize(m_value); + } + + static std::vector serialize(const int64_t& value) + { + if(value == 0) + return std::vector(); + + std::vector result; + const bool neg = value < 0; + uint64_t absvalue = neg ? -value : value; + + while(absvalue) + { + result.push_back(absvalue & 0xff); + absvalue >>= 8; + } + +// - If the most significant byte is >= 0x80 and the value is positive, push a +// new zero-byte to make the significant byte < 0x80 again. + +// - If the most significant byte is >= 0x80 and the value is negative, push a +// new 0x80 byte that will be popped off when converting to an integral. + +// - If the most significant byte is < 0x80 and the value is negative, add +// 0x80 to it, since it will be subtracted and interpreted as a negative when +// converting to an integral. + + if (result.back() & 0x80) + result.push_back(neg ? 0x80 : 0); + else if (neg) + result.back() |= 0x80; + + return result; + } + +private: + static int64_t set_vch(const std::vector& vch) + { + if (vch.empty()) + return 0; + + int64_t result = 0; + for (size_t i = 0; i != vch.size(); ++i) + result |= static_cast(vch[i]) << 8*i; + + // If the input vector's most significant byte is 0x80, remove it from + // the result's msb and return a negative. + if (vch.back() & 0x80) + return -((int64_t)(result & ~(0x80ULL << (8 * (vch.size() - 1))))); + + return result; + } + + int64_t m_value; +}; + + +#endif // BITCOIN_TEST_BIGNUM_H diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp index d95724dbe..6b6689c7d 100644 --- a/src/test/scriptnum_tests.cpp +++ b/src/test/scriptnum_tests.cpp @@ -1,8 +1,8 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "bignum.h" +#include "scriptnum10.h" #include "script/script.h" #include "test/test_bitcoin.h" @@ -16,45 +16,48 @@ static const int64_t values[] = \ { 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, UINT_MAX, LONG_MIN, LONG_MAX }; static const int64_t offsets[] = { 1, 0x79, 0x80, 0x81, 0xFF, 0x7FFF, 0x8000, 0xFFFF, 0x10000}; -static bool verify(const CBigNum& bignum, const CScriptNum& scriptnum) +static bool verify(const CScriptNum10& bignum, const CScriptNum& scriptnum) { return bignum.getvch() == scriptnum.getvch() && bignum.getint() == scriptnum.getint(); } static void CheckCreateVch(const int64_t& num) { - CBigNum bignum(num); + CScriptNum10 bignum(num); CScriptNum scriptnum(num); BOOST_CHECK(verify(bignum, scriptnum)); - CBigNum bignum2(bignum.getvch()); + std::vector vch = bignum.getvch(); + + CScriptNum10 bignum2(bignum.getvch(), false); + vch = scriptnum.getvch(); CScriptNum scriptnum2(scriptnum.getvch(), false); BOOST_CHECK(verify(bignum2, scriptnum2)); - CBigNum bignum3(scriptnum2.getvch()); + CScriptNum10 bignum3(scriptnum2.getvch(), false); CScriptNum scriptnum3(bignum2.getvch(), false); BOOST_CHECK(verify(bignum3, scriptnum3)); } static void CheckCreateInt(const int64_t& num) { - CBigNum bignum(num); + CScriptNum10 bignum(num); CScriptNum scriptnum(num); BOOST_CHECK(verify(bignum, scriptnum)); - BOOST_CHECK(verify(bignum.getint(), CScriptNum(scriptnum.getint()))); - BOOST_CHECK(verify(scriptnum.getint(), CScriptNum(bignum.getint()))); - BOOST_CHECK(verify(CBigNum(scriptnum.getint()).getint(), CScriptNum(CScriptNum(bignum.getint()).getint()))); + BOOST_CHECK(verify(CScriptNum10(bignum.getint()), CScriptNum(scriptnum.getint()))); + BOOST_CHECK(verify(CScriptNum10(scriptnum.getint()), CScriptNum(bignum.getint()))); + BOOST_CHECK(verify(CScriptNum10(CScriptNum10(scriptnum.getint()).getint()), CScriptNum(CScriptNum(bignum.getint()).getint()))); } static void CheckAdd(const int64_t& num1, const int64_t& num2) { - const CBigNum bignum1(num1); - const CBigNum bignum2(num2); + const CScriptNum10 bignum1(num1); + const CScriptNum10 bignum2(num2); const CScriptNum scriptnum1(num1); const CScriptNum scriptnum2(num2); - CBigNum bignum3(num1); - CBigNum bignum4(num1); + CScriptNum10 bignum3(num1); + CScriptNum10 bignum4(num1); CScriptNum scriptnum3(num1); CScriptNum scriptnum4(num1); @@ -71,7 +74,7 @@ static void CheckAdd(const int64_t& num1, const int64_t& num2) static void CheckNegate(const int64_t& num) { - const CBigNum bignum(num); + const CScriptNum10 bignum(num); const CScriptNum scriptnum(num); // -INT64_MIN is undefined @@ -81,8 +84,8 @@ static void CheckNegate(const int64_t& num) static void CheckSubtract(const int64_t& num1, const int64_t& num2) { - const CBigNum bignum1(num1); - const CBigNum bignum2(num2); + const CScriptNum10 bignum1(num1); + const CScriptNum10 bignum2(num2); const CScriptNum scriptnum1(num1); const CScriptNum scriptnum2(num2); bool invalid = false; @@ -107,8 +110,8 @@ static void CheckSubtract(const int64_t& num1, const int64_t& num2) static void CheckCompare(const int64_t& num1, const int64_t& num2) { - const CBigNum bignum1(num1); - const CBigNum bignum2(num2); + const CScriptNum10 bignum1(num1); + const CScriptNum10 bignum2(num2); const CScriptNum scriptnum1(num1); const CScriptNum scriptnum2(num2); @@ -149,7 +152,7 @@ static void RunCreate(const int64_t& num) CheckCreateVch(num); else { - BOOST_CHECK_THROW (CheckCreateVch(num), scriptnum_error); + BOOST_CHECK_THROW (CheckCreateVch(num), scriptnum10_error); } } diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index cc8f2b788..c0fd99aca 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 6fca64d5d..04c6fa962 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013 The Bitcoin Core developers +// Copyright (c) 2013-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index b26fed99f..a207fd921 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -20,7 +20,7 @@ using namespace std; static std::vector Serialize(const CScript& s) { - std::vector sSerialized(s); + std::vector sSerialized(s.begin(), s.end()); return sSerialized; } diff --git a/src/test/skiplist_tests.cpp b/src/test/skiplist_tests.cpp index a904e3862..f14b902fe 100644 --- a/src/test/skiplist_tests.cpp +++ b/src/test/skiplist_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp index 0ed8f363d..34f501e86 100644 --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 9a3517a27..0416d0c92 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -51,8 +51,10 @@ BasicTestingSetup::~BasicTestingSetup() TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName) { + const CChainParams& chainparams = Params(); #ifdef ENABLE_WALLET bitdb.MakeMock(); + walletRegisterRPCCommands(); #endif ClearDatadirCache(); pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); @@ -61,7 +63,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha pblocktree = new CBlockTreeDB(1 << 20, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); - InitBlockIndex(); + InitBlockIndex(chainparams); #ifdef ENABLE_WALLET bool fFirstRun; pwalletMain = new CWallet("wallet.dat"); @@ -143,8 +145,13 @@ TestChain100Setup::~TestChain100Setup() CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPool *pool) { - return CTxMemPoolEntry(tx, nFee, nTime, dPriority, nHeight, - pool ? pool->HasNoInputsOf(tx) : hadNoDependencies); + CTransaction txn(tx); + bool hasNoDependencies = pool ? pool->HasNoInputsOf(tx) : hadNoDependencies; + // Hack to assume either its completely dependent on other mempool txs or not at all + CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0; + + return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight, + hasNoDependencies, inChainValue, spendsCoinbase, sigOpCount); } void Shutdown(void* parg) diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index 815b22741..c62392088 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -1,3 +1,7 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #ifndef BITCOIN_TEST_TEST_BITCOIN_H #define BITCOIN_TEST_TEST_BITCOIN_H @@ -65,11 +69,13 @@ struct TestMemPoolEntryHelper double dPriority; unsigned int nHeight; bool hadNoDependencies; - + bool spendsCoinbase; + unsigned int sigOpCount; + TestMemPoolEntryHelper() : nFee(0), nTime(0), dPriority(0.0), nHeight(1), - hadNoDependencies(false) { } - + hadNoDependencies(false), spendsCoinbase(false), sigOpCount(1) { } + CTxMemPoolEntry FromTx(CMutableTransaction &tx, CTxMemPool *pool = NULL); // Change the default value @@ -78,5 +84,7 @@ struct TestMemPoolEntryHelper TestMemPoolEntryHelper &Priority(double _priority) { dPriority = _priority; return *this; } TestMemPoolEntryHelper &Height(unsigned int _height) { nHeight = _height; return *this; } TestMemPoolEntryHelper &HadNoDependencies(bool _hnd) { hadNoDependencies = _hnd; return *this; } + TestMemPoolEntryHelper &SpendsCoinbase(bool _flag) { spendsCoinbase = _flag; return *this; } + TestMemPoolEntryHelper &SigOps(unsigned int _sigops) { sigOpCount = _sigops; return *this; } }; #endif diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp index 887cfb476..1224ff845 100644 --- a/src/test/timedata_tests.cpp +++ b/src/test/timedata_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index fb0df1aff..c27f194b5 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -310,14 +310,6 @@ BOOST_AUTO_TEST_CASE(test_Get) BOOST_CHECK(AreInputsStandard(t1, coins)); BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50+21+22)*CENT); - - // Adding extra junk to the scriptSig should make it non-standard: - t1.vin[0].scriptSig << OP_11; - BOOST_CHECK(!AreInputsStandard(t1, coins)); - - // ... as should not having enough: - t1.vin[0].scriptSig = CScript(); - BOOST_CHECK(!AreInputsStandard(t1, coins)); } BOOST_AUTO_TEST_CASE(test_IsStandard) diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index 9b8e1c088..66be9d3d5 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index 426d296a9..da0a3d73e 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2013 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "arith_uint256.h" diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 945c1acbe..45d480c81 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -1,4 +1,5 @@ // Copyright 2014 BitPay, Inc. +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 1bbd497f7..01bc2032d 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2014 The Bitcoin Core developers +// Copyright (c) 2011-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/threadsafety.h b/src/threadsafety.h index d01c50abb..61e63dbc7 100644 --- a/src/threadsafety.h +++ b/src/threadsafety.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2012 The Bitcoin Core developers +// 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. diff --git a/src/timedata.cpp b/src/timedata.cpp index 2eaa9e4c8..4d2f8d1e3 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2014-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 08644f296..2c68526df 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -1,3 +1,7 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "torcontrol.h" #include "utilstrencodings.h" #include "net.h" @@ -79,7 +83,7 @@ public: /** * Connect to a Tor control port. * target is address of the form host:port. - * connected is the handler that is called when connection is succesfully established. + * connected is the handler that is called when connection is successfully established. * disconnected is a handler that is called when the connection is broken. * Return true on success. */ @@ -177,7 +181,7 @@ void TorControlConnection::eventcb(struct bufferevent *bev, short what, void *ct { TorControlConnection *self = (TorControlConnection*)ctx; if (what & BEV_EVENT_CONNECTED) { - LogPrint("tor", "tor: Succesfully connected!\n"); + LogPrint("tor", "tor: Successfully connected!\n"); self->connected(*self); } else if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) { if (what & BEV_EVENT_ERROR) @@ -303,7 +307,7 @@ static std::map ParseTorReplyMapping(const std::string /** Read full contents of a file and return them in a std::string. * Returns a pair . - * If an error occured, status will be false, otherwise status will be true and the data will be returned in string. + * If an error occurred, status will be false, otherwise status will be true and the data will be returned in string. * * @param maxsize Puts a maximum size limit on the file that is read. If the file is larger than this, truncated data * (with len > maxsize) will be returned. @@ -380,7 +384,7 @@ private: void authchallenge_cb(TorControlConnection& conn, const TorControlReply& reply); /** Callback for PROTOCOLINFO result */ void protocolinfo_cb(TorControlConnection& conn, const TorControlReply& reply); - /** Callback after succesful connection */ + /** Callback after successful connection */ void connected_cb(TorControlConnection& conn); /** Callback after connection lost or failed connection attempt */ void disconnected_cb(TorControlConnection& conn); @@ -419,7 +423,7 @@ TorController::~TorController() void TorController::add_onion_cb(TorControlConnection& conn, const TorControlReply& reply) { if (reply.code == 250) { - LogPrint("tor", "tor: ADD_ONION succesful\n"); + LogPrint("tor", "tor: ADD_ONION successful\n"); BOOST_FOREACH(const std::string &s, reply.lines) { std::map m = ParseTorReplyMapping(s); std::map::iterator i; @@ -448,7 +452,16 @@ void TorController::add_onion_cb(TorControlConnection& conn, const TorControlRep void TorController::auth_cb(TorControlConnection& conn, const TorControlReply& reply) { if (reply.code == 250) { - LogPrint("tor", "tor: Authentication succesful\n"); + LogPrint("tor", "tor: Authentication successful\n"); + + // Now that we know Tor is running setup the proxy for onion addresses + // if -onion isn't set to something else. + if (GetArg("-onion", "") == "") { + proxyType addrOnion = proxyType(CService("127.0.0.1", 9050), true); + SetProxy(NET_TOR, addrOnion); + SetReachable(NET_TOR); + } + // Finally - now create the service if (private_key.empty()) // No private key, generate one private_key = "NEW:BEST"; @@ -492,7 +505,7 @@ static std::vector ComputeResponse(const std::string &key, const std::v void TorController::authchallenge_cb(TorControlConnection& conn, const TorControlReply& reply) { if (reply.code == 250) { - LogPrint("tor", "tor: SAFECOOKIE authentication challenge succesful\n"); + LogPrint("tor", "tor: SAFECOOKIE authentication challenge successful\n"); std::pair l = SplitTorReplyLine(reply.lines[0]); if (l.first == "AUTHCHALLENGE") { std::map m = ParseTorReplyMapping(l.second); @@ -608,7 +621,9 @@ void TorController::disconnected_cb(TorControlConnection& conn) service = CService(); if (!reconnect) return; - LogPrintf("tor: Disconnected from Tor control port %s, trying to reconnect\n", target); + + LogPrint("tor", "tor: Not connected to Tor control port %s, trying to reconnect\n", target); + // Single-shot timer for reconnect. Use exponential backoff. struct timeval time = MillisToTimeval(int64_t(reconnect_timeout * 1000.0)); reconnect_ev = event_new(base, -1, 0, reconnect_cb, this); diff --git a/src/txdb.cpp b/src/txdb.cpp index cd76c0155..f99e11f26 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/txdb.h b/src/txdb.h index 586ab55d0..22e0c5704 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/txmempool.cpp b/src/txmempool.cpp index a772e7ade..f8e03c253 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -11,6 +11,7 @@ #include "main.h" #include "policy/fees.h" #include "streams.h" +#include "timedata.h" #include "util.h" #include "utilmoneystr.h" #include "utiltime.h" @@ -19,10 +20,12 @@ using namespace std; CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, - int64_t _nTime, double _dPriority, - unsigned int _nHeight, bool poolHasNoInputsOf): - tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight), - hadNoDependencies(poolHasNoInputsOf) + int64_t _nTime, double _entryPriority, unsigned int _entryHeight, + bool poolHasNoInputsOf, CAmount _inChainInputValue, + bool _spendsCoinbase, unsigned int _sigOps): + tx(_tx), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight), + hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue), + spendsCoinbase(_spendsCoinbase), sigOpCount(_sigOps) { nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); nModSize = tx.CalculateModifiedSize(nTxSize); @@ -30,7 +33,11 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, nCountWithDescendants = 1; nSizeWithDescendants = nTxSize; - nFeesWithDescendants = nFee; + nModFeesWithDescendants = nFee; + CAmount nValueIn = tx.GetValueOut()+nFee; + assert(inChainInputValue <= nValueIn); + + feeDelta = 0; } CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other) @@ -41,12 +48,19 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other) double CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const { - CAmount nValueIn = tx.GetValueOut()+nFee; - double deltaPriority = ((double)(currentHeight-nHeight)*nValueIn)/nModSize; - double dResult = dPriority + deltaPriority; + double deltaPriority = ((double)(currentHeight-entryHeight)*inChainInputValue)/nModSize; + double dResult = entryPriority + deltaPriority; + if (dResult < 0) // This should only happen if it was called with a height below entry height + dResult = 0; return dResult; } +void CTxMemPoolEntry::UpdateFeeDelta(int64_t newFeeDelta) +{ + nModFeesWithDescendants += newFeeDelta - feeDelta; + feeDelta = newFeeDelta; +} + // Update the given tx for any in-mempool descendants. // Assumes that setMemPoolChildren is correct for the given tx and all // descendants. @@ -101,7 +115,7 @@ bool CTxMemPool::UpdateForDescendants(txiter updateIt, int maxDescendantsToVisit BOOST_FOREACH(txiter cit, setAllDescendants) { if (!setExclude.count(cit->GetTx().GetHash())) { modifySize += cit->GetTxSize(); - modifyFee += cit->GetFee(); + modifyFee += cit->GetModifiedFee(); modifyCount++; cachedDescendants[updateIt].insert(cit); } @@ -231,7 +245,7 @@ void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, setEntries &setAncestors } const int64_t updateCount = (add ? 1 : -1); const int64_t updateSize = updateCount * it->GetTxSize(); - const CAmount updateFee = updateCount * it->GetFee(); + const CAmount updateFee = updateCount * it->GetModifiedFee(); BOOST_FOREACH(txiter ancestorIt, setAncestors) { mapTx.modify(ancestorIt, update_descendant_state(updateSize, updateFee, updateCount)); } @@ -291,7 +305,7 @@ void CTxMemPoolEntry::SetDirty() { nCountWithDescendants = 0; nSizeWithDescendants = nTxSize; - nFeesWithDescendants = nFee; + nModFeesWithDescendants = GetModifiedFee(); } void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount) @@ -299,8 +313,7 @@ void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t if (!IsDirty()) { nSizeWithDescendants += modifySize; assert(int64_t(nSizeWithDescendants) > 0); - nFeesWithDescendants += modifyFee; - assert(nFeesWithDescendants >= 0); + nModFeesWithDescendants += modifyFee; nCountWithDescendants += modifyCount; assert(int64_t(nCountWithDescendants) > 0); } @@ -359,6 +372,17 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, indexed_transaction_set::iterator newit = mapTx.insert(entry).first; mapLinks.insert(make_pair(newit, TxLinks())); + // Update transaction for any feeDelta created by PrioritiseTransaction + // TODO: refactor so that the fee delta is calculated before inserting + // into mapTx. + std::map >::const_iterator pos = mapDeltas.find(hash); + if (pos != mapDeltas.end()) { + const std::pair &deltas = pos->second; + if (deltas.second) { + mapTx.modify(newit, update_fee_delta(deltas.second)); + } + } + // Update cachedInnerUsage to include contained transaction's usage. // (When we update the entry for in-mempool parents, memory usage will be // further updated.) @@ -475,22 +499,26 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list& rem } } -void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight) +void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags) { - // Remove transactions spending a coinbase which are now immature + // Remove transactions spending a coinbase which are now immature and no-longer-final transactions LOCK(cs); list transactionsToRemove; for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { const CTransaction& tx = it->GetTx(); - BOOST_FOREACH(const CTxIn& txin, tx.vin) { - indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); - if (it2 != mapTx.end()) - continue; - const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); - if (nCheckFrequency != 0) assert(coins); - if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) { - transactionsToRemove.push_back(tx); - break; + if (!CheckFinalTx(tx, flags)) { + transactionsToRemove.push_back(tx); + } else if (it->GetSpendsCoinbase()) { + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); + if (it2 != mapTx.end()) + continue; + const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); + if (nCheckFrequency != 0) assert(coins); + if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) { + transactionsToRemove.push_back(tx); + break; + } } } } @@ -618,27 +646,24 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const CTxMemPool::setEntries setChildrenCheck; std::map::const_iterator iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0)); int64_t childSizes = 0; - CAmount childFees = 0; + CAmount childModFee = 0; for (; iter != mapNextTx.end() && iter->first.hash == it->GetTx().GetHash(); ++iter) { txiter childit = mapTx.find(iter->second.ptx->GetHash()); assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions if (setChildrenCheck.insert(childit).second) { childSizes += childit->GetTxSize(); - childFees += childit->GetFee(); + childModFee += childit->GetModifiedFee(); } } assert(setChildrenCheck == GetMemPoolChildren(it)); - // Also check to make sure size/fees is greater than sum with immediate children. + // Also check to make sure size is greater than sum with immediate children. // just a sanity check, not definitive that this calc is correct... - // also check that the size is less than the size of the entire mempool. if (!it->IsDirty()) { assert(it->GetSizeWithDescendants() >= childSizes + it->GetTxSize()); - assert(it->GetFeesWithDescendants() >= childFees + it->GetFee()); } else { assert(it->GetSizeWithDescendants() == it->GetTxSize()); - assert(it->GetFeesWithDescendants() == it->GetFee()); + assert(it->GetModFeesWithDescendants() == it->GetModifiedFee()); } - assert(it->GetFeesWithDescendants() >= 0); if (fDependsWait) waitingOnDependants.push_back(&(*it)); @@ -701,11 +726,21 @@ CFeeRate CTxMemPool::estimateFee(int nBlocks) const LOCK(cs); return minerPolicyEstimator->estimateFee(nBlocks); } +CFeeRate CTxMemPool::estimateSmartFee(int nBlocks, int *answerFoundAtBlocks) const +{ + LOCK(cs); + return minerPolicyEstimator->estimateSmartFee(nBlocks, answerFoundAtBlocks, *this); +} double CTxMemPool::estimatePriority(int nBlocks) const { LOCK(cs); return minerPolicyEstimator->estimatePriority(nBlocks); } +double CTxMemPool::estimateSmartPriority(int nBlocks, int *answerFoundAtBlocks) const +{ + LOCK(cs); + return minerPolicyEstimator->estimateSmartPriority(nBlocks, answerFoundAtBlocks, *this); +} bool CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const @@ -749,6 +784,18 @@ void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, std::pair &deltas = mapDeltas[hash]; deltas.first += dPriorityDelta; deltas.second += nFeeDelta; + txiter it = mapTx.find(hash); + if (it != mapTx.end()) { + mapTx.modify(it, update_fee_delta(deltas.second)); + // Now update all ancestors' modified fees with descendants + setEntries setAncestors; + uint64_t nNoLimit = std::numeric_limits::max(); + std::string dummy; + CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false); + BOOST_FOREACH(txiter ancestorIt, setAncestors) { + mapTx.modify(ancestorIt, update_descendant_state(0, nFeeDelta, 0)); + } + } } LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta)); } @@ -798,8 +845,8 @@ bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const { size_t CTxMemPool::DynamicMemoryUsage() const { LOCK(cs); - // Estimate the overhead of mapTx to be 9 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented. - return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 9 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + cachedInnerUsage; + // Estimate the overhead of mapTx to be 12 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented. + return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 12 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(mapLinks) + cachedInnerUsage; } void CTxMemPool::RemoveStaged(setEntries &stage) { @@ -904,7 +951,7 @@ void CTxMemPool::trackPackageRemoved(const CFeeRate& rate) { } } -void CTxMemPool::TrimToSize(size_t sizelimit) { +void CTxMemPool::TrimToSize(size_t sizelimit, std::vector* pvNoSpendsRemaining) { LOCK(cs); unsigned nTxnRemoved = 0; @@ -916,15 +963,33 @@ void CTxMemPool::TrimToSize(size_t sizelimit) { // "minimum reasonable fee rate" (ie some value under which we consider txn // to have 0 fee). This way, we don't allow txn to enter mempool with feerate // equal to txn which were removed with no block in between. - CFeeRate removed(it->GetFeesWithDescendants(), it->GetSizeWithDescendants()); + CFeeRate removed(it->GetModFeesWithDescendants(), it->GetSizeWithDescendants()); removed += minReasonableRelayFee; trackPackageRemoved(removed); maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed); setEntries stage; CalculateDescendants(mapTx.project<0>(it), stage); - RemoveStaged(stage); nTxnRemoved += stage.size(); + + std::vector txn; + if (pvNoSpendsRemaining) { + txn.reserve(stage.size()); + BOOST_FOREACH(txiter it, stage) + txn.push_back(it->GetTx()); + } + RemoveStaged(stage); + if (pvNoSpendsRemaining) { + BOOST_FOREACH(const CTransaction& tx, txn) { + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + if (exists(txin.prevout.hash)) + continue; + std::map::iterator it = mapNextTx.lower_bound(COutPoint(txin.prevout.hash, 0)); + if (it == mapNextTx.end() || it->first.hash != txin.prevout.hash) + pvNoSpendsRemaining->push_back(txin.prevout.hash); + } + } + } } if (maxFeeRateRemoved > CFeeRate(0)) diff --git a/src/txmempool.h b/src/txmempool.h index 7b5843a8d..386cb26d2 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -44,12 +44,12 @@ class CTxMemPool; * ("descendant" transactions). * * When a new entry is added to the mempool, we update the descendant state - * (nCountWithDescendants, nSizeWithDescendants, and nFeesWithDescendants) for + * (nCountWithDescendants, nSizeWithDescendants, and nModFeesWithDescendants) for * all ancestors of the newly added transaction. * * If updating the descendant state is skipped, we can mark the entry as - * "dirty", and set nSizeWithDescendants/nFeesWithDescendants to equal nTxSize/ - * nTxFee. (This can potentially happen during a reorg, where we limit the + * "dirty", and set nSizeWithDescendants/nModFeesWithDescendants to equal nTxSize/ + * nFee+feeDelta. (This can potentially happen during a reorg, where we limit the * amount of work we're willing to do to avoid consuming too much CPU.) * */ @@ -63,35 +63,50 @@ private: size_t nModSize; //! ... and modified size for priority size_t nUsageSize; //! ... and total memory usage int64_t nTime; //! Local time when entering the mempool - double dPriority; //! Priority when entering the mempool - unsigned int nHeight; //! Chain height when entering the mempool + double entryPriority; //! Priority when entering the mempool + unsigned int entryHeight; //! Chain height when entering the mempool bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool + CAmount inChainInputValue; //! Sum of all txin values that are already in blockchain + bool spendsCoinbase; //! keep track of transactions that spend a coinbase + unsigned int sigOpCount; //! Legacy sig ops plus P2SH sig op count + int64_t feeDelta; //! Used for determining the priority of the transaction for mining in a block // Information about descendants of this transaction that are in the // mempool; if we remove this transaction we must remove all of these // descendants as well. if nCountWithDescendants is 0, treat this entry as - // dirty, and nSizeWithDescendants and nFeesWithDescendants will not be + // dirty, and nSizeWithDescendants and nModFeesWithDescendants will not be // correct. uint64_t nCountWithDescendants; //! number of descendant transactions uint64_t nSizeWithDescendants; //! ... and size - CAmount nFeesWithDescendants; //! ... and total fees (all including us) + CAmount nModFeesWithDescendants; //! ... and total fees (all including us) public: CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, - int64_t _nTime, double _dPriority, unsigned int _nHeight, bool poolHasNoInputsOf = false); + int64_t _nTime, double _entryPriority, unsigned int _entryHeight, + bool poolHasNoInputsOf, CAmount _inChainInputValue, bool spendsCoinbase, + unsigned int nSigOps); CTxMemPoolEntry(const CTxMemPoolEntry& other); const CTransaction& GetTx() const { return this->tx; } + /** + * Fast calculation of lower bound of current priority as update + * from entry priority. Only inputs that were originally in-chain will age. + */ double GetPriority(unsigned int currentHeight) const; const CAmount& GetFee() const { return nFee; } size_t GetTxSize() const { return nTxSize; } int64_t GetTime() const { return nTime; } - unsigned int GetHeight() const { return nHeight; } + unsigned int GetHeight() const { return entryHeight; } bool WasClearAtEntry() const { return hadNoDependencies; } + unsigned int GetSigOpCount() const { return sigOpCount; } + int64_t GetModifiedFee() const { return nFee + feeDelta; } size_t DynamicMemoryUsage() const { return nUsageSize; } // Adjusts the descendant state, if this entry is not dirty. void UpdateState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount); + // Updates the fee delta used for mining priority score, and the + // modified fees with descendants. + void UpdateFeeDelta(int64_t feeDelta); /** We can set the entry to be dirty if doing the full calculation of in- * mempool descendants will be too expensive, which can potentially happen @@ -102,7 +117,9 @@ public: uint64_t GetCountWithDescendants() const { return nCountWithDescendants; } uint64_t GetSizeWithDescendants() const { return nSizeWithDescendants; } - CAmount GetFeesWithDescendants() const { return nFeesWithDescendants; } + CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; } + + bool GetSpendsCoinbase() const { return spendsCoinbase; } }; // Helpers for modifying CTxMemPool::mapTx, which is a boost multi_index. @@ -127,6 +144,16 @@ struct set_dirty { e.SetDirty(); } }; +struct update_fee_delta +{ + update_fee_delta(int64_t _feeDelta) : feeDelta(_feeDelta) { } + + void operator() (CTxMemPoolEntry &e) { e.UpdateFeeDelta(feeDelta); } + +private: + int64_t feeDelta; +}; + // extracts a TxMemPoolEntry's transaction hash struct mempoolentry_txid { @@ -137,27 +164,27 @@ struct mempoolentry_txid } }; -/** \class CompareTxMemPoolEntryByFee +/** \class CompareTxMemPoolEntryByDescendantScore * - * Sort an entry by max(feerate of entry's tx, feerate with all descendants). + * Sort an entry by max(score/size of entry's tx, score/size with all descendants). */ -class CompareTxMemPoolEntryByFee +class CompareTxMemPoolEntryByDescendantScore { public: bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) { - bool fUseADescendants = UseDescendantFeeRate(a); - bool fUseBDescendants = UseDescendantFeeRate(b); + bool fUseADescendants = UseDescendantScore(a); + bool fUseBDescendants = UseDescendantScore(b); - double aFees = fUseADescendants ? a.GetFeesWithDescendants() : a.GetFee(); + double aModFee = fUseADescendants ? a.GetModFeesWithDescendants() : a.GetModifiedFee(); double aSize = fUseADescendants ? a.GetSizeWithDescendants() : a.GetTxSize(); - double bFees = fUseBDescendants ? b.GetFeesWithDescendants() : b.GetFee(); + double bModFee = fUseBDescendants ? b.GetModFeesWithDescendants() : b.GetModifiedFee(); double bSize = fUseBDescendants ? b.GetSizeWithDescendants() : b.GetTxSize(); // Avoid division by rewriting (a/b > c/d) as (a*d > c*b). - double f1 = aFees * bSize; - double f2 = aSize * bFees; + double f1 = aModFee * bSize; + double f2 = aSize * bModFee; if (f1 == f2) { return a.GetTime() >= b.GetTime(); @@ -165,15 +192,33 @@ public: return f1 < f2; } - // Calculate which feerate to use for an entry (avoiding division). - bool UseDescendantFeeRate(const CTxMemPoolEntry &a) + // Calculate which score to use for an entry (avoiding division). + bool UseDescendantScore(const CTxMemPoolEntry &a) { - double f1 = (double)a.GetFee() * a.GetSizeWithDescendants(); - double f2 = (double)a.GetFeesWithDescendants() * a.GetTxSize(); + double f1 = (double)a.GetModifiedFee() * a.GetSizeWithDescendants(); + double f2 = (double)a.GetModFeesWithDescendants() * a.GetTxSize(); return f2 > f1; } }; +/** \class CompareTxMemPoolEntryByScore + * + * Sort by score of entry ((fee+delta)/size) in descending order + */ +class CompareTxMemPoolEntryByScore +{ +public: + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + { + double f1 = (double)a.GetModifiedFee() * b.GetTxSize(); + double f2 = (double)b.GetModifiedFee() * a.GetTxSize(); + if (f1 == f2) { + return b.GetTx().GetHash() < a.GetTx().GetHash(); + } + return f1 > f2; + } +}; + class CompareTxMemPoolEntryByEntryTime { public: @@ -211,10 +256,11 @@ public: * * CTxMemPool::mapTx, and CTxMemPoolEntry bookkeeping: * - * mapTx is a boost::multi_index that sorts the mempool on 3 criteria: + * mapTx is a boost::multi_index that sorts the mempool on 4 criteria: * - transaction hash * - feerate [we use max(feerate of tx, feerate of tx with all descendants)] * - time in mempool + * - mining score (feerate modified by any fee deltas from PrioritiseTransaction) * * Note: the term "descendant" refers to in-mempool transactions that depend on * this one, while "ancestor" refers to in-mempool transactions that a given @@ -305,12 +351,17 @@ public: // sorted by fee rate boost::multi_index::ordered_non_unique< boost::multi_index::identity, - CompareTxMemPoolEntryByFee + CompareTxMemPoolEntryByDescendantScore >, // sorted by entry time boost::multi_index::ordered_non_unique< boost::multi_index::identity, CompareTxMemPoolEntryByEntryTime + >, + // sorted by score (for mining prioritization) + boost::multi_index::ordered_unique< + boost::multi_index::identity, + CompareTxMemPoolEntryByScore > > > indexed_transaction_set; @@ -325,6 +376,8 @@ public: }; typedef std::set setEntries; + const setEntries & GetMemPoolParents(txiter entry) const; + const setEntries & GetMemPoolChildren(txiter entry) const; private: typedef std::map cacheMap; @@ -336,8 +389,6 @@ private: typedef std::map txlinksMap; txlinksMap mapLinks; - const setEntries & GetMemPoolParents(txiter entry) const; - const setEntries & GetMemPoolChildren(txiter entry) const; void UpdateParent(txiter entry, txiter parent, bool add); void UpdateChild(txiter entry, txiter child, bool add); @@ -370,7 +421,7 @@ public: bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate = true); void remove(const CTransaction &tx, std::list& removed, bool fRecursive = false); - void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight); + void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags); void removeConflicts(const CTransaction &tx, std::list& removed); void removeForBlock(const std::vector& vtx, unsigned int nBlockHeight, std::list& conflicts, bool fCurrentEstimate = true); @@ -420,6 +471,11 @@ public: */ bool CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents = true); + /** Populate setDescendants with all in-mempool descendants of hash. + * Assumes that setDescendants includes all in-mempool descendants of anything + * already in it. */ + void CalculateDescendants(txiter it, setEntries &setDescendants); + /** The minimum fee to get into the mempool, which may itself not be enough * for larger-sized transactions. * The minReasonableRelayFee constructor arg is used to bound the time it @@ -428,8 +484,11 @@ public: */ CFeeRate GetMinFee(size_t sizelimit) const; - /** Remove transactions from the mempool until its dynamic size is <= sizelimit. */ - void TrimToSize(size_t sizelimit); + /** Remove transactions from the mempool until its dynamic size is <= sizelimit. + * pvNoSpendsRemaining, if set, will be populated with the list of transactions + * which are not in mempool which no longer have any spends in this mempool. + */ + void TrimToSize(size_t sizelimit, std::vector* pvNoSpendsRemaining=NULL); /** Expire all transaction (and their dependencies) in the mempool older than time. Return the number of removed transactions. */ int Expire(int64_t time); @@ -454,9 +513,21 @@ public: bool lookup(uint256 hash, CTransaction& result) const; + /** Estimate fee rate needed to get into the next nBlocks + * If no answer can be given at nBlocks, return an estimate + * at the lowest number of blocks where one can be given + */ + CFeeRate estimateSmartFee(int nBlocks, int *answerFoundAtBlocks = NULL) const; + /** Estimate fee rate needed to get into the next nBlocks */ CFeeRate estimateFee(int nBlocks) const; + /** Estimate priority needed to get into the next nBlocks + * If no answer can be given at nBlocks, return an estimate + * at the lowest number of blocks where one can be given + */ + double estimateSmartPriority(int nBlocks, int *answerFoundAtBlocks = NULL) const; + /** Estimate priority needed to get into the next nBlocks */ double estimatePriority(int nBlocks) const; @@ -493,10 +564,6 @@ private: void UpdateForRemoveFromMempool(const setEntries &entriesToRemove); /** Sever link between specified transaction and direct children. */ void UpdateChildrenForRemoval(txiter entry); - /** Populate setDescendants with all in-mempool descendants of hash. - * Assumes that setDescendants includes all in-mempool descendants of anything - * already in it. */ - void CalculateDescendants(txiter it, setEntries &setDescendants); /** Before calling removeUnchecked for a given transaction, * UpdateForRemoveFromMempool must be called on the entire (dependent) set @@ -524,4 +591,17 @@ public: bool HaveCoins(const uint256 &txid) const; }; +// We want to sort transactions by coin age priority +typedef std::pair TxCoinAgePriority; + +struct TxCoinAgePriorityCompare +{ + bool operator()(const TxCoinAgePriority& a, const TxCoinAgePriority& b) + { + if (a.first == b.first) + return CompareTxMemPoolEntryByScore()(*(b.second), *(a.second)); //Reverse order to make sort less than + return a.first < b.first; + } +}; + #endif // BITCOIN_TXMEMPOOL_H diff --git a/src/ui_interface.h b/src/ui_interface.h index e40247993..967d24327 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2012 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,6 +15,7 @@ class CBasicKeyStore; class CWallet; class uint256; +class CBlockIndex; /** General change type (added, updated, removed). */ enum ChangeType @@ -94,7 +95,7 @@ public: boost::signals2::signal ShowProgress; /** New block has been accepted */ - boost::signals2::signal NotifyBlockTip; + boost::signals2::signal NotifyBlockTip; /** Banlist did change. */ boost::signals2::signal BannedListChanged; diff --git a/src/uint256.cpp b/src/uint256.cpp index 25148808c..c58c88bf4 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/uint256.h b/src/uint256.h index 6d016ab16..4495000f2 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,6 +12,7 @@ #include #include #include +#include "crypto/common.h" /** Template base class for fixed-sized opaque blobs. */ template @@ -119,13 +120,10 @@ public: * used when the contents are considered uniformly random. It is not appropriate * when the value can easily be influenced from outside as e.g. a network adversary could * provide values to trigger worst-case behavior. - * @note The result of this function is not stable between little and big endian. */ uint64_t GetCheapHash() const { - uint64_t result; - memcpy((void*)&result, (void*)data, 8); - return result; + return ReadLE64(data); } /** A more secure, salted hash function. diff --git a/src/undo.h b/src/undo.h index 1c4ed95bf..d4fc84c90 100644 --- a/src/undo.h +++ b/src/undo.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// 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. diff --git a/src/univalue/.gitignore b/src/univalue/.gitignore index a7a2ca919..19e42f814 100644 --- a/src/univalue/.gitignore +++ b/src/univalue/.gitignore @@ -18,6 +18,7 @@ univalue-config.h* test-driver libtool ltmain.sh +test-suite.log *.a *.la diff --git a/src/univalue/.travis.yml b/src/univalue/.travis.yml index af632c78d..d318d9cc8 100644 --- a/src/univalue/.travis.yml +++ b/src/univalue/.travis.yml @@ -36,7 +36,7 @@ script: - ./configure --cache-file=config.cache $UNIVALUE_CONFIG_ALL $UNIVALUE_CONFIG || ( cat config.log && false) - make -s $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL ; false ) - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib - - if [ "$RUN_TESTS" = "true" ]; then make check; fi + - if [ "$RUN_TESTS" = "true" ]; then make $MAKEJOBS distcheck; fi matrix: fast_finish: true diff --git a/src/univalue/Makefile.am b/src/univalue/Makefile.am index df9e66229..34fe9e3f1 100644 --- a/src/univalue/Makefile.am +++ b/src/univalue/Makefile.am @@ -70,6 +70,9 @@ TEST_FILES = \ $(TEST_DATA_DIR)/fail32.json \ $(TEST_DATA_DIR)/fail33.json \ $(TEST_DATA_DIR)/fail34.json \ + $(TEST_DATA_DIR)/fail35.json \ + $(TEST_DATA_DIR)/fail36.json \ + $(TEST_DATA_DIR)/fail37.json \ $(TEST_DATA_DIR)/fail3.json \ $(TEST_DATA_DIR)/fail4.json \ $(TEST_DATA_DIR)/fail5.json \ @@ -79,6 +82,7 @@ TEST_FILES = \ $(TEST_DATA_DIR)/fail9.json \ $(TEST_DATA_DIR)/pass1.json \ $(TEST_DATA_DIR)/pass2.json \ - $(TEST_DATA_DIR)/pass3.json + $(TEST_DATA_DIR)/pass3.json \ + $(TEST_DATA_DIR)/round1.json EXTRA_DIST=$(TEST_FILES) $(GEN_SRCS) diff --git a/src/univalue/configure.ac b/src/univalue/configure.ac index 6cd951622..0515b632b 100644 --- a/src/univalue/configure.ac +++ b/src/univalue/configure.ac @@ -14,7 +14,7 @@ m4_define([libunivalue_age], [m4_eval(libunivalue_binary_age - libunivalue_inter m4_define([libunivalue_version], [libunivalue_major_version().libunivalue_minor_version().libunivalue_micro_version()libunivalue_extraversion()]) -AC_INIT([univalue], [1.0.0], +AC_INIT([univalue], [1.0.1], [http://github.com/jgarzik/univalue/]) dnl make the compilation flags quiet unless V=1 is used diff --git a/src/univalue/gen/gen.cpp b/src/univalue/gen/gen.cpp index 5e5a4d4ae..17f361941 100644 --- a/src/univalue/gen/gen.cpp +++ b/src/univalue/gen/gen.cpp @@ -8,7 +8,6 @@ // $ ./gen > univalue_escapes.h // -#include #include #include #include "univalue.h" @@ -16,10 +15,17 @@ using namespace std; static bool initEscapes; -static const char *escapes[256]; +static std::string escapes[256]; static void initJsonEscape() { + // Escape all lower control characters (some get overridden with smaller sequences below) + for (int ch=0x00; ch<0x20; ++ch) { + char tmpbuf[20]; + snprintf(tmpbuf, sizeof(tmpbuf), "\\u%04x", ch); + escapes[ch] = std::string(tmpbuf); + } + escapes[(int)'"'] = "\\\""; escapes[(int)'\\'] = "\\\\"; escapes[(int)'\b'] = "\\b"; @@ -27,6 +33,7 @@ static void initJsonEscape() escapes[(int)'\n'] = "\\n"; escapes[(int)'\r'] = "\\r"; escapes[(int)'\t'] = "\\t"; + escapes[(int)'\x7f'] = "\\u007f"; // U+007F DELETE initEscapes = true; } @@ -39,13 +46,13 @@ static void outputEscape() "static const char *escapes[256] = {\n"); for (unsigned int i = 0; i < 256; i++) { - if (!escapes[i]) { + if (escapes[i].empty()) { printf("\tNULL,\n"); } else { printf("\t\""); unsigned int si; - for (si = 0; si < strlen(escapes[i]); si++) { + for (si = 0; si < escapes[i].size(); si++) { char ch = escapes[i][si]; switch (ch) { case '"': diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h index ac0511601..8428b1c68 100644 --- a/src/univalue/include/univalue.h +++ b/src/univalue/include/univalue.h @@ -243,8 +243,41 @@ extern enum jtokentype getJsonToken(std::string& tokenVal, unsigned int& consumed, const char *raw); extern const char *uvTypeName(UniValue::VType t); +static inline bool jsonTokenIsValue(enum jtokentype jtt) +{ + switch (jtt) { + case JTOK_KW_NULL: + case JTOK_KW_TRUE: + case JTOK_KW_FALSE: + case JTOK_NUMBER: + case JTOK_STRING: + return true; + + default: + return false; + } + + // not reached +} + +static inline bool json_isspace(int ch) +{ + switch (ch) { + case 0x20: + case 0x09: + case 0x0a: + case 0x0d: + return true; + + default: + return false; + } + + // not reached +} + extern const UniValue NullUniValue; const UniValue& find_value( const UniValue& obj, const std::string& name); -#endif // __UNIVALUE_H__ \ No newline at end of file +#endif // __UNIVALUE_H__ diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp index 883e8651f..0076d6678 100644 --- a/src/univalue/lib/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -4,7 +4,6 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include -#include #include #include #include @@ -21,7 +20,7 @@ static bool ParsePrechecks(const std::string& str) { if (str.empty()) // No empty string allowed return false; - if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size()-1]))) // No padding allowed + if (str.size() >= 1 && (json_isspace(str[0]) || json_isspace(str[str.size()-1]))) // No padding allowed return false; if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed return false; @@ -210,7 +209,7 @@ bool UniValue::pushKVs(const UniValue& obj) for (unsigned int i = 0; i < obj.keys.size(); i++) { keys.push_back(obj.keys[i]); - values.push_back(obj.values[i]); + values.push_back(obj.values.at(i)); } return true; @@ -234,7 +233,7 @@ bool UniValue::checkObject(const std::map& t) if (idx < 0) return false; - if (values[idx].getType() != it->second) + if (values.at(idx).getType() != it->second) return false; } @@ -250,7 +249,7 @@ const UniValue& UniValue::operator[](const std::string& key) const if (index < 0) return NullUniValue; - return values[index]; + return values.at(index); } const UniValue& UniValue::operator[](unsigned int index) const @@ -260,7 +259,7 @@ const UniValue& UniValue::operator[](unsigned int index) const if (index >= values.size()) return NullUniValue; - return values[index]; + return values.at(index); } const char *uvTypeName(UniValue::VType t) @@ -278,15 +277,11 @@ const char *uvTypeName(UniValue::VType t) return NULL; } -const UniValue& find_value( const UniValue& obj, const std::string& name) +const UniValue& find_value(const UniValue& obj, const std::string& name) { for (unsigned int i = 0; i < obj.keys.size(); i++) - { - if( obj.keys[i] == name ) - { - return obj.values[i]; - } - } + if (obj.keys[i] == name) + return obj.values.at(i); return NullUniValue; } diff --git a/src/univalue/lib/univalue_escapes.h b/src/univalue/lib/univalue_escapes.h index 4133b24ca..74596aab6 100644 --- a/src/univalue/lib/univalue_escapes.h +++ b/src/univalue/lib/univalue_escapes.h @@ -2,38 +2,38 @@ #ifndef BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H #define BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H static const char *escapes[256] = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + "\\u0000", + "\\u0001", + "\\u0002", + "\\u0003", + "\\u0004", + "\\u0005", + "\\u0006", + "\\u0007", "\\b", "\\t", "\\n", - NULL, + "\\u000b", "\\f", "\\r", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + "\\u000e", + "\\u000f", + "\\u0010", + "\\u0011", + "\\u0012", + "\\u0013", + "\\u0014", + "\\u0015", + "\\u0016", + "\\u0017", + "\\u0018", + "\\u0019", + "\\u001a", + "\\u001b", + "\\u001c", + "\\u001d", + "\\u001e", + "\\u001f", NULL, NULL, "\\\"", @@ -129,7 +129,7 @@ static const char *escapes[256] = { NULL, NULL, NULL, - NULL, + "\\u007f", NULL, NULL, NULL, diff --git a/src/univalue/lib/univalue_read.cpp b/src/univalue/lib/univalue_read.cpp index 64591234c..c7516b962 100644 --- a/src/univalue/lib/univalue_read.cpp +++ b/src/univalue/lib/univalue_read.cpp @@ -9,6 +9,11 @@ using namespace std; +static bool json_isdigit(int ch) +{ + return ((ch >= '0') && (ch <= '9')); +} + // convert hexadecimal string to unsigned integer static const char *hatoui(const char *first, const char *last, unsigned int& out) @@ -17,7 +22,7 @@ static const char *hatoui(const char *first, const char *last, for (; first != last; ++first) { int digit; - if (isdigit(*first)) + if (json_isdigit(*first)) digit = *first - '0'; else if (*first >= 'a' && *first <= 'f') @@ -44,7 +49,7 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, const char *rawStart = raw; - while ((*raw) && (isspace(*raw))) // skip whitespace + while ((*raw) && (json_isspace(*raw))) // skip whitespace raw++; switch (*raw) { @@ -113,18 +118,18 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, const char *first = raw; const char *firstDigit = first; - if (!isdigit(*firstDigit)) + if (!json_isdigit(*firstDigit)) firstDigit++; - if ((*firstDigit == '0') && isdigit(firstDigit[1])) + if ((*firstDigit == '0') && json_isdigit(firstDigit[1])) return JTOK_ERR; numStr += *raw; // copy first char raw++; - if ((*first == '-') && (!isdigit(*raw))) + if ((*first == '-') && (!json_isdigit(*raw))) return JTOK_ERR; - while ((*raw) && isdigit(*raw)) { // copy digits + while ((*raw) && json_isdigit(*raw)) { // copy digits numStr += *raw; raw++; } @@ -134,9 +139,9 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, numStr += *raw; // copy . raw++; - if (!isdigit(*raw)) + if (!json_isdigit(*raw)) return JTOK_ERR; - while ((*raw) && isdigit(*raw)) { // copy digits + while ((*raw) && json_isdigit(*raw)) { // copy digits numStr += *raw; raw++; } @@ -152,9 +157,9 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, raw++; } - if (!isdigit(*raw)) + if (!json_isdigit(*raw)) return JTOK_ERR; - while ((*raw) && isdigit(*raw)) { // copy digits + while ((*raw) && json_isdigit(*raw)) { // copy digits numStr += *raw; raw++; } @@ -236,12 +241,23 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, } } +enum expect_bits { + EXP_OBJ_NAME = (1U << 0), + EXP_COLON = (1U << 1), + EXP_ARR_VALUE = (1U << 2), + EXP_VALUE = (1U << 3), + EXP_NOT_VALUE = (1U << 4), +}; + +#define expect(bit) (expectMask & (EXP_##bit)) +#define setExpect(bit) (expectMask |= EXP_##bit) +#define clearExpect(bit) (expectMask &= ~EXP_##bit) + bool UniValue::read(const char *raw) { clear(); - bool expectName = false; - bool expectColon = false; + uint32_t expectMask = 0; vector stack; string tokenVal; @@ -256,6 +272,41 @@ bool UniValue::read(const char *raw) return false; raw += consumed; + bool isValueOpen = jsonTokenIsValue(tok) || + tok == JTOK_OBJ_OPEN || tok == JTOK_ARR_OPEN; + + if (expect(VALUE)) { + if (!isValueOpen) + return false; + clearExpect(VALUE); + + } else if (expect(ARR_VALUE)) { + bool isArrValue = isValueOpen || (tok == JTOK_ARR_CLOSE); + if (!isArrValue) + return false; + + clearExpect(ARR_VALUE); + + } else if (expect(OBJ_NAME)) { + bool isObjName = (tok == JTOK_OBJ_CLOSE || tok == JTOK_STRING); + if (!isObjName) + return false; + + } else if (expect(COLON)) { + if (tok != JTOK_COLON) + return false; + clearExpect(COLON); + + } else if (!expect(COLON) && (tok == JTOK_COLON)) { + return false; + } + + if (expect(NOT_VALUE)) { + if (isValueOpen) + return false; + clearExpect(NOT_VALUE); + } + switch (tok) { case JTOK_OBJ_OPEN: @@ -277,13 +328,15 @@ bool UniValue::read(const char *raw) } if (utyp == VOBJ) - expectName = true; + setExpect(OBJ_NAME); + else + setExpect(ARR_VALUE); break; } case JTOK_OBJ_CLOSE: case JTOK_ARR_CLOSE: { - if (!stack.size() || expectColon || (last_tok == JTOK_COMMA)) + if (!stack.size() || (last_tok == JTOK_COMMA)) return false; VType utyp = (tok == JTOK_OBJ_CLOSE ? VOBJ : VARR); @@ -292,37 +345,40 @@ bool UniValue::read(const char *raw) return false; stack.pop_back(); - expectName = false; + clearExpect(OBJ_NAME); + setExpect(NOT_VALUE); break; } case JTOK_COLON: { - if (!stack.size() || expectName || !expectColon) + if (!stack.size()) return false; UniValue *top = stack.back(); if (top->getType() != VOBJ) return false; - expectColon = false; + setExpect(VALUE); break; } case JTOK_COMMA: { - if (!stack.size() || expectName || expectColon || + if (!stack.size() || (last_tok == JTOK_COMMA) || (last_tok == JTOK_ARR_OPEN)) return false; UniValue *top = stack.back(); if (top->getType() == VOBJ) - expectName = true; + setExpect(OBJ_NAME); + else + setExpect(ARR_VALUE); break; } case JTOK_KW_NULL: case JTOK_KW_TRUE: case JTOK_KW_FALSE: { - if (!stack.size() || expectName || expectColon) + if (!stack.size()) return false; UniValue tmpVal; @@ -342,17 +398,19 @@ bool UniValue::read(const char *raw) UniValue *top = stack.back(); top->values.push_back(tmpVal); + setExpect(NOT_VALUE); break; } case JTOK_NUMBER: { - if (!stack.size() || expectName || expectColon) + if (!stack.size()) return false; UniValue tmpVal(VNUM, tokenVal); UniValue *top = stack.back(); top->values.push_back(tmpVal); + setExpect(NOT_VALUE); break; } @@ -362,15 +420,16 @@ bool UniValue::read(const char *raw) UniValue *top = stack.back(); - if (expectName) { + if (expect(OBJ_NAME)) { top->keys.push_back(tokenVal); - expectName = false; - expectColon = true; + clearExpect(OBJ_NAME); + setExpect(COLON); } else { UniValue tmpVal(VSTR, tokenVal); top->values.push_back(tmpVal); } + setExpect(NOT_VALUE); break; } diff --git a/src/univalue/lib/univalue_write.cpp b/src/univalue/lib/univalue_write.cpp index bce3997af..ceb4cc916 100644 --- a/src/univalue/lib/univalue_write.cpp +++ b/src/univalue/lib/univalue_write.cpp @@ -2,7 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include #include #include #include @@ -25,10 +24,10 @@ static string json_escape(const string& inS) if (escStr) outS += escStr; - else if (isprint(ch)) + else if (ch < 0x80) outS += ch; - else { + else { // TODO handle UTF-8 properly char tmpesc[16]; sprintf(tmpesc, "\\u%04x", ch); outS += tmpesc; @@ -113,7 +112,7 @@ void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, s += "\"" + json_escape(keys[i]) + "\":"; if (prettyIndent) s += " "; - s += values[i].write(prettyIndent, indentLevel + 1); + s += values.at(i).write(prettyIndent, indentLevel + 1); if (i != (values.size() - 1)) s += ","; if (prettyIndent) diff --git a/src/univalue/test/.gitignore b/src/univalue/test/.gitignore index 4afa094b1..3d9347fe7 100644 --- a/src/univalue/test/.gitignore +++ b/src/univalue/test/.gitignore @@ -1 +1,4 @@ unitester + +*.trs +*.log diff --git a/src/univalue/test/fail35.json b/src/univalue/test/fail35.json new file mode 100644 index 000000000..de30ca5c4 --- /dev/null +++ b/src/univalue/test/fail35.json @@ -0,0 +1 @@ +[ true true true [] [] [] ] diff --git a/src/univalue/test/fail36.json b/src/univalue/test/fail36.json new file mode 100644 index 000000000..f82eb8e1f --- /dev/null +++ b/src/univalue/test/fail36.json @@ -0,0 +1 @@ +{"a":} diff --git a/src/univalue/test/fail37.json b/src/univalue/test/fail37.json new file mode 100644 index 000000000..3294dc3a4 --- /dev/null +++ b/src/univalue/test/fail37.json @@ -0,0 +1 @@ +{"a":1 "b":2} diff --git a/src/univalue/test/round1.json b/src/univalue/test/round1.json new file mode 100644 index 000000000..a711e7308 --- /dev/null +++ b/src/univalue/test/round1.json @@ -0,0 +1 @@ +["\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f"] diff --git a/src/univalue/test/unitester.cpp b/src/univalue/test/unitester.cpp index 835556e03..5a052fe92 100644 --- a/src/univalue/test/unitester.cpp +++ b/src/univalue/test/unitester.cpp @@ -19,24 +19,37 @@ using namespace std; string srcdir(JSON_TEST_SRC); +static bool test_failed = false; + +#define d_assert(expr) { if (!(expr)) { test_failed = true; fprintf(stderr, "%s failed\n", filename.c_str()); } } + +static std::string rtrim(std::string s) +{ + s.erase(s.find_last_not_of(" \n\r\t")+1); + return s; +} static void runtest(string filename, const string& jdata) { - fprintf(stderr, "test %s\n", filename.c_str()); - string prefix = filename.substr(0, 4); - bool wantPass = (prefix == "pass"); + bool wantPass = (prefix == "pass") || (prefix == "roun"); bool wantFail = (prefix == "fail"); + bool wantRoundTrip = (prefix == "roun"); assert(wantPass || wantFail); UniValue val; bool testResult = val.read(jdata); if (wantPass) { - assert(testResult == true); + d_assert(testResult == true); } else { - assert(testResult == false); + d_assert(testResult == false); + } + + if (wantRoundTrip) { + std::string odata = val.write(0, 0); + assert(odata == rtrim(jdata)); } } @@ -92,6 +105,9 @@ static const char *filenames[] = { "fail32.json", "fail33.json", "fail34.json", + "fail35.json", + "fail36.json", + "fail37.json", "fail3.json", "fail4.json", // extra comma "fail5.json", @@ -102,6 +118,7 @@ static const char *filenames[] = { "pass1.json", "pass2.json", "pass3.json", + "round1.json", // round-trip test }; int main (int argc, char *argv[]) @@ -110,6 +127,6 @@ int main (int argc, char *argv[]) runtest_file(filenames[fidx]); } - return 0; + return test_failed ? 1 : 0; } diff --git a/src/util.cpp b/src/util.cpp index 1f6b84119..492697e12 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -99,6 +99,9 @@ namespace boost { using namespace std; +const char * const BITCOIN_CONF_FILENAME = "bitcoin.conf"; +const char * const BITCOIN_PID_FILENAME = "bitcoind.pid"; + map mapArgs; map > mapMultiArgs; bool fDebug = false; @@ -107,9 +110,9 @@ bool fPrintToDebugLog = true; bool fDaemon = false; bool fServer = false; string strMiscWarning; -bool fLogTimestamps = false; +bool fLogTimestamps = DEFAULT_LOGTIMESTAMPS; bool fLogTimeMicros = DEFAULT_LOGTIMEMICROS; -bool fLogIPs = false; +bool fLogIPs = DEFAULT_LOGIPS; volatile bool fReopenDebugLog = false; CTranslationInterface translationInterface; @@ -447,7 +450,6 @@ void PrintExceptionContinue(const std::exception* pex, const char* pszThread) std::string message = FormatException(pex, pszThread); LogPrintf("\n\n************************\n%s\n", message); fprintf(stderr, "\n\n************************\n%s\n", message.c_str()); - strMiscWarning = message; } boost::filesystem::path GetDefaultDataDir() @@ -521,7 +523,7 @@ void ClearDatadirCache() boost::filesystem::path GetConfigFile() { - boost::filesystem::path pathConfigFile(GetArg("-conf", "bitcoin.conf")); + boost::filesystem::path pathConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)); if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile; @@ -555,7 +557,7 @@ void ReadConfigFile(map& mapSettingsRet, #ifndef WIN32 boost::filesystem::path GetPidFile() { - boost::filesystem::path pathPidFile(GetArg("-pid", "bitcoind.pid")); + boost::filesystem::path pathPidFile(GetArg("-pid", BITCOIN_PID_FILENAME)); if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile; return pathPidFile; } diff --git a/src/util.h b/src/util.h index 5a948c6a9..9da8fdf87 100644 --- a/src/util.h +++ b/src/util.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -29,6 +29,8 @@ #include static const bool DEFAULT_LOGTIMEMICROS = false; +static const bool DEFAULT_LOGIPS = false; +static const bool DEFAULT_LOGTIMESTAMPS = true; /** Signals for translation. */ class CTranslationInterface @@ -51,6 +53,9 @@ extern bool fLogIPs; extern volatile bool fReopenDebugLog; extern CTranslationInterface translationInterface; +extern const char * const BITCOIN_CONF_FILENAME; +extern const char * const BITCOIN_PID_FILENAME; + /** * Translation function: Call Translate signal on UI interface, which returns a boost::optional result. * If no translation slot is registered, nothing is returned, and simply return the input. diff --git a/src/utilmoneystr.cpp b/src/utilmoneystr.cpp index 0f3203432..bebe56130 100644 --- a/src/utilmoneystr.cpp +++ b/src/utilmoneystr.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilmoneystr.h b/src/utilmoneystr.h index 99c3ba830..5839b0734 100644 --- a/src/utilmoneystr.h +++ b/src/utilmoneystr.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index a098c3e0a..0f9334cbe 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index ce93e8349..d40613cfc 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/utiltime.cpp b/src/utiltime.cpp index 3202c47f1..91b40d999 100644 --- a/src/utiltime.cpp +++ b/src/utiltime.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -20,7 +20,9 @@ int64_t GetTime() { if (nMockTime) return nMockTime; - return time(NULL); + time_t now = time(NULL); + assert(now > 0); + return now; } void SetMockTime(int64_t nMockTimeIn) @@ -30,14 +32,18 @@ void SetMockTime(int64_t nMockTimeIn) int64_t GetTimeMillis() { - return (boost::posix_time::microsec_clock::universal_time() - - boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds(); + int64_t now = (boost::posix_time::microsec_clock::universal_time() - + boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds(); + assert(now > 0); + return now; } int64_t GetTimeMicros() { - return (boost::posix_time::microsec_clock::universal_time() - - boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds(); + int64_t now = (boost::posix_time::microsec_clock::universal_time() - + boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds(); + assert(now > 0); + return now; } /** Return a time useful for the debug log */ diff --git a/src/utiltime.h b/src/utiltime.h index 241b5211e..b2807267d 100644 --- a/src/utiltime.h +++ b/src/utiltime.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/validationinterface.h b/src/validationinterface.h index ffb56d266..4da145473 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/version.h b/src/version.h index 6cdddf925..f7cf18d0b 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 70011; +static const int PROTOCOL_VERSION = 70012; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -37,4 +37,7 @@ static const int MEMPOOL_GD_VERSION = 60002; //! "filter*" commands are disabled without NODE_BLOOM after and including this version static const int NO_BLOOM_VERSION = 70011; +//! "sendheaders" command and announcing blocks with headers starts with this version +static const int SENDHEADERS_VERSION = 70012; + #endif // BITCOIN_VERSION_H diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index c86ad9758..95aa4c259 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index 70aeb7672..eb06a7866 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index cf6122813..50b0f40a6 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -85,7 +85,7 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string()); unsigned int nEnvFlags = 0; - if (GetBoolArg("-privdb", true)) + if (GetBoolArg("-privdb", DEFAULT_WALLET_PRIVDB)) nEnvFlags |= DB_PRIVATE; dbenv->set_lg_dir(pathLogDir.string().c_str()); @@ -205,7 +205,7 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100; +static const bool DEFAULT_WALLET_PRIVDB = true; extern unsigned int nWalletDBUpdated; diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index c431fc401..9ec28e7b9 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -1,10 +1,10 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" #include "chain.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "init.h" #include "main.h" #include "script/script.h" diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b6eaca80b..857a3a77e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -11,7 +11,8 @@ #include "main.h" #include "net.h" #include "netbase.h" -#include "rpcserver.h" +#include "policy/rbf.h" +#include "rpc/server.h" #include "timedata.h" #include "util.h" #include "utilmoneystr.h" @@ -65,6 +66,8 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); entry.push_back(Pair("blockindex", wtx.nIndex)); entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime())); + } else { + entry.push_back(Pair("trusted", wtx.IsTrusted())); } uint256 hash = wtx.GetHash(); entry.push_back(Pair("txid", hash.GetHex())); @@ -74,6 +77,23 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) entry.push_back(Pair("walletconflicts", conflicts)); entry.push_back(Pair("time", wtx.GetTxTime())); entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived)); + + // Add opt-in RBF status + std::string rbfStatus = "no"; + if (confirms <= 0) { + LOCK(mempool.cs); + if (!mempool.exists(hash)) { + if (SignalsOptInRBF(wtx)) { + rbfStatus = "yes"; + } else { + rbfStatus = "unknown"; + } + } else if (IsRBFOptIn(*mempool.mapTx.find(hash), mempool)) { + rbfStatus = "yes"; + } + } + entry.push_back(Pair("bip125-replaceable", rbfStatus)); + BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue) entry.push_back(Pair(item.first, item.second)); } @@ -90,7 +110,7 @@ UniValue getnewaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 1) throw runtime_error( "getnewaddress ( \"account\" )\n" @@ -135,26 +155,25 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) CAccount account; walletdb.ReadAccount(strAccount, account); - bool bKeyUsed = false; - - // Check if the current key has been used - if (account.vchPubKey.IsValid()) - { - CScript scriptPubKey = GetScriptForDestination(account.vchPubKey.GetID()); - for (map::iterator it = pwalletMain->mapWallet.begin(); - it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid(); - ++it) - { - const CWalletTx& wtx = (*it).second; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - if (txout.scriptPubKey == scriptPubKey) - bKeyUsed = true; + if (!bForceNew) { + if (!account.vchPubKey.IsValid()) + bForceNew = true; + else { + // Check if the current key has been used + CScript scriptPubKey = GetScriptForDestination(account.vchPubKey.GetID()); + for (map::iterator it = pwalletMain->mapWallet.begin(); + it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid(); + ++it) + BOOST_FOREACH(const CTxOut& txout, (*it).second.vout) + if (txout.scriptPubKey == scriptPubKey) { + bForceNew = true; + break; + } } } // Generate a new key - if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed) - { + if (bForceNew) { if (!pwalletMain->GetKeyFromPool(account.vchPubKey)) throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); @@ -169,7 +188,7 @@ UniValue getaccountaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 1) throw runtime_error( "getaccountaddress \"account\"\n" @@ -201,7 +220,7 @@ UniValue getrawchangeaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 1) throw runtime_error( "getrawchangeaddress\n" @@ -236,7 +255,7 @@ UniValue setaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "setaccount \"bitcoinaddress\" \"account\"\n" @@ -282,7 +301,7 @@ UniValue getaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 1) throw runtime_error( "getaccount \"bitcoinaddress\"\n" @@ -314,7 +333,7 @@ UniValue getaddressesbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 1) throw runtime_error( "getaddressesbyaccount \"account\"\n" @@ -382,15 +401,15 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( "sendtoaddress \"bitcoinaddress\" amount ( \"comment\" \"comment-to\" subtractfeefromamount )\n" - "\nSend an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n" + "\nSend an amount to a given address.\n" + HelpRequiringPassphrase() + "\nArguments:\n" "1. \"bitcoinaddress\" (string, required) The bitcoin address to send to.\n" - "2. \"amount\" (numeric, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" + "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" " This is not part of the transaction, just kept in your wallet.\n" "4. \"comment-to\" (string, optional) A comment to store the name of the person or organization \n" @@ -440,7 +459,7 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp) throw runtime_error( "listaddressgroupings\n" @@ -491,7 +510,7 @@ UniValue signmessage(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 2) throw runtime_error( "signmessage \"bitcoinaddress\" \"message\"\n" @@ -547,7 +566,7 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "getreceivedbyaddress \"bitcoinaddress\" ( minconf )\n" @@ -605,7 +624,7 @@ UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "getreceivedbyaccount \"account\" ( minconf )\n" @@ -694,7 +713,7 @@ UniValue getbalance(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 3) throw runtime_error( "getbalance ( \"account\" minconf includeWatchonly )\n" @@ -769,7 +788,7 @@ UniValue getunconfirmedbalance(const UniValue ¶ms, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 0) throw runtime_error( "getunconfirmedbalance\n" @@ -785,7 +804,7 @@ UniValue movecmd(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 3 || params.size() > 5) throw runtime_error( "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n" @@ -858,17 +877,16 @@ UniValue sendfrom(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 3 || params.size() > 6) throw runtime_error( "sendfrom \"fromaccount\" \"tobitcoinaddress\" amount ( minconf \"comment\" \"comment-to\" )\n" - "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address.\n" - "The amount is a real and is rounded to the nearest 0.00000001." + "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address." + HelpRequiringPassphrase() + "\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n" "2. \"tobitcoinaddress\" (string, required) The bitcoin address to send funds to.\n" - "3. amount (numeric, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n" + "3. amount (numeric or string, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n" "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" " This is not part of the transaction, just kept in your wallet.\n" @@ -923,7 +941,7 @@ UniValue sendmany(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] )\n" @@ -933,7 +951,7 @@ UniValue sendmany(const UniValue& params, bool fHelp) "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n" "2. \"amounts\" (string, required) A json object with addresses and amounts\n" " {\n" - " \"address\":amount (numeric) The bitcoin address is the key, the numeric amount in " + CURRENCY_UNIT + " is the value\n" + " \"address\":amount (numeric or string) The bitcoin address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value\n" " ,...\n" " }\n" "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n" @@ -1030,14 +1048,14 @@ UniValue sendmany(const UniValue& params, bool fHelp) return wtx.GetHash().GetHex(); } -// Defined in rpcmisc.cpp +// Defined in rpc/misc.cpp extern CScript _createmultisig_redeemScript(const UniValue& params); UniValue addmultisigaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 2 || params.size() > 3) { string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n" @@ -1220,7 +1238,7 @@ UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 3) throw runtime_error( "listreceivedbyaddress ( minconf includeempty includeWatchonly)\n" @@ -1258,7 +1276,7 @@ UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 3) throw runtime_error( "listreceivedbyaccount ( minconf includeempty includeWatchonly)\n" @@ -1393,7 +1411,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 4) throw runtime_error( "listtransactions ( \"account\" count from includeWatchonly)\n" @@ -1421,7 +1439,9 @@ UniValue listtransactions(const UniValue& params, bool fHelp) " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" " 'send' category of transactions.\n" " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n" - " 'receive' category of transactions.\n" + " 'receive' category of transactions. Negative confirmations indicate the\n" + " transaction conflicts with the block chain\n" + " \"trusted\": xxx (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n" " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n" " category of transactions.\n" " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive'\n" @@ -1436,6 +1456,8 @@ UniValue listtransactions(const UniValue& params, bool fHelp) " \"otheraccount\": \"accountname\", (string) For the 'move' category of transactions, the account the funds came \n" " from (for receiving funds, positive amounts), or went to (for sending funds,\n" " negative amounts).\n" + " \"bip125-replaceable\": \"yes|no|unknown\" (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n" + " may be unknown for unconfirmed transactions not in the mempool\n" " }\n" "]\n" @@ -1515,7 +1537,7 @@ UniValue listaccounts(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 2) throw runtime_error( "listaccounts ( minconf includeWatchonly)\n" @@ -1594,7 +1616,7 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp) throw runtime_error( "listsinceblock ( \"blockhash\" target-confirmations includeWatchonly)\n" @@ -1686,7 +1708,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "gettransaction \"txid\" ( includeWatchonly )\n" @@ -1704,6 +1726,8 @@ UniValue gettransaction(const UniValue& params, bool fHelp) " \"txid\" : \"transactionid\", (string) The transaction id.\n" " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n" " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n" + " \"bip125-replaceable\": \"yes|no|unknown\" (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n" + " may be unknown for unconfirmed transactions not in the mempool\n" " \"details\" : [\n" " {\n" " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n" @@ -1760,12 +1784,46 @@ UniValue gettransaction(const UniValue& params, bool fHelp) return entry; } +UniValue abandontransaction(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() != 1) + throw runtime_error( + "abandontransaction \"txid\"\n" + "\nMark in-wallet transaction as abandoned\n" + "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n" + "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n" + "It only works on transactions which are not included in a block and are not currently in the mempool.\n" + "It has no effect on transactions which are already conflicted or abandoned.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id\n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + uint256 hash; + hash.SetHex(params[0].get_str()); + + if (!pwalletMain->mapWallet.count(hash)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); + if (!pwalletMain->AbandonTransaction(hash)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment"); + + return NullUniValue; +} + UniValue backupwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 1) throw runtime_error( "backupwallet \"destination\"\n" @@ -1791,7 +1849,7 @@ UniValue keypoolrefill(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 1) throw runtime_error( "keypoolrefill ( newsize )\n" @@ -1835,7 +1893,7 @@ UniValue walletpassphrase(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( "walletpassphrase \"passphrase\" timeout\n" @@ -1895,7 +1953,7 @@ UniValue walletpassphrasechange(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n" @@ -1941,7 +1999,7 @@ UniValue walletlock(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0)) throw runtime_error( "walletlock\n" @@ -1980,7 +2038,7 @@ UniValue encryptwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1)) throw runtime_error( "encryptwallet \"passphrase\"\n" @@ -2037,7 +2095,7 @@ UniValue lockunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "lockunspent unlock [{\"txid\":\"txid\",\"vout\":n},...]\n" @@ -2121,7 +2179,7 @@ UniValue listlockunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 0) throw runtime_error( "listlockunspent\n" @@ -2170,13 +2228,13 @@ UniValue settxfee(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() < 1 || params.size() > 1) throw runtime_error( "settxfee amount\n" - "\nSet the transaction fee per kB.\n" + "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n" "\nArguments:\n" - "1. amount (numeric, required) The transaction fee in " + CURRENCY_UNIT + "/kB rounded to the nearest 0.00000001\n" + "1. amount (numeric or sting, required) The transaction fee in " + CURRENCY_UNIT + "/kB\n" "\nResult\n" "true|false (boolean) Returns true if successful\n" "\nExamples:\n" @@ -2197,7 +2255,7 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 0) throw runtime_error( "getwalletinfo\n" @@ -2239,7 +2297,7 @@ UniValue resendwallettransactions(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() != 0) throw runtime_error( "resendwallettransactions\n" @@ -2264,7 +2322,7 @@ UniValue listunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + if (fHelp || params.size() > 3) throw runtime_error( "listunspent ( minconf maxconf [\"address\",...] )\n" @@ -2438,3 +2496,70 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) return result; } + +extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp +extern UniValue importprivkey(const UniValue& params, bool fHelp); +extern UniValue importaddress(const UniValue& params, bool fHelp); +extern UniValue importpubkey(const UniValue& params, bool fHelp); +extern UniValue dumpwallet(const UniValue& params, bool fHelp); +extern UniValue importwallet(const UniValue& params, bool fHelp); + +const CRPCCommand vWalletRPCCommands[] = +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- + { "rawtransactions", "fundrawtransaction", &fundrawtransaction, false }, + { "hidden", "resendwallettransactions", &resendwallettransactions, true }, + { "wallet", "abandontransaction", &abandontransaction, false }, + { "wallet", "addmultisigaddress", &addmultisigaddress, true }, + { "wallet", "backupwallet", &backupwallet, true }, + { "wallet", "dumpprivkey", &dumpprivkey, true }, + { "wallet", "dumpwallet", &dumpwallet, true }, + { "wallet", "encryptwallet", &encryptwallet, true }, + { "wallet", "getaccountaddress", &getaccountaddress, true }, + { "wallet", "getaccount", &getaccount, true }, + { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true }, + { "wallet", "getbalance", &getbalance, false }, + { "wallet", "getnewaddress", &getnewaddress, true }, + { "wallet", "getrawchangeaddress", &getrawchangeaddress, true }, + { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false }, + { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false }, + { "wallet", "gettransaction", &gettransaction, false }, + { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false }, + { "wallet", "getwalletinfo", &getwalletinfo, false }, + { "wallet", "importprivkey", &importprivkey, true }, + { "wallet", "importwallet", &importwallet, true }, + { "wallet", "importaddress", &importaddress, true }, + { "wallet", "importpubkey", &importpubkey, true }, + { "wallet", "keypoolrefill", &keypoolrefill, true }, + { "wallet", "listaccounts", &listaccounts, false }, + { "wallet", "listaddressgroupings", &listaddressgroupings, false }, + { "wallet", "listlockunspent", &listlockunspent, false }, + { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false }, + { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false }, + { "wallet", "listsinceblock", &listsinceblock, false }, + { "wallet", "listtransactions", &listtransactions, false }, + { "wallet", "listunspent", &listunspent, false }, + { "wallet", "lockunspent", &lockunspent, true }, + { "wallet", "move", &movecmd, false }, + { "wallet", "sendfrom", &sendfrom, false }, + { "wallet", "sendmany", &sendmany, false }, + { "wallet", "sendtoaddress", &sendtoaddress, false }, + { "wallet", "setaccount", &setaccount, true }, + { "wallet", "settxfee", &settxfee, true }, + { "wallet", "signmessage", &signmessage, true }, + { "wallet", "walletlock", &walletlock, true }, + { "wallet", "walletpassphrasechange", &walletpassphrasechange, true }, + { "wallet", "walletpassphrase", &walletpassphrase, true }, +}; + +void walletRegisterRPCCommands() +{ + unsigned int vcidx; + for (vcidx = 0; vcidx < ARRAYLEN(vWalletRPCCommands); vcidx++) + { + const CRPCCommand *pcmd; + + pcmd = &vWalletRPCCommands[vcidx]; + tableRPC.appendCommand(pcmd->name, pcmd); + } +} diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h new file mode 100644 index 000000000..42e8021af --- /dev/null +++ b/src/wallet/rpcwallet.h @@ -0,0 +1,10 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_WALLET_RPCWALLET_H +#define BITCOIN_WALLET_RPCWALLET_H + +void walletRegisterRPCCommands(); + +#endif //BITCOIN_WALLET_RPCWALLET_H diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 8b9292bd1..e84d58802 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2012-2014 The Bitcoin Core developers +// Copyright (c) 2012-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -328,4 +328,37 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) empty_wallet(); } +BOOST_AUTO_TEST_CASE(ApproximateBestSubset) +{ + CoinSet setCoinsRet; + CAmount nValueRet; + + LOCK(wallet.cs_wallet); + + empty_wallet(); + + // Test vValue sort order + for (int i = 0; i < 1000; i++) + add_coin(1000 * COIN); + add_coin(3 * COIN); + + BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); + + empty_wallet(); + + // Test trimming + for (int i = 0; i < 100; i++) + add_coin(10 * COIN); + for (int i = 0; i < 100; i++) + add_coin(1000 * COIN); + + BOOST_CHECK(wallet.SelectCoinsMinConf(100001 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet)); + // We need all 100 larger coins and exactly one small coin. + // Superfluous small coins must be trimmed from the set: + BOOST_CHECK_EQUAL(nValueRet, 100010 * COIN); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 101); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1b152f419..dd9d549f6 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -37,17 +37,23 @@ using namespace std; * Settings */ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); -CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET; -bool bSpendZeroConfChange = true; -bool fSendFreeTransactions = false; -bool fPayAtLeastCustomFee = true; +bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; +bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS; /** * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) * Override with -mintxfee */ CFeeRate CWallet::minTxFee = CFeeRate(DEFAULT_TRANSACTION_MINFEE); +/** + * If fee estimation does not have enough data to provide estimates, use this fee instead. + * Has no effect if not using fee estimation + * Override with -fallbackfee + */ +CFeeRate CWallet::fallbackFee = CFeeRate(DEFAULT_FALLBACK_FEE); + +const uint256 CMerkleTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); /** @defgroup mapWallet * @@ -456,8 +462,11 @@ bool CWallet::IsSpent(const uint256& hash, unsigned int n) const { const uint256& wtxid = it->second; std::map::const_iterator mit = mapWallet.find(wtxid); - if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) - return true; // Spent + if (mit != mapWallet.end()) { + int depth = mit->second.GetDepthInMainChain(); + if (depth > 0 || (depth == 0 && !mit->second.isAbandoned())) + return true; // Spent + } } return false; } @@ -608,6 +617,14 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD wtx.BindWallet(this); wtxOrdered.insert(make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0))); AddToSpends(hash); + BOOST_FOREACH(const CTxIn& txin, wtx.vin) { + if (mapWallet.count(txin.prevout.hash)) { + CWalletTx& prevtx = mapWallet[txin.prevout.hash]; + if (prevtx.nIndex == -1 && !prevtx.hashUnset()) { + MarkConflicted(prevtx.hashBlock, wtx.GetHash()); + } + } + } } else { @@ -624,7 +641,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD wtxOrdered.insert(make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0))); wtx.nTimeSmart = wtx.nTimeReceived; - if (!wtxIn.hashBlock.IsNull()) + if (!wtxIn.hashUnset()) { if (mapBlockIndex.count(wtxIn.hashBlock)) { @@ -674,7 +691,13 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD if (!fInsertedNew) { // Merge - if (!wtxIn.hashBlock.IsNull() && wtxIn.hashBlock != wtx.hashBlock) + if (!wtxIn.hashUnset() && wtxIn.hashBlock != wtx.hashBlock) + { + wtx.hashBlock = wtxIn.hashBlock; + fUpdated = true; + } + // If no longer abandoned, update + if (wtxIn.hashBlock.IsNull() && wtx.isAbandoned()) { wtx.hashBlock = wtxIn.hashBlock; fUpdated = true; @@ -727,6 +750,20 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl { { AssertLockHeld(cs_wallet); + + if (pblock) { + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + std::pair range = mapTxSpends.equal_range(txin.prevout); + while (range.first != range.second) { + if (range.first->second != tx.GetHash()) { + LogPrintf("Transaction %s (in block %s) conflicts with wallet transaction %s (both spend %s:%i)\n", tx.GetHash().ToString(), pblock->GetHash().ToString(), range.first->second.ToString(), range.first->first.hash.ToString(), range.first->first.n); + MarkConflicted(pblock->GetHash(), range.first->second); + } + range.first++; + } + } + } + bool fExisted = mapWallet.count(tx.GetHash()) != 0; if (fExisted && !fUpdate) return false; if (fExisted || IsMine(tx) || IsFromMe(tx)) @@ -747,9 +784,122 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl return false; } +bool CWallet::AbandonTransaction(const uint256& hashTx) +{ + LOCK2(cs_main, cs_wallet); + + // Do not flush the wallet here for performance reasons + CWalletDB walletdb(strWalletFile, "r+", false); + + std::set todo; + std::set done; + + // Can't mark abandoned if confirmed or in mempool + assert(mapWallet.count(hashTx)); + CWalletTx& origtx = mapWallet[hashTx]; + if (origtx.GetDepthInMainChain() > 0 || origtx.InMempool()) { + return false; + } + + todo.insert(hashTx); + + while (!todo.empty()) { + uint256 now = *todo.begin(); + todo.erase(now); + done.insert(now); + assert(mapWallet.count(now)); + CWalletTx& wtx = mapWallet[now]; + int currentconfirm = wtx.GetDepthInMainChain(); + // If the orig tx was not in block, none of its spends can be + assert(currentconfirm <= 0); + // if (currentconfirm < 0) {Tx and spends are already conflicted, no need to abandon} + if (currentconfirm == 0 && !wtx.isAbandoned()) { + // If the orig tx was not in block/mempool, none of its spends can be in mempool + assert(!wtx.InMempool()); + wtx.nIndex = -1; + wtx.setAbandoned(); + wtx.MarkDirty(); + wtx.WriteToDisk(&walletdb); + NotifyTransactionChanged(this, wtx.GetHash(), CT_UPDATED); + // Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too + TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(hashTx, 0)); + while (iter != mapTxSpends.end() && iter->first.hash == now) { + if (!done.count(iter->second)) { + todo.insert(iter->second); + } + iter++; + } + // If a transaction changes 'conflicted' state, that changes the balance + // available of the outputs it spends. So force those to be recomputed + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + { + if (mapWallet.count(txin.prevout.hash)) + mapWallet[txin.prevout.hash].MarkDirty(); + } + } + } + + return true; +} + +void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) +{ + LOCK2(cs_main, cs_wallet); + + CBlockIndex* pindex; + assert(mapBlockIndex.count(hashBlock)); + pindex = mapBlockIndex[hashBlock]; + int conflictconfirms = 0; + if (chainActive.Contains(pindex)) { + conflictconfirms = -(chainActive.Height() - pindex->nHeight + 1); + } + assert(conflictconfirms < 0); + + // Do not flush the wallet here for performance reasons + CWalletDB walletdb(strWalletFile, "r+", false); + + std::set todo; + std::set done; + + todo.insert(hashTx); + + while (!todo.empty()) { + uint256 now = *todo.begin(); + todo.erase(now); + done.insert(now); + assert(mapWallet.count(now)); + CWalletTx& wtx = mapWallet[now]; + int currentconfirm = wtx.GetDepthInMainChain(); + if (conflictconfirms < currentconfirm) { + // Block is 'more conflicted' than current confirm; update. + // Mark transaction as conflicted with this block. + wtx.nIndex = -1; + wtx.hashBlock = hashBlock; + wtx.MarkDirty(); + wtx.WriteToDisk(&walletdb); + // Iterate over all its outputs, and mark transactions in the wallet that spend them conflicted too + TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0)); + while (iter != mapTxSpends.end() && iter->first.hash == now) { + if (!done.count(iter->second)) { + todo.insert(iter->second); + } + iter++; + } + // If a transaction changes 'conflicted' state, that changes the balance + // available of the outputs it spends. So force those to be recomputed + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + { + if (mapWallet.count(txin.prevout.hash)) + mapWallet[txin.prevout.hash].MarkDirty(); + } + } + } +} + void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock) { LOCK2(cs_main, cs_wallet); + if (!AddToWalletIfInvolvingMe(tx, pblock, true)) return; // Not one of ours @@ -900,7 +1050,7 @@ int CWalletTx::GetRequestCount() const if (IsCoinBase()) { // Generated block - if (!hashBlock.IsNull()) + if (!hashUnset()) { map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); if (mi != pwallet->mapRequestCount.end()) @@ -916,7 +1066,7 @@ int CWalletTx::GetRequestCount() const nRequests = (*mi).second; // How about the block it's in? - if (nRequests == 0 && !hashBlock.IsNull()) + if (nRequests == 0 && !hashUnset()) { map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); if (mi != pwallet->mapRequestCount.end()) @@ -965,7 +1115,8 @@ void CWalletTx::GetAmounts(list& listReceived, // In either case, we need to get the destination address CTxDestination address; - if (!ExtractDestination(txout.scriptPubKey, address)) + + if (!ExtractDestination(txout.scriptPubKey, address) && !txout.scriptPubKey.IsUnspendable()) { LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n", this->GetHash().ToString()); @@ -1089,7 +1240,7 @@ void CWallet::ReacceptWalletTransactions() int nDepth = wtx.GetDepthInMainChain(); - if (!wtx.IsCoinBase() && nDepth < 0) { + if (!wtx.IsCoinBase() && (nDepth == 0 && !wtx.isAbandoned())) { mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx)); } } @@ -1109,7 +1260,7 @@ bool CWalletTx::RelayWalletTransaction() assert(pwallet->GetBroadcastTransactions()); if (!IsCoinBase()) { - if (GetDepthInMainChain() == 0) { + if (GetDepthInMainChain() == 0 && !isAbandoned()) { LogPrintf("Relaying wtx %s\n", GetHash().ToString()); RelayTransaction((CTransaction)*this); return true; @@ -1290,6 +1441,15 @@ CAmount CWalletTx::GetChange() const return nChangeCached; } +bool CWalletTx::InMempool() const +{ + LOCK(mempool.cs); + if (mempool.exists(GetHash())) { + return true; + } + return false; +} + bool CWalletTx::IsTrusted() const { // Quick answer in most cases @@ -1303,6 +1463,10 @@ bool CWalletTx::IsTrusted() const if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit return false; + // Don't trust unconfirmed transactions from us unless they are in the mempool. + if (!InMempool()) + return false; + // Trusted if all inputs are from us and are in the mempool: BOOST_FOREACH(const CTxIn& txin, vin) { @@ -1555,6 +1719,16 @@ static void ApproximateBestSubset(vector= nTargetValue ) + { + vfBest[i] = false; + nBest -= vValue[i].first; + } + } } bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector vCoins, @@ -1624,7 +1798,8 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int } // Solve subset sum by stochastic approximation - sort(vValue.rbegin(), vValue.rend(), CompareValueOnly()); + std::sort(vValue.begin(), vValue.end(), CompareValueOnly()); + std::reverse(vValue.begin(), vValue.end()); vector vfBest; CAmount nBest; @@ -1794,15 +1969,25 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt // Discourage fee sniping. // - // However because of a off-by-one-error in previous versions we need to - // neuter it by setting nLockTime to at least one less than nBestHeight. - // Secondly currently propagation of transactions created for block heights - // corresponding to blocks that were just mined may be iffy - transactions - // aren't re-accepted into the mempool - we additionally neuter the code by - // going ten blocks back. Doesn't yet do anything for sniping, but does act - // to shake out wallet bugs like not showing nLockTime'd transactions at - // all. - txNew.nLockTime = std::max(0, chainActive.Height() - 10); + // For a large miner the value of the transactions in the best block and + // the mempool can exceed the cost of deliberately attempting to mine two + // blocks to orphan the current best block. By setting nLockTime such that + // only the next block can include the transaction, we discourage this + // practice as the height restricted and limited blocksize gives miners + // considering fee sniping fewer options for pulling off this attack. + // + // A simple way to think about this is from the wallet's point of view we + // always want the blockchain to move forward. By setting nLockTime this + // way we're basically making the statement that we only want this + // transaction to appear in the next block; we don't want to potentially + // encourage reorgs by allowing transactions to appear at lower heights + // than the next block in forks of the best chain. + // + // Of course, the subsidy is high enough, and transaction volume low + // enough, that fee sniping isn't a problem yet, but by implementing a fix + // now we ensure code won't be written that makes assumptions about + // nLockTime that preclude a fix later. + txNew.nLockTime = chainActive.Height(); // Secondly occasionally randomly pick a nLockTime even further back, so // that transactions that are delayed after signing for whatever reason, @@ -1879,6 +2064,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt //a chance at a free transaction. //But mempool inputs might still be in the mempool, so their age stays 0 int age = pcoin.first->GetDepthInMainChain(); + assert(age >= 0); if (age != 0) age += 1; dPriority += (double)nCredit * age; @@ -2010,17 +2196,16 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt if (fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE) { // Not enough fee: enough priority? - double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget); - // Not enough mempool history to estimate: use hard-coded AllowFree. - if (dPriorityNeeded <= 0 && AllowFree(dPriority)) - break; - - // Small enough, and priority high enough, to send for free - if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded) + double dPriorityNeeded = mempool.estimateSmartPriority(nTxConfirmTarget); + // Require at least hard-coded AllowFree. + if (dPriority >= dPriorityNeeded && AllowFree(dPriority)) break; } CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool); + if (coinControl && nFeeNeeded > 0 && coinControl->nMinimumTotalFee > nFeeNeeded) { + nFeeNeeded = coinControl->nMinimumTotalFee; + } // If we made it here and we aren't even able to meet the relay fee on the next pass, give up // because we must be at the maximum allowed fee. @@ -2116,19 +2301,16 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge { // payTxFee is user-set "I want to pay this much" CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes); - // user selected total at least (default=true) - if (fPayAtLeastCustomFee && nFeeNeeded > 0 && nFeeNeeded < payTxFee.GetFeePerK()) - nFeeNeeded = payTxFee.GetFeePerK(); // User didn't set: use -txconfirmtarget to estimate... - if (nFeeNeeded == 0) - nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes); - // ... unless we don't have enough mempool data, in which case fall - // back to the required fee - if (nFeeNeeded == 0) - nFeeNeeded = GetRequiredFee(nTxBytes); - // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee - if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes)) - nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes); + if (nFeeNeeded == 0) { + int estimateFoundTarget = nConfirmTarget; + nFeeNeeded = pool.estimateSmartFee(nConfirmTarget, &estimateFoundTarget).GetFee(nTxBytes); + // ... unless we don't have enough mempool data for estimatefee, then use fallbackFee + if (nFeeNeeded == 0) + nFeeNeeded = fallbackFee.GetFee(nTxBytes); + } + // prevent user from paying a fee below minRelayTxFee or minTxFee + nFeeNeeded = std::max(nFeeNeeded, GetRequiredFee(nTxBytes)); // But always obey the maximum if (nFeeNeeded > maxTxFee) nFeeNeeded = maxTxFee; @@ -2262,7 +2444,7 @@ bool CWallet::NewKeyPool() if (IsLocked()) return false; - int64_t nKeys = max(GetArg("-keypool", 100), (int64_t)0); + int64_t nKeys = max(GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t)0); for (int i = 0; i < nKeys; i++) { int64_t nIndex = i+1; @@ -2289,7 +2471,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) if (kpSize > 0) nTargetSize = kpSize; else - nTargetSize = max(GetArg("-keypool", 100), (int64_t) 0); + nTargetSize = max(GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 0); while (setKeyPool.size() < (nTargetSize + 1)) { @@ -2816,10 +2998,11 @@ int CMerkleTx::SetMerkleBranch(const CBlock& block) return chainActive.Height() - pindex->nHeight + 1; } -int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const +int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const { - if (hashBlock.IsNull() || nIndex == -1) + if (hashUnset()) return 0; + AssertLockHeld(cs_main); // Find the block it claims to be in @@ -2831,17 +3014,7 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const return 0; pindexRet = pindex; - return chainActive.Height() - pindex->nHeight + 1; -} - -int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const -{ - AssertLockHeld(cs_main); - int nResult = GetDepthInMainChainINTERNAL(pindexRet); - if (nResult == 0 && !mempool.exists(GetHash())) - return -1; // Not in chain, not in mempool - - return nResult; + return ((nIndex == -1) ? (-1) : 1) * (chainActive.Height() - pindex->nHeight + 1); } int CMerkleTx::GetBlocksToMaturity() const @@ -2857,4 +3030,3 @@ bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) CValidationState state; return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, false, fRejectAbsurdFee); } - diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 7e846569f..28d2f8a04 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,6 +15,7 @@ #include "wallet/crypter.h" #include "wallet/wallet_ismine.h" #include "wallet/walletdb.h" +#include "wallet/rpcwallet.h" #include #include @@ -31,30 +32,29 @@ * Settings */ extern CFeeRate payTxFee; -extern CAmount maxTxFee; extern unsigned int nTxConfirmTarget; extern bool bSpendZeroConfChange; extern bool fSendFreeTransactions; -extern bool fPayAtLeastCustomFee; +static const unsigned int DEFAULT_KEYPOOL_SIZE = 100; //! -paytxfee default static const CAmount DEFAULT_TRANSACTION_FEE = 0; -//! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB -static const CAmount nHighTransactionFeeWarning = 0.01 * COIN; +//! -fallbackfee default +static const CAmount DEFAULT_FALLBACK_FEE = 20000; //! -mintxfee default static const CAmount DEFAULT_TRANSACTION_MINFEE = 1000; -//! -maxtxfee default -static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; //! minimum change amount static const CAmount MIN_CHANGE = CENT; +//! Default for -spendzeroconfchange +static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true; +//! Default for -sendfreetransactions +static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false; //! -txconfirmtarget default static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; -//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis) -static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWarning; //! Largest (in bytes) free transaction we're willing to create static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; +static const bool DEFAULT_WALLETBROADCAST = true; -class CAccountingEntry; class CBlockIndex; class CCoinControl; class COutput; @@ -151,10 +151,17 @@ struct COutputEntry class CMerkleTx : public CTransaction { private: - int GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const; + /** Constant used in hashBlock to indicate tx has been abandoned */ + static const uint256 ABANDON_HASH; public: uint256 hashBlock; + + /* An nIndex == -1 means that hashBlock (in nonzero) refers to the earliest + * block in the chain we know this or any in-wallet dependency conflicts + * with. Older clients interpret nIndex == -1 as unconfirmed for backward + * compatibility. + */ int nIndex; CMerkleTx() @@ -187,18 +194,21 @@ public: int SetMerkleBranch(const CBlock& block); - /** * Return depth of transaction in blockchain: - * -1 : not in blockchain, and not in memory pool (conflicted transaction) + * <0 : conflicts with a transaction this deep in the blockchain * 0 : in memory pool, waiting to be included in a block * >=1 : this many blocks deep in the main chain */ int GetDepthInMainChain(const CBlockIndex* &pindexRet) const; int GetDepthInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } - bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChainINTERNAL(pindexRet) > 0; } + bool IsInMainChain() const { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; } int GetBlocksToMaturity() const; + /** Pass this transaction to the mempool. Fails if absolute fee exceeds maxTxFee. */ bool AcceptToMemoryPool(bool fLimitFree=true, bool fRejectAbsurdFee=true); + bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); } + bool isAbandoned() const { return (hashBlock == ABANDON_HASH); } + void setAbandoned() { hashBlock = ABANDON_HASH; } }; /** @@ -377,6 +387,7 @@ public: // True if only scriptSigs are different bool IsEquivalentTo(const CWalletTx& tx) const; + bool InMempool() const; bool IsTrusted() const; bool WriteToDisk(CWalletDB *pwalletdb); @@ -437,6 +448,86 @@ public: } }; +/** + * Internal transfers. + * Database key is acentry. + */ +class CAccountingEntry +{ +public: + std::string strAccount; + CAmount nCreditDebit; + int64_t nTime; + std::string strOtherAccount; + std::string strComment; + mapValue_t mapValue; + int64_t nOrderPos; //! position in ordered transaction list + uint64_t nEntryNo; + + CAccountingEntry() + { + SetNull(); + } + + void SetNull() + { + nCreditDebit = 0; + nTime = 0; + strAccount.clear(); + strOtherAccount.clear(); + strComment.clear(); + nOrderPos = -1; + nEntryNo = 0; + } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + //! Note: strAccount is serialized as part of the key, not here. + READWRITE(nCreditDebit); + READWRITE(nTime); + READWRITE(LIMITED_STRING(strOtherAccount, 65536)); + + if (!ser_action.ForRead()) + { + WriteOrderPos(nOrderPos, mapValue); + + if (!(mapValue.empty() && _ssExtra.empty())) + { + CDataStream ss(nType, nVersion); + ss.insert(ss.begin(), '\0'); + ss << mapValue; + ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end()); + strComment.append(ss.str()); + } + } + + READWRITE(LIMITED_STRING(strComment, 65536)); + + size_t nSepPos = strComment.find("\0", 0, 1); + if (ser_action.ForRead()) + { + mapValue.clear(); + if (std::string::npos != nSepPos) + { + CDataStream ss(std::vector(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion); + ss >> mapValue; + _ssExtra = std::vector(ss.begin(), ss.end()); + } + ReadOrderPos(nOrderPos, mapValue); + } + if (std::string::npos != nSepPos) + strComment.erase(nSepPos); + + mapValue.erase("n"); + } + +private: + std::vector _ssExtra; +}; /** @@ -475,6 +566,9 @@ private: void AddToSpends(const COutPoint& outpoint, const uint256& wtxid); void AddToSpends(const uint256& wtxid); + /* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */ + void MarkConflicted(const uint256& hashBlock, const uint256& hashTx); + void SyncMetaData(std::pair); public: @@ -654,6 +748,7 @@ public: bool AddAccountingEntry(const CAccountingEntry&, CWalletDB & pwalletdb); static CFeeRate minTxFee; + static CFeeRate fallbackFee; /** * Estimate the minimum fee considering user set parameters * and the required fee @@ -771,6 +866,9 @@ public: bool GetBroadcastTransactions() const { return fBroadcastTransactions; } /** Set whether this wallet broadcasts transactions. */ void SetBroadcastTransactions(bool broadcast) { fBroadcastTransactions = broadcast; } + + /* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */ + bool AbandonTransaction(const uint256& hashTx); }; /** A key allocated from the key pool. */ @@ -828,87 +926,4 @@ public: } }; - - -/** - * Internal transfers. - * Database key is acentry. - */ -class CAccountingEntry -{ -public: - std::string strAccount; - CAmount nCreditDebit; - int64_t nTime; - std::string strOtherAccount; - std::string strComment; - mapValue_t mapValue; - int64_t nOrderPos; //! position in ordered transaction list - uint64_t nEntryNo; - - CAccountingEntry() - { - SetNull(); - } - - void SetNull() - { - nCreditDebit = 0; - nTime = 0; - strAccount.clear(); - strOtherAccount.clear(); - strComment.clear(); - nOrderPos = -1; - nEntryNo = 0; - } - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - if (!(nType & SER_GETHASH)) - READWRITE(nVersion); - //! Note: strAccount is serialized as part of the key, not here. - READWRITE(nCreditDebit); - READWRITE(nTime); - READWRITE(LIMITED_STRING(strOtherAccount, 65536)); - - if (!ser_action.ForRead()) - { - WriteOrderPos(nOrderPos, mapValue); - - if (!(mapValue.empty() && _ssExtra.empty())) - { - CDataStream ss(nType, nVersion); - ss.insert(ss.begin(), '\0'); - ss << mapValue; - ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end()); - strComment.append(ss.str()); - } - } - - READWRITE(LIMITED_STRING(strComment, 65536)); - - size_t nSepPos = strComment.find("\0", 0, 1); - if (ser_action.ForRead()) - { - mapValue.clear(); - if (std::string::npos != nSepPos) - { - CDataStream ss(std::vector(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion); - ss >> mapValue; - _ssExtra = std::vector(ss.begin(), ss.end()); - } - ReadOrderPos(nOrderPos, mapValue); - } - if (std::string::npos != nSepPos) - strComment.erase(nSepPos); - - mapValue.erase("n"); - } - -private: - std::vector _ssExtra; -}; - #endif // BITCOIN_WALLET_WALLET_H diff --git a/src/wallet/wallet_ismine.cpp b/src/wallet/wallet_ismine.cpp index d27b1531e..ebda5cc53 100644 --- a/src/wallet/wallet_ismine.cpp +++ b/src/wallet/wallet_ismine.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/wallet_ismine.h b/src/wallet/wallet_ismine.h index 9f45f76c6..51afd1b14 100644 --- a/src/wallet/wallet_ismine.h +++ b/src/wallet/wallet_ismine.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -17,7 +17,7 @@ class CScript; enum isminetype { ISMINE_NO = 0, - //! Indicates that we dont know how to create a scriptSig that would solve this if we were given the appropriate private keys + //! Indicates that we don't know how to create a scriptSig that would solve this if we were given the appropriate private keys ISMINE_WATCH_UNSOLVABLE = 1, //! Indicates that we know how to create a scriptSig that would solve this if we were given the appropriate private keys ISMINE_WATCH_SOLVABLE = 2, diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 9ce9f53bd..67511976d 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,6 +15,7 @@ #include "utiltime.h" #include "wallet/wallet.h" +#include #include #include #include @@ -113,19 +114,19 @@ bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript) { nWalletDBUpdated++; - return Write(std::make_pair(std::string("cscript"), hash), redeemScript, false); + return Write(std::make_pair(std::string("cscript"), hash), *(const CScriptBase*)(&redeemScript), false); } bool CWalletDB::WriteWatchOnly(const CScript &dest) { nWalletDBUpdated++; - return Write(std::make_pair(std::string("watchs"), dest), '1'); + return Write(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest)), '1'); } bool CWalletDB::EraseWatchOnly(const CScript &dest) { nWalletDBUpdated++; - return Erase(std::make_pair(std::string("watchs"), dest)); + return Erase(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest))); } bool CWalletDB::WriteBestBlock(const CBlockLocator& locator) @@ -421,7 +422,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, else if (strType == "watchs") { CScript script; - ssKey >> script; + ssKey >> *(CScriptBase*)(&script); char fYes; ssValue >> fYes; if (fYes == '1') @@ -575,7 +576,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, uint160 hash; ssKey >> hash; CScript script; - ssValue >> script; + ssValue >> *(CScriptBase*)(&script); if (!pwallet->LoadCScript(script)) { strErr = "Error reading wallet database: LoadCScript failed"; @@ -810,7 +811,7 @@ void ThreadFlushWalletDB(const string& strFile) if (fOneThread) return; fOneThread = true; - if (!GetBoolArg("-flushwallet", true)) + if (!GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) return; unsigned int nLastSeen = nWalletDBUpdated; @@ -960,8 +961,13 @@ bool CWalletDB::Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKe CDataStream ssKey(row.first, SER_DISK, CLIENT_VERSION); CDataStream ssValue(row.second, SER_DISK, CLIENT_VERSION); string strType, strErr; - bool fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue, + bool fReadOK; + { + // Required in LoadKeyMetadata(): + LOCK(dummyWallet.cs_wallet); + fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue, wss, strType, strErr); + } if (!IsKeyType(strType)) continue; if (!fReadOK) diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 3ebc05afd..8da33dead 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2015 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -16,6 +16,8 @@ #include #include +static const bool DEFAULT_FLUSHWALLET = true; + class CAccount; class CAccountingEntry; struct CBlockLocator; diff --git a/src/zmq/zmqconfig.h b/src/zmq/zmqconfig.h index 6057f5d1a..610d7fbda 100644 --- a/src/zmq/zmqconfig.h +++ b/src/zmq/zmqconfig.h @@ -1,4 +1,4 @@ -// Copyright (c) 2015 The Bitcoin Core developers +// 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. diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 09fe3aeb4..be2aec7d1 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -12,7 +12,7 @@ void zmqError(const char *str) { - LogPrint("zmq", "Error: %s, errno=%s\n", str, zmq_strerror(errno)); + LogPrint("zmq", "zmq: Error: %s, errno=%s\n", str, zmq_strerror(errno)); } CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(NULL) @@ -72,7 +72,7 @@ CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const // Called at startup to conditionally set up ZMQ socket(s) bool CZMQNotificationInterface::Initialize() { - LogPrint("zmq", "Initialize notification interface\n"); + LogPrint("zmq", "zmq: Initialize notification interface\n"); assert(!pcontext); pcontext = zmq_init(1); @@ -110,7 +110,7 @@ bool CZMQNotificationInterface::Initialize() // Called during shutdown sequence void CZMQNotificationInterface::Shutdown() { - LogPrint("zmq", "Shutdown notification interface\n"); + LogPrint("zmq", "zmq: Shutdown notification interface\n"); if (pcontext) { for (std::list::iterator i=notifiers.begin(); i!=notifiers.end(); ++i) diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index ac788843e..ddc8fe93e 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -78,7 +78,7 @@ bool CZMQAbstractPublishNotifier::Initialize(void *pcontext) } else { - LogPrint("zmq", " Reuse socket for address %s\n", address); + LogPrint("zmq", "zmq: Reusing socket for address %s\n", address); psocket = i->second->psocket; mapPublishNotifiers.insert(std::make_pair(address, this)); @@ -120,7 +120,7 @@ void CZMQAbstractPublishNotifier::Shutdown() bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { uint256 hash = pindex->GetBlockHash(); - LogPrint("zmq", "Publish hash block %s\n", hash.GetHex()); + LogPrint("zmq", "zmq: Publish hashblock %s\n", hash.GetHex()); char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; @@ -131,7 +131,7 @@ bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction) { uint256 hash = transaction.GetHash(); - LogPrint("zmq", "Publish hash transaction %s\n", hash.GetHex()); + LogPrint("zmq", "zmq: Publish hashtx %s\n", hash.GetHex()); char data[32]; for (unsigned int i = 0; i < 32; i++) data[31 - i] = hash.begin()[i]; @@ -141,7 +141,7 @@ bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &t bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { - LogPrint("zmq", "Publish raw block %s\n", pindex->GetBlockHash().GetHex()); + LogPrint("zmq", "zmq: Publish rawblock %s\n", pindex->GetBlockHash().GetHex()); const Consensus::Params& consensusParams = Params().GetConsensus(); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); @@ -164,7 +164,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction) { uint256 hash = transaction.GetHash(); - LogPrint("zmq", "Publish raw transaction %s\n", hash.GetHex()); + LogPrint("zmq", "zmq: Publish rawtx %s\n", hash.GetHex()); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << transaction; int rc = zmq_send_multipart(psocket, "rawtx", 5, &(*ss.begin()), ss.size(), 0);